| โฆ | โฆ | @@ -0,0 +1,165 @@ | |
| 127 | + | ) | |
| 128 | + | throw new Error("This TIFF color format is not supported."); | |
| 129 | + | await validateTiffStrips(bytes, metadata); | |
| 130 | + | const image = decodeTiff(bytes, { pages: [0] })[0]!; | |
๐ High files/imageDecode.worker.ts:130
TIFFs with a non-default Orientation tag fail to produce a preview, so valid camera or scanner images (for example, Orientation=6) show โUnable to load image.โ The decodeTiff call at line 130 reaches tiff@7.1.3's decodeImageData, which throws Unsupported orientation; handle the orientation before decoding or reject it explicitly with a clear error.
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/imageDecode.worker.ts around line 130: |
| 2 | |
| 3 | TIFFs with a non-default `Orientation` tag fail to produce a preview, so valid camera or scanner images (for example, `Orientation=6`) show โUnable to load image.โ The `decodeTiff` call at line 130 reaches `tiff@7.1.3`'s `decodeImageData`, which throws `Unsupported orientation`; handle the orientation before decoding or reject it explicitly with a clear error. |
Note
Written by gpt-6.1-sol on behalf of Maria
Nondefault TIFF orientation now produces an explicit unsupported-orientation error before pixel decoding in 5b24af6040.
| โฆ | โฆ | @@ -0,0 +1,165 @@ | |
| 101 | + | } finally { | |
| 102 | + | await reader.cancel(); | |
| 103 | + | } | |
| 104 | + | } else if (image.compression !== 1 && image.compression !== 32773) | |
๐ High files/imageDecode.worker.ts:104
PackBits-compressed TIFFs pass this validation but fail during decodeTiff, so valid images using compression 32773 cannot be previewed. The tiff decoder throws Unsupported Compression: PackBits; reject 32773 here unless a PackBits decoder is added.
| 1 | } else if (image.compression !== 1) |
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/imageDecode.worker.ts around line 104: |
| 2 | |
| 3 | PackBits-compressed TIFFs pass this validation but fail during `decodeTiff`, so valid images using compression `32773` cannot be previewed. The `tiff` decoder throws `Unsupported Compression: PackBits`; reject `32773` here unless a PackBits decoder is added. |
Note
Written by gpt-6.1-sol on behalf of Maria
PackBits is rejected by strip validation with the unsupported-compression error in 5b24af6040.
| โฆ | โฆ | @@ -0,0 +1,202 @@ | |
| 162 | + | } else { | |
| 163 | + | files = new Map(); | |
| 164 | + | let entries: ArchiveEntry[]; | |
| 165 | + | if ( | |
๐ก Medium files/binaryPreview.worker.ts:165
A valid empty ZIP uploaded as download with MIME application/zip falls through to tarEntries and is rejected as having no readable entries. This branch recognizes ZIPs only by filename or the local-file signature; also recognize the ZIP end-of-central-directory signature (or pass the known ZIP format through).
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/binaryPreview.worker.ts around line 165: |
| 2 | |
| 3 | A valid empty ZIP uploaded as `download` with MIME `application/zip` falls through to `tarEntries` and is rejected as having no readable entries. This branch recognizes ZIPs only by filename or the local-file signature; also recognize the ZIP end-of-central-directory signature (or pass the known ZIP format through). |
Note
Written by gpt-6.1-sol on behalf of Maria
Recognizes the empty ZIP end-of-central-directory signature in 5b24af6040, including extensionless uploads.
| โฆ | โฆ | @@ -0,0 +1,78 @@ | |
| 20 | + | if (view.getUint32(offset, true) !== 0x06054b50) continue; | |
| 21 | + | if (offset + 22 + view.getUint16(offset + 20, true) !== bytes.byteLength) continue; | |
| 22 | + | if (view.getUint16(offset + 10, true) > ARCHIVE_MAX_ENTRIES) | |
| 23 | + | throw new Error("This archive contains more than 2,048 entries."); | |
๐ High files/boundedZip.ts:22
Valid ZIP64 archives with at most 2,048 entries are rejected as oversized, so ZIP64 ZIP/JAR/DOCX files cannot be previewed. ZIP64 uses 0xffff in this legacy EOCD field as a sentinel rather than the actual count; validate the ZIP64 count or defer this limit to the parsed entries.length check below.
| 1 | - if (view.getUint16(offset + 10, true) > ARCHIVE_MAX_ENTRIES) |
| 2 | - throw new Error("This archive contains more than 2,048 entries."); |
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/boundedZip.ts around lines 22-23: |
| 2 | |
| 3 | Valid ZIP64 archives with at most 2,048 entries are rejected as oversized, so ZIP64 ZIP/JAR/DOCX files cannot be previewed. ZIP64 uses `0xffff` in this legacy EOCD field as a sentinel rather than the actual count; validate the ZIP64 count or defer this limit to the parsed `entries.length` check below. |
Note
Written by gpt-6.1-sol on behalf of Maria
Validates bounded ZIP64 directory counts and offsets in 5b24af6040. The existing browser suite successfully reads a generated small ZIP64 archive.
| โฆ | โฆ | @@ -0,0 +1,202 @@ | |
| 166 | + | /\.(zip|jar)$/i.test(input.name) || | |
| 167 | + | new DataView(input.bytes).getUint32(0, true) === 0x04034b50 | |
| 168 | + | ) { | |
| 169 | + | const archive = await boundedZip(input.bytes, ARCHIVE_ENTRY_MAX_BYTES); | |
๐ High files/binaryPreview.worker.ts:169
A ZIP/JAR with any member larger than 10 MB fails here before its entries are listed, so users cannot browse the archive even though the entry handler is intended to reject only opening oversized members. Pass the 50 MB BINARY_PREVIEW_MAX_BYTES limit to enumeration and keep the 10 MB check in the entry handler.
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/binaryPreview.worker.ts around line 169: |
| 2 | |
| 3 | A ZIP/JAR with any member larger than 10 MB fails here before its entries are listed, so users cannot browse the archive even though the `entry` handler is intended to reject only opening oversized members. Pass the 50 MB `BINARY_PREVIEW_MAX_BYTES` limit to enumeration and keep the 10 MB check in the `entry` handler. |
Note
Written by gpt-6.1-sol on behalf of Maria
Enumeration now allows members up to the existing 50 MB archive budget in 5b24af6040. Opening a member retains the 10 MB limit.
| โฆ | โฆ | @@ -0,0 +1,165 @@ | |
| 124 | + | ![1, 2, 3, 4].includes(metadata.components) || | |
| 125 | + | ![8, 16].includes(metadata.bitsPerSample) || | |
| 126 | + | ![0, 1, 2, 3].includes(metadata.type) | |
| 127 | + | ) | |
๐ High files/imageDecode.worker.ts:123
Tiled RGB/RGBA previews are emitted with missing color channels, so the resulting PNG is incorrect. The tiled path in tiff's readTileData writes only one sample per pixel, but this worker accepts multi-component tiled images and converts their data as RGB; reject tiled images with more than one component or decode all samples.
| 1 | if ( |
| 2 | (metadata.tiled && metadata.components > 1) || |
| 3 | ![1, 2, 3, 4].includes(metadata.components) || |
| 4 | ![8, 16].includes(metadata.bitsPerSample) || |
| 5 | ![0, 1, 2, 3].includes(metadata.type) |
| 6 | ) |
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/imageDecode.worker.ts around lines 123-127: |
| 2 | |
| 3 | Tiled RGB/RGBA previews are emitted with missing color channels, so the resulting PNG is incorrect. The tiled path in `tiff`'s `readTileData` writes only one sample per pixel, but this worker accepts multi-component tiled images and converts their data as RGB; reject tiled images with more than one component or decode all samples. |
Note
Written by gpt-6.1-sol on behalf of Maria
Rejects multicomponent tiled TIFFs before pixel decoding in 5b24af6040, since the installed decoder does not read those samples correctly.
| โฆ | โฆ | @@ -274,15 +278,7 @@ export function AttachmentFilePreview(props: { | |
| 283 | - | onError={() => setError("Unable to load image.")} | |
| 284 | - | /> | |
| 285 | - | </div> | |
| 281 | + | <PreviewImage key={url} src={url} name={props.name} mimeType={props.mimeType} /> | |
๐ก Medium files/AttachmentFilePreview.tsx:281
When an image fails to load, PreviewImage shows its local failure surface instead of setting this componentโs error, so the parent FileSurfaceFailure and its retry action never appear. Report image load failures through setError so retry can refresh the asset URL and reload the image.
๐ Reply "fix it for me" or copy this AI Prompt for your agent:
| 1 | In file @apps/web/src/components/files/AttachmentFilePreview.tsx around line 281: |
| 2 | |
| 3 | When an image fails to load, `PreviewImage` shows its local failure surface instead of setting this componentโs `error`, so the parent `FileSurfaceFailure` and its retry action never appear. Report image load failures through `setError` so retry can refresh the asset URL and reload the image. |
Note
Written by gpt-6.1-sol on behalf of Maria
Image errors now reach the attachment failure surface in 5b24af6040. The browser regression clicks retry and verifies that asset authorization refreshes twice and the replacement image loads.