Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- **scoop-uninstall**: Allow access to `$bucket` in uninstall scripts ([#6380](https://github.com/ScoopInstaller/Scoop/issues/6380))
- **install:** Add separator at the end of notes, highlight suggestions ([#6418](https://github.com/ScoopInstaller/Scoop/issues/6418))
- **virustotal:** Refactor into lib and integrate pre-download checks for install and update ([#6525](https://github.com/ScoopInstaller/Scoop/issues/6525))


### Bug Fixes

Expand Down
1 change: 1 addition & 0 deletions bin/checkhashes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ param(

. "$PSScriptRoot\..\lib\core.ps1"
. "$PSScriptRoot\..\lib\manifest.ps1"
. "$PSScriptRoot\..\lib\hash.ps1" # 'get_hash'
. "$PSScriptRoot\..\lib\buckets.ps1"
. "$PSScriptRoot\..\lib\autoupdate.ps1"
. "$PSScriptRoot\..\lib\json.ps1"
Expand Down
2 changes: 2 additions & 0 deletions lib/autoupdate.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Must included with 'json.ps1'

. "$PSScriptRoot\..\lib\hash.ps1" # 'get_hash'

function format_hash([String] $hash) {
$hash = $hash.toLower()

Expand Down
62 changes: 24 additions & 38 deletions lib/download.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Description: Functions for downloading files

. "$PSScriptRoot\..\lib\core.ps1"
. "$PSScriptRoot\..\lib\hash.ps1" # 'hash_for_url'
. "$PSScriptRoot\..\lib\virustotal.ps1"

## Meta downloader

function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture, $dir, $use_cache = $true, $check_hash = $true) {
function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture, $dir, $use_cache = $true, $check_hash = $true, $check_virustotal = $false) {
# we only want to show this warning once
if (!$use_cache) { warn 'Cache is being ignored.' }

Expand All @@ -14,8 +18,14 @@ function Invoke-ScoopDownload ($app, $version, $manifest, $bucket, $architecture

# download first
if (Test-Aria2Enabled) {
Invoke-CachedAria2Download $app $version $manifest $architecture $dir $cookies $use_cache $check_hash
Invoke-CachedAria2Download $app $version $manifest $architecture $dir $cookies $use_cache $check_hash $check_virustotal
} else {
$urls = if ($check_virustotal) {
Test-UrlsWithVirusTotal $app $urls $manifest $architecture
} else {
$urls
}

foreach ($url in $urls) {
$fname = url_filename $url

Expand Down Expand Up @@ -329,9 +339,14 @@ function get_filename_from_metalink($file) {
return $filename
}

function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $dir, $cookies = $null, $use_cache = $true, $check_hash = $true) {
function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $dir, $cookies = $null, $use_cache = $true, $check_hash = $true, $check_virustotal = $false) {
$data = @{}
$urls = @(script:url $manifest $architecture)
$urls = if ($check_virustotal) {
Test-UrlsWithVirusTotal $app $urls $manifest $architecture
} else {
$urls
}

# aria2 input file
$urlstxt = Join-Path $cachedir "$app.txt"
Expand Down Expand Up @@ -457,9 +472,9 @@ function Invoke-CachedAria2Download ($app, $version, $manifest, $architecture, $
warn "Download failed! (Error $lastexitcode) $(aria_exit_code $lastexitcode)"
warn $urlstxt_content
warn $aria2
warn $(new_issue_msg $app $bucket "download via aria2 failed")
warn $(new_issue_msg $app $bucket 'download via aria2 failed')

Write-Host "Fallback to default downloader ..."
Write-Host 'Fallback to default downloader ...'

try {
foreach ($url in $urls) {
Expand Down Expand Up @@ -666,7 +681,7 @@ function get_magic_bytes_pretty($file, $glue = ' ') {
return (get_magic_bytes $file | ForEach-Object { $_.ToString('x2') }) -join $glue
}

Function Get-RemoteFileSize ($Uri) {
function Get-RemoteFileSize ($Uri) {
$response = Invoke-WebRequest -Uri $Uri -Method HEAD -UseBasicParsing
if (!$response.Headers.StatusCode) {
$response.Headers.'Content-Length' | ForEach-Object { [int]$_ }
Expand All @@ -689,33 +704,18 @@ function url_remote_filename($url) {
# this function extracts the original filename from the URL.
$uri = (New-Object URI $url)
$basename = Split-Path $uri.PathAndQuery -Leaf
If ($basename -match '.*[?=]+([\w._-]+)') {
if ($basename -match '.*[?=]+([\w._-]+)') {
$basename = $matches[1]
}
If (($basename -notlike '*.*') -or ($basename -match '^[v.\d]+$')) {
if (($basename -notlike '*.*') -or ($basename -match '^[v.\d]+$')) {
$basename = Split-Path $uri.AbsolutePath -Leaf
}
If (($basename -notlike '*.*') -and ($uri.Fragment -ne '')) {
if (($basename -notlike '*.*') -and ($uri.Fragment -ne '')) {
$basename = $uri.Fragment.Trim('/', '#')
}
return $basename
}

### Hash-related functions

function hash_for_url($manifest, $url, $arch) {
$hashes = @(hash $manifest $arch) | Where-Object { $_ -ne $null }

if ($hashes.length -eq 0) { return $null }

$urls = @(script:url $manifest $arch)

$index = [array]::IndexOf($urls, $url)
if ($index -eq -1) { abort "Couldn't find hash in manifest for '$url'." }

@($hashes)[$index]
}

function check_hash($file, $hash, $app_name) {
# returns (ok, err)
if (!$hash) {
Expand Down Expand Up @@ -751,19 +751,5 @@ function check_hash($file, $hash, $app_name) {
return $true, $null
}

function get_hash([String] $multihash) {
$type, $hash = $multihash -split ':'
if (!$hash) {
# no type specified, assume sha256
$type, $hash = 'sha256', $multihash
}

if (@('md5', 'sha1', 'sha256', 'sha512') -notcontains $type) {
return $null, "Hash type '$type' isn't supported."
}

return $type, $hash.ToLower()
}

# Setup proxy globally
setup_proxy
28 changes: 28 additions & 0 deletions lib/hash.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
### Hash-related functions

function hash_for_url($manifest, $url, $arch) {
$hashes = @(hash $manifest $arch) | Where-Object { $_ -ne $null }

if ($hashes.length -eq 0) { return $null }

$urls = @(script:url $manifest $arch)

$index = [array]::IndexOf($urls, $url)
if ($index -eq -1) { abort "Couldn't find hash in manifest for '$url'." }

@($hashes)[$index]
}

function get_hash([String] $multihash) {
$type, $hash = $multihash -split ':'
if (!$hash) {
# no type specified, assume sha256
$type, $hash = 'sha256', $multihash
}

if (@('md5', 'sha1', 'sha256', 'sha512') -notcontains $type) {
return $null, "Hash type '$type' isn't supported."
}

return $type, $hash.ToLower()
}
5 changes: 3 additions & 2 deletions lib/install.ps1
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@

function nightly_version($quiet = $false) {
if (!$quiet) {
warn "This is a nightly version. Downloaded files won't be verified."
}
return "nightly-$(Get-Date -Format 'yyyyMMdd')"
}

function install_app($app, $architecture, $global, $suggested, $use_cache = $true, $check_hash = $true) {
function install_app($app, $architecture, $global, $suggested, $use_cache = $true, $check_hash = $true, $check_virustotal = $false) {
$app, $manifest, $bucket, $url = Get-Manifest $app

if (!$manifest) {
Expand Down Expand Up @@ -49,7 +50,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
$original_dir = $dir # keep reference to real (not linked) directory
$persist_dir = persistdir $app $global

$fname = Invoke-ScoopDownload $app $version $manifest $bucket $architecture $dir $use_cache $check_hash
$fname = Invoke-ScoopDownload $app $version $manifest $bucket $architecture $dir $use_cache $check_hash $check_virustotal
Invoke-Extraction -Path $dir -Name $fname -Manifest $manifest -ProcessorArchitecture $architecture
Invoke-HookScript -HookType 'pre_install' -Manifest $manifest -ProcessorArchitecture $architecture

Expand Down
Loading