Skip to content

Commit b6d7170

Browse files
JoshuaWhite1vividviolet
authored andcommitted
address png encoding bug, path changes
1 parent df78ef1 commit b6d7170

2 files changed

Lines changed: 27 additions & 5 deletions

File tree

packages/app/src/cli/services/dev/extension/server/middlewares.test.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ describe('fileServerMiddleware()', async () => {
133133
})
134134

135135
expect(event.node.res.setHeader).toHaveBeenCalledWith('Content-Type', 'text/html')
136-
expect(result).toBe('<html></html>')
136+
expect(String(result)).toBe('<html></html>')
137137
})
138138
})
139139

@@ -166,7 +166,25 @@ describe('fileServerMiddleware()', async () => {
166166
})
167167

168168
expect(event.node.res.setHeader).toHaveBeenCalledWith('Content-Type', contentType)
169-
expect(result).toBe(fileContent)
169+
expect(String(result)).toBe(fileContent)
170+
})
171+
})
172+
173+
test('serves binary files as a Buffer without UTF-8 corruption', async () => {
174+
await inTemporaryDirectory(async (tmpDir: string) => {
175+
// Bytes that are invalid as UTF-8 input (0x89, 0xFF, 0xFE) — if the
176+
// middleware decoded these as UTF-8 they'd collapse to U+FFFD and the
177+
// image would be corrupt. Includes the real PNG magic header.
178+
const pngBytes = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0xff, 0xfe, 0x00, 0x42])
179+
await mkdir(joinPath(tmpDir, 'img'))
180+
await writeFile(joinPath(tmpDir, 'img', 'logo.png'), pngBytes)
181+
182+
const event = getMockEvent()
183+
const result = await fileServerMiddleware(event, {filePath: joinPath(tmpDir, 'img', 'logo.png')})
184+
185+
expect(event.node.res.setHeader).toHaveBeenCalledWith('Content-Type', 'image/png')
186+
expect(Buffer.isBuffer(result)).toBe(true)
187+
expect(Buffer.compare(result as Buffer, pngBytes)).toBe(0)
170188
})
171189
})
172190

@@ -183,7 +201,7 @@ describe('fileServerMiddleware()', async () => {
183201
})
184202

185203
expect(event.node.res.setHeader).toHaveBeenCalledWith('Content-Type', 'text/plain')
186-
expect(result).toBe('Content for bar.foo')
204+
expect(String(result)).toBe('Content for bar.foo')
187205
})
188206
})
189207
})
@@ -275,7 +293,7 @@ describe('getExtensionAssetMiddleware()', () => {
275293
const result = await getExtensionAssetMiddleware(options)(event)
276294

277295
expect(event.node.res.setHeader).toHaveBeenCalledWith('Content-Type', 'text/javascript')
278-
expect(result).toBe('compiled bundle content')
296+
expect(String(result)).toBe('compiled bundle content')
279297
})
280298
})
281299

packages/app/src/cli/services/dev/extension/server/middlewares.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ export async function fileServerMiddleware(event: H3Event, options: {filePath: s
4141
return sendError(event, {statusCode: 404, statusMessage: `Not Found: ${filePath}`})
4242
}
4343

44-
const fileContent = await readFile(filePath)
44+
// Pass `{}` to opt out of cli-kit's `{encoding: 'utf8'}` default — binary
45+
// files (png, jpeg, pdf, wasm, …) must come back as a Buffer or their bytes
46+
// get mangled into U+FFFD replacement chars by the UTF-8 decode. h3 sends
47+
// Buffers as-is and the browser decodes per Content-Type for text types.
48+
const fileContent = await readFile(filePath, {})
4549
const extensionToContent = {
4650
'.ico': 'image/x-icon',
4751
'.html': 'text/html',

0 commit comments

Comments
 (0)