mirror of
https://github.com/shivammathur/setup-php.git
synced 2026-10-15 20:06:58 +00:00
Harden tool checksum verification (#1099)
This commit is contained in:
1 parent
8ca9579834
commit
8e6e5267e7
6 files changed
+90
-32
No files matched your search
@@ -226,11 +226,15 @@ describe('Tools tests', () => {
|
||||
${'tool:1.2.3'} | ${'tool:1.2.3'} | ${undefined} | ${undefined}
|
||||
${'tool:1.2.3@sha256:' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined}
|
||||
${'tool:1.2.3@sha256:' + 'A'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined}
|
||||
${'tool:1.2.3@SHA256:' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined}
|
||||
${'tool:1.2.3@sha512:' + 'b'.repeat(128)} | ${'tool:1.2.3'} | ${'sha512:' + 'b'.repeat(128)} | ${undefined}
|
||||
${'composer:2.9.8@sha256:' + 'c'.repeat(64)} | ${'composer:2.9.8'} | ${'sha256:' + 'c'.repeat(64)} | ${undefined}
|
||||
${'tool:1.2.3@sha256:xyz'} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha256 checksum, expected 64 hexadecimal characters'}
|
||||
${'tool:1.2.3@sha256:' + 'a'.repeat(63)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha256 checksum, expected 64 hexadecimal characters'}
|
||||
${'tool:1.2.3@sha512:' + 'b'.repeat(64)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha512 checksum, expected 128 hexadecimal characters'}
|
||||
${'tool:1.2.3@sha384:' + 'b'.repeat(96)} | ${'tool:1.2.3'} | ${undefined} | ${'Unsupported checksum algorithm sha384, expected sha256 or sha512'}
|
||||
${'tool:1.2.3@md5:' + 'b'.repeat(32)} | ${'tool:1.2.3'} | ${undefined} | ${'Unsupported checksum algorithm md5, expected sha256 or sha512'}
|
||||
${'tool:1.2.3@sha256' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid checksum syntax, expected @sha256:<hash> or @sha512:<hash>'}
|
||||
${'tool:1.0@dev'} | ${'tool:1.0@dev'} | ${undefined} | ${undefined}
|
||||
`(
|
||||
'checking extractChecksum: $release',
|
||||
@@ -257,6 +261,11 @@ describe('Tools tests', () => {
|
||||
${'a, b, composer:v2'} | ${'composer:2, a, b'}
|
||||
${'a, b, composer:2.7.1@sha256:' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256:' + 'a'.repeat(64) + ', a, b'}
|
||||
${'a, b, composer:v2.7.1@sha256:' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256:' + 'a'.repeat(64) + ', a, b'}
|
||||
${'a, b, composer:2.7.1@SHA256:' + 'a'.repeat(64)} | ${'composer:2.7.1@SHA256:' + 'a'.repeat(64) + ', a, b'}
|
||||
${'a, b, composer:2.7.1@sha384:' + 'a'.repeat(96)} | ${'composer:2.7.1@sha384:' + 'a'.repeat(96) + ', a, b'}
|
||||
${'a, b, composer:2.7.1@md5:' + 'a'.repeat(32)} | ${'composer:2.7.1@md5:' + 'a'.repeat(32) + ', a, b'}
|
||||
${'a, b, composer:2.7.1@sha256' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256' + 'a'.repeat(64) + ', a, b'}
|
||||
${'a, b, composer@sha256:' + 'a'.repeat(64)} | ${'composer@sha256:' + 'a'.repeat(64) + ', a, b'}
|
||||
`('checking filterList $input_list', async ({input_list, filtered_list}) => {
|
||||
expect(await tools.filterList(input_list.split(', '))).toStrictEqual(
|
||||
filtered_list.split(', ')
|
||||
@@ -825,6 +834,10 @@ describe('Tools tests', () => {
|
||||
${'phinx:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "phinx" "Checksum verification is not supported for phinx"'}
|
||||
${'pecl@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "pecl" "Checksum verification is not supported for pecl"'}
|
||||
${'phpunit:9.5.0@sha256:invalid'} | ${'linux'} | ${'add_log "$cross" "phpunit" "Invalid sha256 checksum, expected 64 hexadecimal characters"'}
|
||||
${'composer:2.9.8@SHA256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)}
|
||||
${'composer:2.9.8@sha384:' + 'b'.repeat(96)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm sha384, expected sha256 or sha512"'}
|
||||
${'composer:2.9.8@md5:' + 'b'.repeat(32)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm md5, expected sha256 or sha512"'}
|
||||
${'composer:2.9.8@sha256' + 'b'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "composer" "Invalid checksum syntax, expected @sha256:<hash> or @sha512:<hash>"'}
|
||||
`(
|
||||
'checking addTools with checksum: $tools_csv, $os',
|
||||
async ({tools_csv, os, script}) => {
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i<r.length;i++)if(r[i]!=="default")n(t,e,r[i]);s(t,e);return t}}();Object.defineProperty(t,"__esModule",{value:true});t.addINIValuesUnix=addINIValuesUnix;t.addINIValuesWindows=addINIValuesWindows;t.addINIValues=addINIValues;const o=i(r(277));async function addINIValuesUnix(e){const t=await o.CSVArray(e);let r="";await o.asyncForEach(t,async function(e){r+="\n"+await o.addLog("$tick",e,"Added to php.ini","linux")});return'echo "'+t.map(e=>o.escapeForShell(e,"linux")).join("\n")+'" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"});return'Add-Content "$php_dir\\php.ini" "'+t.map(e=>o.escapeForShell(e,"win32")).join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let s=`::${e}`;if(t&&Object.keys(t).length>0){s+=" ";const e=Object.entries(t).filter(([,e])=>e).map(([e,t])=>`${e}=${escapeProperty(t)}`).join(",");s+=e}s+=`::${escapeData(r)}`;process.stdout.write(s+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i<r.length;i++)if(r[i]!=="default")n(t,e,r[i]);s(t,e);return t}}();Object.defineProperty(t,"__esModule",{value:true});t.checkXdebugError=checkXdebugError;t.addCoverageXdebug=addCoverageXdebug;t.addCoveragePCOV=addCoveragePCOV;t.disableCoverage=disableCoverage;t.addCoverage=addCoverage;const o=i(r(277));const a=i(r(252));const c=i(r(472));async function checkXdebugError(e,t){if(/^5\.[3-6]$|^7\.[0-1]$/.test(t)&&e=="xdebug3"||/^8\.[0-9]$/.test(t)&&e=="xdebug2"){return e+" is not supported on PHP "+t}return""}async function addCoverageXdebug(e,t,r,n){let s="\n";const i=await checkXdebugError(e,t);if(!i){s+=await a.addExtension(":pcov:false",t,r,true)+n;e=e=="xdebug3"?"xdebug":e;s+=await a.addExtension(e,t,r,true)+n;s+=await o.setVariable("xdebug_version","php -r \"echo phpversion('xdebug');\"",r);s+=await o.getCommand(r,"extension_log")+'xdebug "Xdebug $xdebug_version enabled as coverage driver"'}else{s+=await o.addLog("$cross",e,i,r)}return s}async function addCoveragePCOV(e,t,r){let n="\n";switch(true){default:n+=await a.addExtension(":xdebug:Line truncated
|
||||
(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i<r.length;i++)if(r[i]!=="default")n(t,e,r[i]);s(t,e);return t}}();Object.defineProperty(t,"__esModule",{value:true});t.addINIValuesUnix=addINIValuesUnix;t.addINIValuesWindows=addINIValuesWindows;t.addINIValues=addINIValues;const o=i(r(277));async function addINIValuesUnix(e){const t=await o.CSVArray(e);let r="";await o.asyncForEach(t,async function(e){r+="\n"+await o.addLog("$tick",e,"Added to php.ini","linux")});return'echo "'+t.map(e=>o.escapeForShell(e,"linux")).join("\n")+'" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"});return'Add-Content "$php_dir\\php.ini" "'+t.map(e=>o.escapeForShell(e,"win32")).join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let s=`::${e}`;if(t&&Object.keys(t).length>0){s+=" ";const e=Object.entries(t).filter(([,e])=>e).map(([e,t])=>`${e}=${escapeProperty(t)}`).join(",");s+=e}s+=`::${escapeData(r)}`;process.stdout.write(s+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i<r.length;i++)if(r[i]!=="default")n(t,e,r[i]);s(t,e);return t}}();Object.defineProperty(t,"__esModule",{value:true});t.checkXdebugError=checkXdebugError;t.addCoverageXdebug=addCoverageXdebug;t.addCoveragePCOV=addCoveragePCOV;t.disableCoverage=disableCoverage;t.addCoverage=addCoverage;const o=i(r(277));const a=i(r(252));const c=i(r(472));async function checkXdebugError(e,t){if(/^5\.[3-6]$|^7\.[0-1]$/.test(t)&&e=="xdebug3"||/^8\.[0-9]$/.test(t)&&e=="xdebug2"){return e+" is not supported on PHP "+t}return""}async function addCoverageXdebug(e,t,r,n){let s="\n";const i=await checkXdebugError(e,t);if(!i){s+=await a.addExtension(":pcov:false",t,r,true)+n;e=e=="xdebug3"?"xdebug":e;s+=await a.addExtension(e,t,r,true)+n;s+=await o.setVariable("xdebug_version","php -r \"echo phpversion('xdebug');\"",r);s+=await o.getCommand(r,"extension_log")+'xdebug "Xdebug $xdebug_version enabled as coverage driver"'}else{s+=await o.addLog("$cross",e,i,r)}return s}async function addCoveragePCOV(e,t,r){let n="\n";switch(true){default:n+=await a.addExtension(":xdebug:Line truncated
|
||||
@@ -144,6 +144,21 @@ Function Test-MutableToolUrl() {
|
||||
return ($Url -match $mutableUrlRegex) -or (($Url -match '\.phar([?#].*)?$') -and -not ($Url -match $versionLikeRegex))
|
||||
}
|
||||
|
||||
# Function to verify the checksum of a file.
|
||||
Function Test-ToolChecksum() {
|
||||
Param(
|
||||
[Parameter(Position = 0, Mandatory = $true)]
|
||||
[string]
|
||||
$Path,
|
||||
[Parameter(Position = 1, Mandatory = $true)]
|
||||
[string]
|
||||
$Checksum
|
||||
)
|
||||
$checksum_parts = $Checksum -split ':'
|
||||
$actual_checksum = (Get-FileHash -Path $Path -Algorithm $checksum_parts[0]).Hash
|
||||
return $actual_checksum -eq $checksum_parts[1]
|
||||
}
|
||||
|
||||
# Function to extract tool version.
|
||||
Function Get-ToolVersion() {
|
||||
Param (
|
||||
@@ -255,7 +270,12 @@ Function Add-Tool() {
|
||||
$use_cache = -not (Test-MutableToolUrl $urls[0])
|
||||
$status_code = 200
|
||||
if ($use_cache -and (Test-Path $cache_path -PathType Leaf)) {
|
||||
Copy-Item $cache_path -Destination $tool_path -Force
|
||||
if($checksum -and -not(Test-ToolChecksum $cache_path $checksum)) {
|
||||
Remove-Item $cache_path -Force -ErrorAction SilentlyContinue
|
||||
$status_code = 'checksum_mismatch'
|
||||
} else {
|
||||
Copy-Item $cache_path -Destination $tool_path -Force
|
||||
}
|
||||
} else {
|
||||
$backup_path = "$tool_path.bak"
|
||||
if (Test-Path $tool_path) { Copy-Item $tool_path -Destination $backup_path -Force }
|
||||
@@ -275,29 +295,29 @@ Function Add-Tool() {
|
||||
}
|
||||
}
|
||||
if($status_code -eq 200 -and (Test-Path $tool_path)) {
|
||||
if ($use_cache) {
|
||||
Copy-Item $tool_path -Destination $cache_path -Force
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if($status_code -eq 200 -and (Test-Path $tool_path)) {
|
||||
if($checksum -and -not(Test-ToolChecksum $tool_path $checksum)) {
|
||||
Remove-Item @($tool_path, $cache_path) -Force -ErrorAction SilentlyContinue
|
||||
$status_code = 'checksum_mismatch'
|
||||
} elseif($use_cache) {
|
||||
Copy-Item $tool_path -Destination $cache_path -Force
|
||||
}
|
||||
}
|
||||
if ($status_code -ne 200 -and (Test-Path $backup_path)) {
|
||||
Copy-Item $backup_path -Destination $tool_path -Force
|
||||
}
|
||||
Remove-Item $backup_path -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if($checksum -and ($status_code -eq 200) -and (Test-Path $tool_path)) {
|
||||
$checksum_parts = $checksum -split ':'
|
||||
$actual_checksum = (Get-FileHash -Path $tool_path -Algorithm $checksum_parts[0]).Hash
|
||||
if($actual_checksum -ne $checksum_parts[1]) {
|
||||
Remove-Item @($tool_path, $cache_path) -Force -ErrorAction SilentlyContinue
|
||||
if($tool -eq "composer") {
|
||||
$env:fail_fast = 'true'
|
||||
}
|
||||
Add-Log $cross $tool "Checksum verification failed for $tool"
|
||||
return
|
||||
if($status_code -eq 'checksum_mismatch') {
|
||||
if($tool -eq "composer") {
|
||||
$env:fail_fast = 'true'
|
||||
}
|
||||
Add-Log $cross $tool "Checksum verification failed for $tool"
|
||||
return
|
||||
}
|
||||
|
||||
$escaped_tool = [regex]::Escape($tool)
|
||||
|
||||
@@ -227,7 +227,12 @@ add_tool() {
|
||||
is_mutable_tool_url "${url[0]}" && use_cache=false
|
||||
status_code="200"
|
||||
if [ "$use_cache" = "true" ] && [ -f "$cache_path" ]; then
|
||||
sudo cp -a "$cache_path" "$tool_path"
|
||||
if [ -n "$checksum" ] && ! verify_checksum "$cache_path" "$checksum"; then
|
||||
sudo rm -f "$cache_path"
|
||||
status_code="checksum_mismatch"
|
||||
else
|
||||
sudo cp -a "$cache_path" "$tool_path"
|
||||
fi
|
||||
else
|
||||
[ -f "$tool_path" ] && sudo cp -a "$tool_path" "$tool_path.bak"
|
||||
status_code=$(get -v -e "$tool_path" "${url[@]}")
|
||||
@@ -236,16 +241,18 @@ add_tool() {
|
||||
status_code=$(get -v -e "$tool_path" "${url[0]}")
|
||||
fi
|
||||
if [ "$status_code" = "200" ]; then
|
||||
[ "$use_cache" = "true" ] && sudo cp -a "$tool_path" "$cache_path"
|
||||
elif [ -f "$tool_path.bak" ]; then
|
||||
if [ -n "$checksum" ] && ! verify_checksum "$tool_path" "$checksum"; then
|
||||
sudo rm -f "$tool_path" "$cache_path"
|
||||
status_code="checksum_mismatch"
|
||||
elif [ "$use_cache" = "true" ]; then
|
||||
sudo cp -a "$tool_path" "$cache_path"
|
||||
fi
|
||||
fi
|
||||
if [ "$status_code" != "200" ] && [ -f "$tool_path.bak" ]; then
|
||||
sudo mv "$tool_path.bak" "$tool_path"
|
||||
fi
|
||||
sudo rm -f "$tool_path.bak"
|
||||
fi
|
||||
if [ "$status_code" = "200" ] && [ -n "$checksum" ] && ! verify_checksum "$tool_path" "$checksum"; then
|
||||
sudo rm -f "$tool_path" "$cache_path"
|
||||
status_code="checksum_mismatch"
|
||||
fi
|
||||
if [ "$status_code" = "200" ]; then
|
||||
add_tools_helper "$tool"
|
||||
tool_version=$(get_tool_version "$tool" "$ver_param")
|
||||
|
||||
+7
-6
@@ -130,12 +130,13 @@ verify_checksum() {
|
||||
local algo="${checksum%%:*}"
|
||||
local expected="${checksum#*:}"
|
||||
local actual=
|
||||
if command -v "${algo}sum" >/dev/null; then
|
||||
actual="$(sudo "${algo}sum" "$file_path" | cut -d' ' -f1)"
|
||||
elif command -v shasum >/dev/null; then
|
||||
actual="$(sudo shasum -a "${algo#sha}" "$file_path" | cut -d' ' -f1)"
|
||||
elif command -v openssl >/dev/null; then
|
||||
actual="$(sudo openssl dgst -"$algo" "$file_path" | awk '{print $NF}')"
|
||||
local hash_command=
|
||||
if hash_command="$(command -v "${algo}sum")"; then
|
||||
actual="$(sudo "$hash_command" "$file_path" | cut -d' ' -f1)"
|
||||
elif hash_command="$(command -v shasum)"; then
|
||||
actual="$(sudo "$hash_command" -a "${algo#sha}" "$file_path" | cut -d' ' -f1)"
|
||||
elif hash_command="$(command -v openssl)"; then
|
||||
actual="$(sudo "$hash_command" dgst -"$algo" "$file_path" | awk '{print $NF}')"
|
||||
fi
|
||||
[ -n "$actual" ] && [ "$(echo "$actual" | tr '[:upper:]' '[:lower:]')" = "$(echo "$expected" | tr '[:upper:]' '[:lower:]')" ]
|
||||
}
|
||||
|
||||
+21
-4
@@ -77,7 +77,8 @@ interface ToolConfig {
|
||||
/**
|
||||
* Regex to match a checksum suffix in a tool release - tool:version@sha256:<hash>
|
||||
*/
|
||||
const checksum_suffix_regex = /@(sha256|sha512):([^@]*)$/;
|
||||
const checksum_suffix_regex = /@([a-z][a-z0-9-]*):([^@]*)$/i;
|
||||
const checksum_like_suffix_regex = /@sha[^@]*$/i;
|
||||
|
||||
/**
|
||||
* Function to parse the checksum suffix in the tool release
|
||||
@@ -91,10 +92,24 @@ export function extractChecksum(release: string): {
|
||||
} {
|
||||
const matches = release.match(checksum_suffix_regex);
|
||||
if (!matches) {
|
||||
const checksum_like_matches = release.match(checksum_like_suffix_regex);
|
||||
if (checksum_like_matches) {
|
||||
return {
|
||||
release: release.slice(0, -checksum_like_matches[0].length),
|
||||
error:
|
||||
'Invalid checksum syntax, expected @sha256:<hash> or @sha512:<hash>'
|
||||
};
|
||||
}
|
||||
return {release};
|
||||
}
|
||||
release = release.slice(0, -matches[0].length);
|
||||
const algo = matches[1];
|
||||
const algo = matches[1].toLowerCase();
|
||||
if (!['sha256', 'sha512'].includes(algo)) {
|
||||
return {
|
||||
release,
|
||||
error: `Unsupported checksum algorithm ${algo}, expected sha256 or sha512`
|
||||
};
|
||||
}
|
||||
const hash = matches[2].toLowerCase();
|
||||
const hash_length = algo === 'sha256' ? 64 : 128;
|
||||
if (!new RegExp(`^[a-f0-9]{${hash_length}}$`).test(hash)) {
|
||||
@@ -294,10 +309,12 @@ export async function filterList(tools_list: string[]): Promise<string[]> {
|
||||
const regex_valid =
|
||||
/^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/;
|
||||
const matches: string[] = tools_list.filter(tool =>
|
||||
regex_valid.test(tool.replace(checksum_suffix_regex, ''))
|
||||
regex_valid.test(extractChecksum(tool).release)
|
||||
);
|
||||
let composer = 'composer';
|
||||
tools_list = tools_list.filter(tool => !regex_any.test(tool));
|
||||
tools_list = tools_list.filter(
|
||||
tool => !regex_any.test(extractChecksum(tool).release)
|
||||
);
|
||||
switch (true) {
|
||||
case matches[0] == undefined:
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user