@@ -93,12 +93,16 @@ export async function fetchImage(fetcher: Fetcher | undefined, imageUrl: string,
9393 }
9494
9595 if ( ! contentType ) {
96- // Fallback to the sanitized upstream header when the type can not be detected
96+ // Fallback to upstream header when the type can not be detected
9797 // https://github.com/vercel/next.js/blob/d76f0b1/packages/next/src/server/image-optimizer.ts#L748
98- const header = imgResponse . headers . get ( "content-type" ) ?? "" ;
99- if ( header . startsWith ( "image/" ) && ! header . includes ( "," ) ) {
100- contentType = header ;
101- }
98+ contentType = imgResponse . headers . get ( "content-type" ) ?? "" ;
99+ }
100+
101+ // Sanitize the content type:
102+ // - Accept images only
103+ // - Reject multiple content types
104+ if ( ! contentType . startsWith ( "image/" ) || contentType . includes ( "," ) ) {
105+ contentType = undefined ;
102106 }
103107
104108 if ( contentType && ! ( contentType === SVG && ! __IMAGES_ALLOW_SVG__ ) ) {
@@ -167,12 +171,17 @@ const AVIF = "image/avif";
167171const WEBP = "image/webp" ;
168172const PNG = "image/png" ;
169173const JPEG = "image/jpeg" ;
174+ const JXL = "image/jxl" ;
175+ const JP2 = "image/jp2" ;
176+ const HEIC = "image/heic" ;
170177const GIF = "image/gif" ;
171178const SVG = "image/svg+xml" ;
172179const ICO = "image/x-icon" ;
173180const ICNS = "image/x-icns" ;
174181const TIFF = "image/tiff" ;
175182const BMP = "image/bmp" ;
183+ // pdf will be rejected (not an `image/...` type)
184+ const PDF = "application/pdf" ;
176185
177186/**
178187 * Detects the content type by looking at the first few bytes of a file
@@ -216,6 +225,25 @@ export function detectContentType(buffer: Uint8Array) {
216225 if ( [ 0x42 , 0x4d ] . every ( ( b , i ) => buffer [ i ] === b ) ) {
217226 return BMP ;
218227 }
228+ if ( [ 0xff , 0x0a ] . every ( ( b , i ) => buffer [ i ] === b ) ) {
229+ return JXL ;
230+ }
231+ if (
232+ [ 0x00 , 0x00 , 0x00 , 0x0c , 0x4a , 0x58 , 0x4c , 0x20 , 0x0d , 0x0a , 0x87 , 0x0a ] . every ( ( b , i ) => buffer [ i ] === b )
233+ ) {
234+ return JXL ;
235+ }
236+ if ( [ 0 , 0 , 0 , 0 , 0x66 , 0x74 , 0x79 , 0x70 , 0x68 , 0x65 , 0x69 , 0x63 ] . every ( ( b , i ) => ! b || buffer [ i ] === b ) ) {
237+ return HEIC ;
238+ }
239+ if ( [ 0x25 , 0x50 , 0x44 , 0x46 , 0x2d ] . every ( ( b , i ) => buffer [ i ] === b ) ) {
240+ return PDF ;
241+ }
242+ if (
243+ [ 0x00 , 0x00 , 0x00 , 0x0c , 0x6a , 0x50 , 0x20 , 0x20 , 0x0d , 0x0a , 0x87 , 0x0a ] . every ( ( b , i ) => buffer [ i ] === b )
244+ ) {
245+ return JP2 ;
246+ }
219247}
220248
221249declare global {
0 commit comments