Repository navigation
fix: isolate locale properties in createLocalReq #18280
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
base: main
Are you sure you want to change the base?
Changes from all commits
5e2ce12
b67d2b8
47876d2
650a6b1
fcfab96
2c590d9
58ea817
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,11 +21,54 @@ export function isolateObjectProperty<T extends object>(object: T, key: (keyof T | |
| return Reflect.get(delegate, p, receiver) | ||
| } | ||
| // Use target as receiver to preserve private field access (e.g., Request#headers in Node 24+) | ||
| return Reflect.get(target, p, target) | ||
| const value = Reflect.get(target, p, target) | ||
| // Methods must run against the target: invoked as proxy.method(), `this` | ||
| // would be the proxy and private field access (e.g., Request#text reading | ||
| // #state in undici) throws "Cannot read private member". | ||
| if (typeof value === 'function') { | ||
| return value.bind(target) | ||
| } | ||
| return value | ||
| }, | ||
| getOwnPropertyDescriptor(target, p) { | ||
| if (keys.includes(p as keyof T)) { | ||
| const descriptor = Reflect.getOwnPropertyDescriptor(delegate, p) | ||
|
|
||
| if (descriptor) { | ||
| const targetDescriptor = Reflect.getOwnPropertyDescriptor(target, p) | ||
|
Comment on lines
+35
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis
Return a descriptor the target can hold when it is non-extensible. Proxy descriptor invariants reject reports that the target cannot support when the target is non-extensible. Two cases apply:
🐛 Suggested fix
🤖 Prompt for AI Agents
|
||
|
|
||
| // A key held only in the delegate is not an own property of the | ||
| // target, so it can only be reported as configurable. Keep the | ||
| // target's configurability when it also holds the key. | ||
| return { | ||
| ...descriptor, | ||
| configurable: targetDescriptor ? targetDescriptor.configurable : true, | ||
| } | ||
|
Comment on lines
+43
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Preserve the full descriptor constraints of non-configurable target properties. If an isolated target property is non-configurable and non-enumerable, 🤖 Prompt for AI Agents
|
||
| } | ||
|
|
||
| const targetDescriptor = Reflect.getOwnPropertyDescriptor(target, p) | ||
|
|
||
| // An isolated key missing from the delegate counts as absent, | ||
| // unless the target holds it as non-configurable, which a proxy | ||
| // is not allowed to hide. | ||
| return targetDescriptor && !targetDescriptor.configurable ? targetDescriptor : undefined | ||
| } | ||
| return Reflect.getOwnPropertyDescriptor(target, p) | ||
| }, | ||
| has(target, p) { | ||
| return Reflect.has(keys.includes(p as keyof T) ? delegate : target, p) | ||
| }, | ||
| ownKeys(target) { | ||
| const targetKeys = Reflect.ownKeys(target) | ||
|
|
||
| // Extra keys can only be reported when the target is extensible, | ||
| // otherwise the result must match the target's keys exactly. | ||
| if (!Object.isExtensible(target)) { | ||
| return targetKeys | ||
| } | ||
|
|
||
| return [...targetKeys, ...Reflect.ownKeys(delegate).filter((k) => !targetKeys.includes(k))] | ||
| }, | ||
| set(target, p, newValue, _receiver) { | ||
| if (keys.includes(p as keyof T)) { | ||
| // in case of transactionID we must ignore any receiver, because | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 13865
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 21081
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 14132
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 2088
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 1141
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 4320
🏁 Script executed:
Repository: payloadcms/payload
Length of output: 3480
Bind native
Requestmethods to the underlying request.handleEndpointspasses the nativeRequestthroughcreatePayloadRequestFromWebRequest, which returns a proxy. The registered upload endpoint receives that proxy and callsreq.json(). NativeRequestmethods can reject the proxy receiver, so/upload-instructionsrequests can fail before parsing the body.Suggested fix
🤖 Prompt for AI Agents