# fix_manifest_sha_v1.1.ps1 # Objet : Recalcul canonique du bloc [SYNC_MANIFEST] (hors ligne MANIFEST_SHA256) et correction ?ventuelle. # Modes : -Preview (par d?faut, no-touch) ; -Write (SAFE-WRITE : .bak dat?e, .tmp, UTF-8 sans BOM). # PS 5.1-safe : pas d'op?rateurs modernes, pas de d?pendance au r?pertoire courant, r?solution robuste du _registry. param([switch]$Preview,[switch]$Write) function Write-NoBOM([string]$Path,[string]$Text){ $enc=[Text.UTF8Encoding]::new($false); [IO.File]::WriteAllText($Path,$Text,$enc) } function Ensure-Parent([string]$Path){ $p=Split-Path -Parent $Path; if($p -and !(Test-Path $p)){ New-Item -ItemType Directory -Force -Path $p|Out-Null } } function Safe-ReplaceFile([string]$Target,[string]$Text){ Ensure-Parent $Target $ts=Get-Date -Format 'yyyyMMdd_HHmmss' $tmp="$Target.$ts.tmp"; $bak="$Target.bak_$ts" Write-NoBOM $tmp $Text $shaTmp=(Get-FileHash -Algorithm SHA256 -LiteralPath $tmp).Hash if(Test-Path $Target){ Copy-Item -LiteralPath $Target -Destination $bak -Force } Move-Item -LiteralPath $tmp -Destination $Target -Force $shaFinal=(Get-FileHash -Algorithm SHA256 -LiteralPath $Target).Hash @{Bak=$bak;ShaTmp=$shaTmp;ShaFinal=$shaFinal} } # === D?tection robuste du r?pertoire _registry === $scriptPath = $MyInvocation.MyCommand.Definition $scriptDir = Split-Path -Parent $scriptPath $registry = Split-Path -Parent $scriptDir # .\_registry $bp = Join-Path $registry 'bootpack\bootpack.txt' if(!(Test-Path $bp)){ Write-Host "[BLOCKING] bootpack.txt introuvable : $bp" Write-Host "Hint: le script suppose la structure .\_registry\scripts\fix_manifest_sha_v1.1.ps1" exit 1 } # === Lecture et extraction du bloc manifest === $raw = Get-Content -LiteralPath $bp -Raw -Encoding UTF8 $match = [regex]::Match($raw,'(?ms)^\[SYNC_MANIFEST\]\s*(.*?)(?=^\[|\Z)') if(!$match.Success){ Write-Host "[BLOCKING] Section [SYNC_MANIFEST] absente."; exit 1 } $body = $match.Groups[1].Value $infile = [regex]::Match($body,'(?mi)^\s*MANIFEST_SHA256\s*:\s*([0-9a-f]+)\s*$').Groups[1].Value.ToLower() # === Canonicalisation : CRLF, trim des fins de lignes, pas de newline final === $coreLines=@() foreach($ln in ($body -split "`r?`n")){ if($ln -match '^\s*MANIFEST_SHA256\s*:'){ continue } $coreLines += $ln.TrimEnd() } $core = [string]::Join("`r`n",$coreLines) $recalc = [BitConverter]::ToString( [Security.Cryptography.SHA256]::Create().ComputeHash([Text.Encoding]::UTF8.GetBytes($core)) ).Replace('-','').ToLower() 'InFile = '+$infile | Write-Host 'Recalc = '+$recalc | Write-Host if($infile -eq $recalc){ Write-Host "STATUS = MATCH (aucune action requise)" exit 0 } Write-Host "STATUS = DIFF (correction propos?e)" if(-not $Write){ Write-Host "Preview uniquement - aucune ?criture effectu?e." exit 0 } # === Remplacement de la ligne MANIFEST_SHA256 en SAFE-WRITE === $fixed = [regex]::Replace($raw,'(?mi)^\s*MANIFEST_SHA256\s*:\s*[0-9a-f]+\s*$','MANIFEST_SHA256: '+$recalc) $result = Safe-ReplaceFile -Target $bp -Text $fixed "Backup : {0}" -f $result.Bak | Write-Host "SHA tmp/final: {0} / {1}" -f $result.ShaTmp,$result.ShaFinal | Write-Host # === Re-v?rification imm?diate === $raw2 = Get-Content -LiteralPath $bp -Raw -Encoding UTF8 $body2 = [regex]::Match($raw2,'(?ms)^\[SYNC_MANIFEST\]\s*(.*?)(?=^\[|\Z)').Groups[1].Value $in2=[regex]::Match($body2,'(?mi)^\s*MANIFEST_SHA256\s*:\s*([0-9a-f]+)\s*$').Groups[1].Value.ToLower() "STATUS = "+$(if($in2 -eq $recalc){'MATCH'}else{'DIFF'}) | Write-Host