Skip to content

Commit 2a0bb59

Browse files
committed
fix(core): Substitute params in length-descending order to avoid substring collisions
1 parent 8468c8c commit 2a0bb59

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
- **uninstall:** Import `url_filename` from `download.ps1` ([#6530](https://github.com/ScoopInstaller/Scoop/issues/6530))
2828
- **schema:** Add missing `hash.mode` value `github` ([#6533](https://github.com/ScoopInstaller/Scoop/issues/6533))
2929
- **core:** Skip NO_JUNCTION logic when $app is 'scoop' in `currentdir` function ([#6541](https://github.com/ScoopInstaller/Scoop/issues/6541))
30+
- **core:** Substitute params in length-descending order to avoid substring collisions ([#6561](https://github.com/ScoopInstaller/Scoop/issues/6561))
3031

3132
### Code Refactoring
3233

lib/core.ps1

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,12 +1209,15 @@ function substitute($entity, [Hashtable] $params, [Bool]$regexEscape = $false) {
12091209
$newentity = $entity.PSObject.Copy()
12101210
switch ($entity.GetType().Name) {
12111211
'String' {
1212-
$params.GetEnumerator() | ForEach-Object {
1213-
if ($regexEscape -eq $false -or $null -eq $_.Value) {
1214-
$newentity = $newentity.Replace($_.Name, $_.Value)
1215-
} else {
1216-
$newentity = $newentity.Replace($_.Name, [Regex]::Escape($_.Value))
1212+
$params.Keys | Sort-Object @{Expression = { $_.Length }; Descending = $true }, @{Expression = { $_ }; Descending = $false } | ForEach-Object {
1213+
$key = $_
1214+
$value = $params[$key]
1215+
1216+
if ($regexEscape -and ($null -ne $value)) {
1217+
$value = [Regex]::Escape($value)
12171218
}
1219+
1220+
$newEntity = $newEntity.Replace($key, $value)
12181221
}
12191222
}
12201223
'Object[]' {

test/Scoop-Core.Tests.ps1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,18 @@ Describe 'Format Architecture String' -Tag 'Scoop' {
393393
{ Format-ArchitectureString 'PPC' } | Should -Throw "Invalid architecture: 'ppc'"
394394
}
395395
}
396+
397+
Describe 'substitute' -Tag 'Scoop' {
398+
It 'should properly handle keys that are substrings of other keys' {
399+
$params = @{
400+
'$url' = 'https://example.com/download/win-desktop.exe'
401+
'$urlNoExt' = 'https://example.com/download/win-desktop'
402+
'$basename' = 'win-desktop.exe'
403+
'$basenameNoExt' = 'win-desktop'
404+
'$NULL' = $null
405+
}
406+
substitute '$urlNoExt.sha256' $params $false | Should -Be 'https://example.com/download/win-desktop.sha256'
407+
substitute '$basenameNoExt.sha256' $params $false | Should -Be 'win-desktop.sha256'
408+
substitute '$NULL.sha256' $params $false | Should -Be '.sha256'
409+
}
410+
}

0 commit comments

Comments
 (0)