diff --git a/docker/frontend/src/engine/rawDevelop.ts b/docker/frontend/src/engine/rawDevelop.ts index 490cc9e..23eeb89 100644 --- a/docker/frontend/src/engine/rawDevelop.ts +++ b/docker/frontend/src/engine/rawDevelop.ts @@ -260,60 +260,65 @@ export function extractEmbeddedJpeg(buf: Uint8Array): Uint8Array | null { const len = buf.length; let largest: Uint8Array | null = null; let maxLen = 0; + for (let i = 0; i < len - 4; i++) { if (buf[i] === 0xff && buf[i + 1] === 0xd8 && buf[i + 2] === 0xff) { + const start = i; let pos = i + 2; let eoiPos = -1; - let valid = true; - while (pos < len - 1) { + let validJpeg = true; + + while (pos < len - 4) { if (buf[pos] !== 0xff) { - pos++; - continue; + validJpeg = false; + break; } - const marker = buf[pos + 1]; - if (marker === 0x00 || (marker >= 0xd0 && marker <= 0xd7)) { - pos += 2; - continue; - } - if (marker === 0xd9) { + const m = buf[pos + 1]; + if (m === 0xd9) { eoiPos = pos + 2; break; } - if (marker === 0xd8) { + if (m === 0xda) { + const sosHeaderLen = (buf[pos + 2] << 8) | buf[pos + 3]; + if (sosHeaderLen < 2 || pos + 2 + sosHeaderLen > len) { + validJpeg = false; + break; + } + let scanPos = pos + 2 + sosHeaderLen; + const searchEnd = Math.min(len - 1, scanPos + 20 * 1024 * 1024); + while (scanPos < searchEnd) { + if (buf[scanPos] === 0xff) { + const marker = buf[scanPos + 1]; + if (marker === 0xd9) { + eoiPos = scanPos + 2; + break; + } + if (marker === 0x00 || (marker >= 0xd0 && marker <= 0xd7)) { + scanPos += 2; + continue; + } + } + scanPos++; + } + break; + } + if (m === 0x00 || (m >= 0xd0 && m <= 0xd7)) { pos += 2; continue; } - if (pos + 3 >= len) break; const segLen = (buf[pos + 2] << 8) | buf[pos + 3]; - if (segLen < 2) { - valid = false; + if (segLen < 2 || pos + 2 + segLen > len) { + validJpeg = false; break; } - if (marker === 0xda) { - pos += 2 + segLen; - while (pos < len - 1) { - if (buf[pos] === 0xff) { - const m = buf[pos + 1]; - if (m === 0xd9) { - eoiPos = pos + 2; - break; - } - if (m !== 0x00 && !(m >= 0xd0 && m <= 0xd7)) { - break; - } - } - pos++; - } - if (eoiPos !== -1) break; - } else { - pos += 2 + segLen; - } + pos += 2 + segLen; } - if (valid && eoiPos > i) { - const segSize = eoiPos - i; + + if (eoiPos > start && validJpeg) { + const segSize = eoiPos - start; if (segSize > 10000 && segSize > maxLen) { maxLen = segSize; - largest = buf.subarray(i, eoiPos); + largest = buf.subarray(start, eoiPos); } i = eoiPos - 1; }