228 lines
7.8 KiB
PowerShell
228 lines
7.8 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Patch wszystkich paczek aktualizacji: dodanie urlencode() na update_key w URL.
|
|
|
|
.DESCRIPTION
|
|
Po wczesniejszym patchu http->https, klucz licencji nadal wysylany jako raw string.
|
|
Klucze zawierajace # @ : $ etc. lamia URL. Fix: urlencode($settings['update_key']).
|
|
|
|
Wzorce zamiany (oba warianty pliku class.S.php legacy oraz Helpers.php nowy):
|
|
1. ?key=' . $settings['update_key']) -> ?key=' . urlencode($settings['update_key']))
|
|
2. ?key=' . $settings['update_key'] ) -> ?key=' . urlencode( $settings['update_key'] ) )
|
|
|
|
Idempotentny: pomija pliki ktore juz maja urlencode().
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$UpdatesDir = "C:\visual studio code\projekty\cmsPRO\updates",
|
|
[string]$LogPath = "C:\visual studio code\projekty\cmsPRO\.paul\phases\04h-hotfix-https-updates\patch-urlencode-log.md"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
|
$SuspectFiles = @(
|
|
'autoload/class.S.php',
|
|
'autoload/Shared/Helpers/Helpers.php',
|
|
'autoload/admin/factory/class.Update.php'
|
|
)
|
|
|
|
# Zwraca $true jesli content zawiera buggy pattern (raw $settings['update_key'] w URL)
|
|
function Test-NeedsUrlencode {
|
|
param([string]$Content)
|
|
# already has urlencode wrapping update_key?
|
|
if ($Content -match "urlencode\s*\(\s*\`$settings\[\s*'update_key'\s*\]\s*\)") {
|
|
# check if there's still any RAW occurrence
|
|
# Strategy: count raw vs encoded occurrences
|
|
$raw = ([regex]::Matches($Content, "\`$settings\[\s*'update_key'\s*\]")).Count
|
|
$enc = ([regex]::Matches($Content, "urlencode\s*\(\s*\`$settings\[\s*'update_key'\s*\]\s*\)")).Count
|
|
return ($raw -gt $enc) # any raw not yet wrapped
|
|
}
|
|
return ($Content -match "key=['""]?\s*\.\s*\`$settings\[\s*'update_key'\s*\]")
|
|
}
|
|
|
|
function Apply-UrlencodePatch {
|
|
param([string]$Content)
|
|
# Two flavors of whitespace: with and without spaces inside brackets
|
|
# Replacement strategy: find $settings['update_key'] preceded by something containing ?key= and . and replace with urlencode wrap
|
|
# Safest: match the full "?key=' . $settings['update_key']" with optional spaces/quotes/closing ).
|
|
|
|
# Variant A: ?key=' . $settings['update_key'] (no trailing space, may have ) or ; after)
|
|
$newContent = [regex]::Replace($Content,
|
|
"(\?key=['""]?\s*\.\s*)(\`$settings\[\s*'update_key'\s*\])",
|
|
'$1urlencode($2)'
|
|
)
|
|
return $newContent
|
|
}
|
|
|
|
function Patch-Zip {
|
|
param([string]$ZipPath)
|
|
|
|
$log = [PSCustomObject]@{
|
|
Package = (Resolve-Path $ZipPath).Path.Substring($UpdatesDir.Length).TrimStart('\','/')
|
|
Sha256Before = $null
|
|
Sha256After = $null
|
|
PatchedFiles = @()
|
|
ManifestUpd = $false
|
|
Skipped = $false
|
|
Error = $null
|
|
}
|
|
|
|
# backup (separate from previous .bak)
|
|
$bak = "$ZipPath.preurlencode.bak"
|
|
if (-not (Test-Path $bak)) {
|
|
Copy-Item -LiteralPath $ZipPath -Destination $bak -Force
|
|
}
|
|
$log.Sha256Before = (Get-FileHash -Algorithm SHA256 -Path $ZipPath).Hash.ToLower()
|
|
|
|
# Find entries needing patch
|
|
$entriesToPatch = @()
|
|
try {
|
|
$zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
|
|
foreach ($entry in $zip.Entries) {
|
|
$name = $entry.FullName.Replace('\','/')
|
|
if ($SuspectFiles -contains $name) {
|
|
$reader = New-Object System.IO.StreamReader($entry.Open())
|
|
$content = $reader.ReadToEnd()
|
|
$reader.Close()
|
|
if (Test-NeedsUrlencode -Content $content) {
|
|
$entriesToPatch += $name
|
|
}
|
|
}
|
|
}
|
|
$zip.Dispose()
|
|
} catch {
|
|
$log.Error = "OpenRead: $($_.Exception.Message)"
|
|
return $log
|
|
}
|
|
|
|
if (-not $entriesToPatch) {
|
|
$log.Skipped = $true
|
|
$log.Sha256After = $log.Sha256Before
|
|
return $log
|
|
}
|
|
|
|
# Patch in-place
|
|
try {
|
|
$zipUpd = [System.IO.Compression.ZipFile]::Open($ZipPath, [System.IO.Compression.ZipArchiveMode]::Update)
|
|
foreach ($name in $entriesToPatch) {
|
|
$entry = $zipUpd.Entries | Where-Object { $_.FullName.Replace('\','/') -eq $name } | Select-Object -First 1
|
|
if (-not $entry) { continue }
|
|
|
|
$stream = $entry.Open()
|
|
$reader = New-Object System.IO.StreamReader($stream)
|
|
$content = $reader.ReadToEnd()
|
|
$reader.Close()
|
|
$stream.Close()
|
|
|
|
$newContent = Apply-UrlencodePatch -Content $content
|
|
if ($newContent -eq $content) { continue }
|
|
|
|
$writeStream = $entry.Open()
|
|
$writeStream.SetLength(0)
|
|
$writer = New-Object System.IO.StreamWriter($writeStream, (New-Object System.Text.UTF8Encoding $false))
|
|
$writer.Write($newContent)
|
|
$writer.Flush()
|
|
$writer.Close()
|
|
$writeStream.Close()
|
|
|
|
$log.PatchedFiles += $name
|
|
}
|
|
$zipUpd.Dispose()
|
|
} catch {
|
|
$log.Error = "Patch: $($_.Exception.Message)"
|
|
return $log
|
|
}
|
|
|
|
$log.Sha256After = (Get-FileHash -Algorithm SHA256 -Path $ZipPath).Hash.ToLower()
|
|
|
|
# Update manifest
|
|
$verBase = [System.IO.Path]::GetFileNameWithoutExtension($ZipPath)
|
|
$manifestPath = Join-Path (Split-Path $ZipPath -Parent) "${verBase}_manifest.json"
|
|
if (Test-Path $manifestPath) {
|
|
try {
|
|
$jsonRaw = [System.IO.File]::ReadAllText($manifestPath)
|
|
if ($jsonRaw.Length -gt 0 -and $jsonRaw[0] -eq [char]0xFEFF) {
|
|
$jsonRaw = $jsonRaw.Substring(1)
|
|
}
|
|
$manifest = $jsonRaw | ConvertFrom-Json
|
|
if ($manifest.PSObject.Properties.Name -contains 'checksum_zip') {
|
|
$manifest.checksum_zip = "sha256:$($log.Sha256After)"
|
|
$newJson = $manifest | ConvertTo-Json -Depth 20
|
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
|
[System.IO.File]::WriteAllText($manifestPath, $newJson, $utf8)
|
|
$log.ManifestUpd = $true
|
|
}
|
|
} catch {
|
|
$log.Error = "Manifest: $($_.Exception.Message)"
|
|
}
|
|
}
|
|
|
|
return $log
|
|
}
|
|
|
|
# --- Main ---
|
|
Write-Host "Skanuje $UpdatesDir ..." -ForegroundColor Cyan
|
|
|
|
$zips = @()
|
|
$baseInstall = Join-Path $UpdatesDir 'cmsPro.zip'
|
|
if (Test-Path $baseInstall) { $zips += $baseInstall }
|
|
$zips += Get-ChildItem -Path $UpdatesDir -Filter 'ver_*.zip' -Recurse | Sort-Object FullName | ForEach-Object { $_.FullName }
|
|
|
|
Write-Host "Paczek do sprawdzenia: $($zips.Count)" -ForegroundColor Cyan
|
|
|
|
$results = @()
|
|
$i = 0
|
|
foreach ($zip in $zips) {
|
|
$i++
|
|
Write-Progress -Activity "Patch urlencode" -Status "$i / $($zips.Count)" -PercentComplete (($i / $zips.Count) * 100)
|
|
$results += Patch-Zip -ZipPath $zip
|
|
}
|
|
Write-Progress -Activity "Patch urlencode" -Completed
|
|
|
|
$patched = $results | Where-Object { $_.PatchedFiles.Count -gt 0 -and -not $_.Error }
|
|
$skipped = $results | Where-Object { $_.Skipped }
|
|
$errored = $results | Where-Object { $_.Error }
|
|
$manifUpd = $results | Where-Object { $_.ManifestUpd }
|
|
|
|
# Log
|
|
$lines = @()
|
|
$lines += '# Patch Log: urlencode($settings[update_key])'
|
|
$lines += ''
|
|
$lines += "**Data:** $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
|
|
$lines += ''
|
|
$lines += "Spatchowanych: $($patched.Count)"
|
|
$lines += "Pominietych: $($skipped.Count)"
|
|
$lines += "Manifestow zaktualizowanych: $($manifUpd.Count)"
|
|
$lines += "Bledow: $($errored.Count)"
|
|
$lines += ''
|
|
$lines += '## Spatchowane'
|
|
if ($patched) {
|
|
$lines += '| # | Paczka | Pliki | SHA256 (po) |'
|
|
$lines += '|---|--------|-------|-------------|'
|
|
$idx = 0
|
|
foreach ($r in $patched) {
|
|
$idx++
|
|
$files = ($r.PatchedFiles -join '<br>')
|
|
$sha = if ($r.Sha256After.Length -ge 16) { $r.Sha256After.Substring(0,16) } else { $r.Sha256After }
|
|
$lines += "| $idx | ``$($r.Package)`` | $files | ``$sha`` |"
|
|
}
|
|
}
|
|
$lines += ''
|
|
if ($errored) {
|
|
$lines += '## Bledy'
|
|
foreach ($r in $errored) { $lines += "- ``$($r.Package)`` -- $($r.Error)" }
|
|
}
|
|
|
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
|
[System.IO.File]::WriteAllText($LogPath, ($lines -join "`r`n"), $utf8)
|
|
|
|
Write-Host ""
|
|
Write-Host "Patch urlencode zakonczony." -ForegroundColor Green
|
|
Write-Host " Spatchowanych: $($patched.Count)" -ForegroundColor Yellow
|
|
Write-Host " Manifestow updated: $($manifUpd.Count)"
|
|
Write-Host " Pominietych: $($skipped.Count)"
|
|
Write-Host " Bledow: $($errored.Count)"
|
|
Write-Host "Log: $LogPath" -ForegroundColor Cyan
|