share collections in middleware vm context (#31043)

When libraries are required outside of the middleware function context and they do checks such as `a instanceof Uint8Array` since the constructors are different between the two contexts they'll always yield false.

This is a problem for libraries validating user input as well as the WebCryptoAPI polyfill used outside of Edge Functions.

- Fixes #30477
- Fixes #30911

This is only a problem for the sandbox runtime, not when ran inside an Edge Function.
This commit is contained in:
Filip Skokan 2021-11-09 20:57:19 +01:00 committed by GitHub
parent 764e29c170
commit 0985b0b472
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 1 deletions

View file

@ -87,6 +87,30 @@ export async function run(params: {
TransformStream,
URL,
URLSearchParams,
// Indexed collections
Array,
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
BigInt64Array,
BigUint64Array,
// Keyed collections
Map,
Set,
WeakMap,
WeakSet,
// Structured data
ArrayBuffer,
SharedArrayBuffer,
}
context.self = context

View file

@ -2,7 +2,7 @@
import { NextResponse } from 'next/server'
export function middleware(request) {
export async function middleware(request) {
const url = request.nextUrl
if (url.pathname.endsWith('/globalthis')) {
@ -13,6 +13,28 @@ export function middleware(request) {
})
}
if (url.pathname.endsWith('/webcrypto')) {
const response = {}
try {
const algorithm = {
name: 'RSA-PSS',
hash: 'SHA-256',
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
modulusLength: 2048,
}
const keyUsages = ['sign', 'verify']
await crypto.subtle.generateKey(algorithm, false, keyUsages)
} catch (err) {
response.error = true
} finally {
return new NextResponse(JSON.stringify(response), {
headers: {
'content-type': 'application/json; charset=utf-8',
},
})
}
}
return new Response(null, {
headers: {
'req-url-basepath': request.nextUrl.basePath,

View file

@ -350,6 +350,12 @@ function interfaceTests(locale = '') {
expect(globals.length > 0).toBe(true)
})
it(`${locale} collection constructors are shared`, async () => {
const res = await fetchViaHTTP(context.appPort, '/interface/webcrypto')
const response = await res.json()
expect('error' in response).toBe(false)
})
it(`${locale} should validate request url parameters from a static route`, async () => {
const res = await fetchViaHTTP(
context.appPort,