Skip to content

Commit 6950e22

Browse files
committed
chore(files): drop the unreachable export asset-count cap
extractEmbeddedFileRefs stops collecting at MAX_EMBEDDED_IMAGES, so the list this route receives is already bounded before it arrives and the count check could never fire. Its test only passed because it mocked the extractor, so it asserted a branch production cannot reach. The byte ceilings are the real bound and stay. A comment records where the count is actually enforced, so the next reader does not add a second one.
1 parent b7f6acd commit 6950e22

2 files changed

Lines changed: 6 additions & 30 deletions

File tree

apps/sim/app/api/files/export/[id]/route.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,6 @@ describe('markdown export bundling', () => {
8080
mockExtractEmbeddedImageIds.mockReturnValue([])
8181
})
8282

83-
it('rejects a document embedding more assets than an export may bundle', async () => {
84-
mockExtractEmbeddedImageIds.mockReturnValue(
85-
Array.from({ length: 501 }, (_, index) => `img-${index}`)
86-
)
87-
88-
const response = await GET(request(), context)
89-
90-
expect(response.status).toBe(400)
91-
expect((await response.json()).error).toContain('501')
92-
// Rejected on the embed count alone: nothing was resolved or downloaded.
93-
expect(mockGetFileMetadataById).toHaveBeenCalledTimes(1)
94-
})
95-
9683
it('rejects on declared asset bytes before downloading any of them', async () => {
9784
mockExtractEmbeddedImageIds.mockReturnValue(['a', 'b', 'c'])
9885
mockGetFileMetadataById.mockImplementation(async (id: string) =>

apps/sim/app/api/files/export/[id]/route.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,14 @@ import { encodeFilenameForHeader } from '@/app/api/files/utils'
2424
const logger = createLogger('FilesExportAPI')
2525

2626
/**
27-
* Bundling caps. The embed list comes from scanning the document body, so its length
28-
* and the bytes behind it are whatever the author put there — without these the export
29-
* would materialize an unbounded number of unbounded assets in one request.
27+
* Byte ceilings for a bundled export. The bytes behind an embed list are whatever the
28+
* author put there, so without these the export would materialize unbounded assets in
29+
* one request. They match the bulk-download route, so the two export surfaces reject at
30+
* the same size.
3031
*
31-
* The byte ceilings are the real bound and match the bulk-download route, so the two
32-
* export surfaces reject at the same size. The count is only a guard on the metadata
33-
* lookups that precede the byte check, so it sits far above any hand-authored document
34-
* rather than at a number a screenshot-heavy doc could plausibly reach.
32+
* There is deliberately no count cap here: `extractEmbeddedFileRefs` already stops at
33+
* `MAX_EMBEDDED_IMAGES`, so the list this route receives is bounded before it arrives.
3534
*/
36-
const MAX_EXPORT_ASSETS = 500
3735
const MAX_EXPORT_ASSET_BYTES = 25 * 1024 * 1024
3836
const MAX_EXPORT_TOTAL_BYTES = 250 * 1024 * 1024
3937

@@ -169,15 +167,6 @@ export const GET = withRouteHandler(
169167
})
170168
}
171169

172-
if (imageIds.length > MAX_EXPORT_ASSETS) {
173-
return NextResponse.json(
174-
{
175-
error: `This document embeds ${imageIds.length} files, more than the ${MAX_EXPORT_ASSETS} an export can bundle.`,
176-
},
177-
{ status: 400 }
178-
)
179-
}
180-
181170
// Metadata first: declared sizes bound the download before a byte is read, and the
182171
// authorization check costs nothing to run here.
183172
const assetTargets = (

0 commit comments

Comments
 (0)