-
Notifications
You must be signed in to change notification settings - Fork 27.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(next): throw when
twitter-image
or opengraph-image
file size…
… exceeds (#70353) Co-authored-by: Jiachi Liu <[email protected]>
- Loading branch information
Showing
12 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
test/production/app-dir/metadata-img-too-large/generate-image.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import zlib from 'zlib' | ||
|
||
const PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]) | ||
|
||
function createChunk(type, data) { | ||
const length = Buffer.alloc(4) | ||
length.writeUInt32BE(data.length, 0) | ||
const crc = Buffer.alloc(4) | ||
const crcValue = calculateCRC(Buffer.concat([Buffer.from(type), data])) >>> 0 // Ensure unsigned 32-bit integer | ||
crc.writeUInt32BE(crcValue, 0) | ||
return Buffer.concat([length, Buffer.from(type), data, crc]) | ||
} | ||
|
||
function calculateCRC(data) { | ||
let crc = 0xffffffff | ||
for (const b of data) { | ||
crc ^= b | ||
for (let i = 0; i < 8; i++) { | ||
crc = (crc >>> 1) ^ (crc & 1 ? 0xedb88320 : 0) | ||
} | ||
} | ||
return crc ^ 0xffffffff | ||
} | ||
|
||
export function generatePNG(targetSizeMB) { | ||
const targetSizeBytes = targetSizeMB * 1024 * 1024 | ||
|
||
let width = 2048, | ||
height = 1024 | ||
let pngFile: Buffer | ||
|
||
do { | ||
const ihdrData = Buffer.alloc(13) | ||
ihdrData.writeUInt32BE(width, 0) | ||
ihdrData.writeUInt32BE(height, 4) | ||
ihdrData.writeUInt8(8, 8) // bitDepth | ||
ihdrData.writeUInt8(6, 9) // colorType | ||
ihdrData.writeUInt8(0, 10) // compressionMethod | ||
ihdrData.writeUInt8(0, 11) // filterMethod | ||
ihdrData.writeUInt8(0, 12) // interlaceMethod | ||
|
||
const ihdrChunk = createChunk('IHDR', ihdrData) | ||
|
||
const rowSize = width * 4 + 1 | ||
const imageData = Buffer.alloc(rowSize * height) | ||
|
||
for (let y = 0; y < height; y++) { | ||
imageData[y * rowSize] = 0 | ||
for (let x = 0; x < width; x++) { | ||
const idx = y * rowSize + 1 + x * 4 | ||
imageData[idx] = (Math.random() * 256) | 0 | ||
imageData[idx + 1] = (Math.random() * 256) | 0 | ||
imageData[idx + 2] = (Math.random() * 256) | 0 | ||
imageData[idx + 3] = 255 | ||
} | ||
} | ||
|
||
const compressedImageData = zlib.deflateSync(imageData) | ||
const idatChunk = createChunk('IDAT', compressedImageData) | ||
const iendChunk = createChunk('IEND', Buffer.alloc(0)) | ||
|
||
pngFile = Buffer.concat([PNG_SIGNATURE, ihdrChunk, idatChunk, iendChunk]) | ||
|
||
if (pngFile.length < targetSizeBytes) { | ||
width *= 2 | ||
height *= 2 | ||
} | ||
} while (pngFile.length < targetSizeBytes) | ||
|
||
return pngFile | ||
} |
8 changes: 8 additions & 0 deletions
8
test/production/app-dir/metadata-img-too-large/opengraph-image/app/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { ReactNode } from 'react' | ||
export default function Root({ children }: { children: ReactNode }) { | ||
return ( | ||
<html> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
3 changes: 3 additions & 0 deletions
3
test/production/app-dir/metadata-img-too-large/opengraph-image/app/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function Page() { | ||
return <p>hello world</p> | ||
} |
21 changes: 21 additions & 0 deletions
21
test/production/app-dir/metadata-img-too-large/opengraph-image/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { nextTestSetup } from 'e2e-utils' | ||
import { generatePNG } from '../generate-image' | ||
|
||
describe('app-dir - metadata-img-too-large opengraph-image', () => { | ||
const { next } = nextTestSetup({ | ||
files: __dirname, | ||
skipStart: true, | ||
}) | ||
|
||
const pngFile = generatePNG(8) | ||
|
||
it('should throw when opengraph-image file size exceeds 8MB', async () => { | ||
await next.patchFile('app/opengraph-image.png', pngFile as any) | ||
|
||
await next.build() | ||
const { cliOutput } = next | ||
expect(cliOutput).toMatch( | ||
/Error: File size for Open Graph image ".*\/app\/opengraph-image\.png" exceeds 8MB/ | ||
) | ||
}) | ||
}) |
6 changes: 6 additions & 0 deletions
6
test/production/app-dir/metadata-img-too-large/opengraph-image/next.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* @type {import('next').NextConfig} | ||
*/ | ||
const nextConfig = {} | ||
|
||
module.exports = nextConfig |
8 changes: 8 additions & 0 deletions
8
test/production/app-dir/metadata-img-too-large/twitter-image/app/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { ReactNode } from 'react' | ||
export default function Root({ children }: { children: ReactNode }) { | ||
return ( | ||
<html> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
3 changes: 3 additions & 0 deletions
3
test/production/app-dir/metadata-img-too-large/twitter-image/app/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function Page() { | ||
return <p>hello world</p> | ||
} |
21 changes: 21 additions & 0 deletions
21
test/production/app-dir/metadata-img-too-large/twitter-image/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { nextTestSetup } from 'e2e-utils' | ||
import { generatePNG } from '../generate-image' | ||
|
||
describe('metadata-img-too-large twitter-image', () => { | ||
const { next } = nextTestSetup({ | ||
files: __dirname, | ||
skipStart: true, | ||
}) | ||
|
||
const pngFile = generatePNG(6) | ||
|
||
it('should throw when twitter-image file size exceeds 5MB', async () => { | ||
await next.patchFile('app/twitter-image.png', pngFile as any) | ||
|
||
await next.build() | ||
const { cliOutput } = next | ||
expect(cliOutput).toMatch( | ||
/Error: File size for Twitter image ".*\/app\/twitter-image\.png" exceeds 5MB/ | ||
) | ||
}) | ||
}) |
6 changes: 6 additions & 0 deletions
6
test/production/app-dir/metadata-img-too-large/twitter-image/next.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* @type {import('next').NextConfig} | ||
*/ | ||
const nextConfig = {} | ||
|
||
module.exports = nextConfig |