From 061443f8043c164c9efe25b83eebe3a760c08f26 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 5 May 2023 21:55:47 +0200 Subject: [PATCH] Fix issue where nextP is not replaced in searchParams (#49315) ## What? Fixes a bug with iterating over the searchParams while `delete` and `append` are used. This is the minimal example of what happened: ```js const searchParams = new URLSearchParams('a=valueA&b=valueB&c=valueC') for(const key of searchParams.keys()) { console.log(key) if(key === 'b') { searchParams.delete('b') searchParams.append('bb', 'valueBB') } } ``` Output is: ``` a b bb ``` Instead of: ``` a b c bb ``` The reason seems to be that the iterator uses an internal count while iterating, e.g. the implementation in JavaScriptCore: https://github.com/WebKit/WebKit/blob/0743137c2f4f602963fc409ebc56ecd6690d204d/Source/WebCore/html/URLSearchParams.cpp#L155-L163 This can't be reproduced with `new Map()` or `new Set()`. This PR fixes it by only iterating over the keys that are known before the loop starts. Fixes an issue [reported by users](https://vercel.slack.com/archives/C03S8ED1DKM/p1683007482211449). --- packages/next/src/server/web/adapter.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index d05c2114e5..e96f5d4422 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -97,7 +97,10 @@ export async function adapter( nextConfig: params.request.nextConfig, }) - for (const key of requestUrl.searchParams.keys()) { + // Iterator uses an index to keep track of the current iteration. Because of deleting and appending below we can't just use the iterator. + // Instead we use the keys before iteration. + const keys = [...requestUrl.searchParams.keys()] + for (const key of keys) { const value = requestUrl.searchParams.getAll(key) if (