fix: properly parse PNG iTXt chunks per specification

Skip compression flag, method, language tag, and translated keyword
fields in iTXt chunks as required by the PNG specification.

Fixes #8150

Amp-Thread-ID: https://ampcode.com/threads/T-019c17e4-e2f2-710d-a37a-7b6e1cc67532
This commit is contained in:
bymyself
2026-01-31 22:48:41 -08:00
parent 544ef5bb70
commit 072a6c245a

View File

@@ -29,10 +29,23 @@ export function getFromPngBuffer(buffer: ArrayBuffer): Record<string, string> {
...pngData.slice(offset + 8, keyword_end)
)
// Get the text
const contentArraySegment = pngData.slice(
keyword_end + 1,
offset + 8 + length
)
// For iTXt chunks, skip compression flag (1), compression method (1),
// language tag (null-terminated), and translated keyword (null-terminated)
let textStart = keyword_end + 1
if (type === 'iTXt') {
textStart += 2 // Skip compression flag and method
// Skip language tag (find null terminator)
while (pngData[textStart] !== 0 && textStart < offset + 8 + length) {
textStart++
}
textStart++ // Skip null terminator
// Skip translated keyword (find null terminator)
while (pngData[textStart] !== 0 && textStart < offset + 8 + length) {
textStart++
}
textStart++ // Skip null terminator
}
const contentArraySegment = pngData.slice(textStart, offset + 8 + length)
const contentJson = new TextDecoder('utf-8').decode(contentArraySegment)
txt_chunks[keyword] = contentJson
}