mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 21:43:23 -05:00
The manifest is untrusted input. It is now read under a size limit and validated before use: destinations are contained below the BIOS root, repo_path stays inside bios/, release_asset is a basename, hashes match their shape, declared totals match their lists, and every entry has a download source. Downloads stream against the declared size, are checked by SHA-256 then SHA-1, land in a per-process temporary file and are installed with os.replace. Copies into standalone-emulator directories are opt-in with --standalone-copies so a detection never writes outside the selected tree. Both bootstraps verify install.py against an embedded SHA-256 before running it, and require the Python version install.py actually needs. A target that publishes no core list is a target with no filter, not a broken manifest: rejecting it disabled --target for the whole platform.
64 lines
2.8 KiB
PowerShell
64 lines
2.8 KiB
PowerShell
# One-line bootstrap and local wrapper. The downloaded installer is accepted
|
|
# only when it matches the SHA-256 embedded in this wrapper.
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
[string[]]$InstallerArguments
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
|
$defaultInstallSha256 = "79630030c1b7445e2df02bcf0272c4530d24827b2589780b214489ab036d2e8c"
|
|
$maximumInstallerBytes = 2MB
|
|
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
|
$temporary = $null
|
|
|
|
try {
|
|
if (-not $installer -or -not (Test-Path -LiteralPath $installer -PathType Leaf)) {
|
|
$url = if ($env:RETROBIOS_INSTALL_URL) { $env:RETROBIOS_INSTALL_URL } else { $defaultInstallUrl }
|
|
$expected = if ($env:RETROBIOS_INSTALL_SHA256) { $env:RETROBIOS_INSTALL_SHA256 } else { $defaultInstallSha256 }
|
|
$uri = [Uri]$url
|
|
if ($uri.Scheme -ne "https") {
|
|
throw "RETROBIOS_INSTALL_URL must use HTTPS."
|
|
}
|
|
if ($expected -notmatch '^[0-9a-fA-F]{64}$') {
|
|
throw "Installer SHA-256 must contain exactly 64 hexadecimal characters."
|
|
}
|
|
$temporary = Join-Path ([IO.Path]::GetTempPath()) ("retrobios-install-{0}.py" -f [Guid]::NewGuid())
|
|
Invoke-WebRequest -Uri $uri -OutFile $temporary -UseBasicParsing
|
|
if ((Get-Item -LiteralPath $temporary).Length -gt $maximumInstallerBytes) {
|
|
throw "Downloaded installer exceeds the size limit."
|
|
}
|
|
$actual = (Get-FileHash -LiteralPath $temporary -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
if ($actual -ne $expected.ToLowerInvariant()) {
|
|
throw "install.py SHA-256 mismatch."
|
|
}
|
|
$installer = $temporary
|
|
}
|
|
|
|
$python = Get-Command py -ErrorAction SilentlyContinue
|
|
if ($python) {
|
|
& $python.Source -3 -c "import sys; raise SystemExit(sys.version_info < (3, 8))"
|
|
if ($LASTEXITCODE -ne 0) { throw "Python 3.8 or newer is required." }
|
|
& $python.Source -3 $installer @InstallerArguments
|
|
if ($LASTEXITCODE -ne 0) { throw "RetroBIOS installer failed with exit code $LASTEXITCODE." }
|
|
return
|
|
}
|
|
$python = Get-Command python3 -ErrorAction SilentlyContinue
|
|
if (-not $python) {
|
|
$python = Get-Command python -ErrorAction SilentlyContinue
|
|
}
|
|
if (-not $python) {
|
|
throw "Python 3.8 or newer is required."
|
|
}
|
|
& $python.Source -c "import sys; raise SystemExit(sys.version_info < (3, 8))"
|
|
if ($LASTEXITCODE -ne 0) { throw "Python 3.8 or newer is required." }
|
|
& $python.Source $installer @InstallerArguments
|
|
if ($LASTEXITCODE -ne 0) { throw "RetroBIOS installer failed with exit code $LASTEXITCODE." }
|
|
}
|
|
finally {
|
|
if ($temporary -and (Test-Path -LiteralPath $temporary)) {
|
|
Remove-Item -LiteralPath $temporary -Force
|
|
}
|
|
}
|