Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update decoder to correctly handle grayscale PNGs #23393

Merged
merged 6 commits into from Apr 1, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 27 additions & 12 deletions packages/next/next-server/server/lib/squoosh/png/squoosh_png.js
@@ -1,5 +1,29 @@
import { TextDecoder } from '../text-decoder'

let wasm

let cachedTextDecoder = new TextDecoder('utf-8', {
ignoreBOM: true,
fatal: true,
})

cachedTextDecoder.decode()

let cachegetUint8Memory0 = null
function getUint8Memory0() {
if (
cachegetUint8Memory0 === null ||
cachegetUint8Memory0.buffer !== wasm.memory.buffer
) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer)
}
return cachegetUint8Memory0
}

function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len))
}

let cachegetUint8ClampedMemory0 = null
function getUint8ClampedMemory0() {
if (
Expand Down Expand Up @@ -30,17 +54,6 @@ function addHeapObject(obj) {
return idx
}

let cachegetUint8Memory0 = null
function getUint8Memory0() {
if (
cachegetUint8Memory0 === null ||
cachegetUint8Memory0.buffer !== wasm.memory.buffer
) {
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer)
}
return cachegetUint8Memory0
}

let WASM_VECTOR_LEN = 0

function passArray8ToWasm0(arg, malloc) {
Expand Down Expand Up @@ -161,7 +174,9 @@ async function init(input) {
var ret = new ImageData(v0, arg2 >>> 0, arg3 >>> 0)
return addHeapObject(ret)
}

imports.wbg.__wbindgen_throw = function (arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1))
}
if (
typeof input === 'string' ||
(typeof Request === 'function' && input instanceof Request) ||
Expand Down
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions test/integration/image-optimizer/test/index.test.js
Expand Up @@ -482,6 +482,26 @@ function runTests({ w, isDev, domains }) {
await expectWidth(res, 400)
})

it('should not change the color type of a png', async () => {
// https://github.com/vercel/next.js/issues/22929
// A grayscaled PNG with transparent pixels.
const query = { url: '/grayscale.png', w: largeSize, q: 80 }
const opts = { headers: { accept: 'image/png' } }
const res = await fetchViaHTTP(appPort, '/_next/image', query, opts)
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toBe('image/png')
expect(res.headers.get('cache-control')).toBe(
'public, max-age=0, must-revalidate'
)

const png = await res.buffer()

// Read the color type byte (offset 9 + magic number 16).
// http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
const colorType = png.readUIntBE(25, 1)
expect(colorType).toBe(4)
})

it("should error if the resource isn't a valid image", async () => {
const query = { url: '/test.txt', w, q: 80 }
const opts = { headers: { accept: 'image/webp' } }
Expand Down