Fix: Falsch benannte Hash-Manifeste löschen keine korrekten Dateien mehr
readHashManifest hat den pro Zeile korrekt erkannten Algorithmus mit dem aus der
DATEIENDUNG abgeleiteten überschrieben (.sfv→crc32, .md5→md5, .sha1→sha1).
parseHashLine erkennt den Algorithmus jedoch eindeutig an der Digest-Länge
(32-hex=MD5, 40-hex=SHA1, 8-hex=CRC32) — die Länge ist die verlässliche Quelle.
Stimmte die Endung nicht mit dem Zeileninhalt überein (z.B. eine MD5-Zeile in
einer .sfv-Datei), wurde der Algorithmus auf crc32 verbogen, hashFile berechnete
einen 8-Zeichen-CRC und verglich ihn mit dem 32-Zeichen-MD5 → garantiert
Mismatch. Folge: die intakte Datei wurde gelöscht, neu geladen, scheiterte
erneut und brach hart ab ("Integritätsprüfung fehlgeschlagen").
Fix: Den von parseHashLine erkannten Algorithmus übernehmen statt ihn per
Dateiendung zu überschreiben. Bei korrekt benannten Manifesten ist das ohnehin
ein No-op; nur die fehl-etikettierten Fälle werden repariert.
Test: .sfv-Datei mit MD5-formatierter Zeile + passende Datei → Algorithmus bleibt
MD5 und die Prüfung besteht. Mit der Endungs-Überschreibung wird crc32 erzwungen
und die gute Datei fällt durch (rot bewiesen).
This commit is contained in:
parent
2b639b7267
commit
45789918b0
@ -93,15 +93,11 @@ export function readHashManifest(packageDir: string): Map<string, ParsedHashEntr
|
|||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const normalized: ParsedHashEntry = {
|
|
||||||
...parsed,
|
|
||||||
algorithm: hit[1]
|
|
||||||
};
|
|
||||||
const key = normalizeManifestKey(parsed.fileName);
|
const key = normalizeManifestKey(parsed.fileName);
|
||||||
if (map.has(key)) {
|
if (map.has(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
map.set(key, normalized);
|
map.set(key, parsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manifestCache.set(cacheKey, { at: Date.now(), entries: new Map(map) });
|
manifestCache.set(cacheKey, { at: Date.now(), entries: new Map(map) });
|
||||||
|
|||||||
@ -66,6 +66,21 @@ describe("integrity", () => {
|
|||||||
expect(parseHashLine(" ")).toBeNull();
|
expect(parseHashLine(" ")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("trusts the per-line algorithm over the file extension for a mislabeled manifest (.sfv holding md5 lines)", async () => {
|
||||||
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-int-"));
|
||||||
|
tempDirs.push(dir);
|
||||||
|
const filePath = path.join(dir, "movie.bin");
|
||||||
|
fs.writeFileSync(filePath, Buffer.from("hello"));
|
||||||
|
fs.writeFileSync(path.join(dir, "checksums.sfv"), "5d41402abc4b2a76b9719d911017c592 movie.bin\n", "utf8");
|
||||||
|
|
||||||
|
const manifest = readHashManifest(dir);
|
||||||
|
expect(manifest.get("movie.bin")?.algorithm).toBe("md5");
|
||||||
|
|
||||||
|
const result = await validateFileAgainstManifest(filePath, dir);
|
||||||
|
expect(result.ok).toBe(true);
|
||||||
|
expect(result.message).toContain("MD5");
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps first hash entry when duplicate filename appears across manifests", () => {
|
it("keeps first hash entry when duplicate filename appears across manifests", () => {
|
||||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-int-"));
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-int-"));
|
||||||
tempDirs.push(dir);
|
tempDirs.push(dir);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user