Skip to content
Open
Show file tree
Hide file tree
Changes from 10 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