mirror of
https://github.com/morluto/rea.git
synced 2026-10-29 10:55:57 +00:00
fix(javascript): follow actual receivers in nested intrinsic calls (#1912)
Consume arguments per generic function invocation rather than property-chain depth. Preserve the callable receiver through call/apply, Reflect.apply and bound invocation. Cover nested mutations and fresh targets through source analysis and inert production CLI/MCP fixtures. Fixes #1909. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
This commit is contained in:
4 files changed
+99
-45
No files matched your search
@@ -534,6 +534,50 @@ describe("Electron module interop capture and scope", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Electron module interop generic invocations", () => {
|
||||
it.each([
|
||||
'const change = Function.prototype.call.bind(Object.defineProperty); change(null,Object,"create",{value:customCreate});',
|
||||
'const call = Function.prototype.call; const change = call.bind(Object.defineProperty); change(null,Object,"create",{value:customCreate});',
|
||||
'const change = Function.prototype.call.bind(Object.defineProperty,null,Object,"create"); change({value:customCreate});',
|
||||
'Function.prototype.call.apply(Object.defineProperty,[null,Object,"create",{value:customCreate}]);',
|
||||
'Reflect.apply(Function.prototype.call,Object.defineProperty,[null,Object,"create",{value:customCreate}]);',
|
||||
'const change = Function.prototype.apply.bind(Object.defineProperty); change(null,[Object,"create",{value:customCreate}]);',
|
||||
'Reflect.apply(Function.prototype.apply,Object.defineProperty,[null,[Object,"create",{value:customCreate}]]);',
|
||||
'const first = Function.prototype.call.bind(Object.defineProperty,null,Object,"create"); const change = first.bind(fake); change({value:customCreate});',
|
||||
"const change = Function.prototype.call.bind(Object.defineProperty); change(null,...args);",
|
||||
"const change = Function.prototype.apply.bind(Object.defineProperty); change(null,args);",
|
||||
'const change = Function.prototype.call.bind(Object.defineProperty,null,...args); change(metadata,"x",{value:1});',
|
||||
'Function.prototype.call.call.call(Object.defineProperty,null,Object,"create",{value:customCreate});',
|
||||
'Object.defineProperty.call.call(Object.defineProperty,null,Object,"create",{value:customCreate});',
|
||||
'Function.prototype.apply.apply(Object.defineProperty,[null,[Object,"create",{value:customCreate}]]);',
|
||||
'const change = Object.defineProperty.call.bind(Object.defineProperty); change(null,Object,"create",{value:customCreate});',
|
||||
'const change = Function.prototype.call.call.bind(Object.defineProperty,null,Object,"create"); change({value:customCreate});',
|
||||
])("follows the callable receiver of a generic invocation: %s", (write) => {
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(
|
||||
`${write}\n${ROLLDOWN_MODULE_INTEROP}\n${IMPORT} ${WRAP} ${WINDOW}`,
|
||||
).electron.browser_windows,
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
'const change = Function.prototype.call.bind(Object.defineProperty); change(null,metadata,"x",{value:1});',
|
||||
'const change = Function.prototype.call.bind(Object.defineProperty,null,metadata,"x"); change({value:1});',
|
||||
'Function.prototype.call.call(Object.defineProperty,null,metadata,"x",{value:1});',
|
||||
'const change = Function.prototype.apply.bind(Object.defineProperty); change(null,[metadata,"x",{value:1}]);',
|
||||
'Reflect.apply(Function.prototype.apply,Object.defineProperty,[null,[metadata,"x",{value:1}]]);',
|
||||
'Function.prototype.call.call.call(Object.defineProperty,null,metadata,"x",{value:1});',
|
||||
'Function.prototype.apply.apply(Object.defineProperty,[null,[metadata,"x",{value:1}]]);',
|
||||
'const change = Object.defineProperty.call.bind(Object.defineProperty); change(null,metadata,"x",{value:1});',
|
||||
])("preserves fresh targets through a generic invocation: %s", (write) => {
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(
|
||||
`const metadata = {}; ${write}\n${ROLLDOWN_MODULE_INTEROP}\n${IMPORT} ${WRAP} ${WINDOW}`,
|
||||
).electron.browser_windows,
|
||||
).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Electron module interop bound mutators", () => {
|
||||
it.each([
|
||||
'const change = Object.defineProperty.bind(null); change(Object,"create",{value:customCreate});',
|
||||
@@ -560,6 +604,9 @@ describe("Electron module interop bound mutators", () => {
|
||||
'Reflect.apply = Object.defineProperty; Reflect.apply(Object,"create",{value:customCreate});',
|
||||
'const apply = Reflect.apply; Reflect.apply = Object.defineProperty; Reflect.apply(Object,"create",{value:customCreate});',
|
||||
'const change = Reflect.set.bind(null,Object,"create"); change(customCreate);',
|
||||
'const change = Object.defineProperty.call; change.call(Object.defineProperty,null,Object,"create",{value:customCreate});',
|
||||
'const {apply:change} = Object.defineProperty; change.call(Object.defineProperty,null,[Object,"create",{value:customCreate}]);',
|
||||
'const change = Reflect.apply.call; change.call(Reflect.apply,null,Object.defineProperty,null,[Object,"create",{value:customCreate}]);',
|
||||
'Reflect.set({},"create",customCreate,Object);',
|
||||
'const metadata = {}; Reflect.set(metadata,"create",customCreate,Object);',
|
||||
'const change = Reflect.set.bind(null,{},"create",customCreate); change(Object);',
|
||||
@@ -568,9 +615,6 @@ describe("Electron module interop bound mutators", () => {
|
||||
'Reflect.set({},"create",...valuesAndReceivers);',
|
||||
"Reflect.set({},...keysValuesAndReceivers);",
|
||||
'Reflect.set({},"create",customCreate,receiver);',
|
||||
'const change = Object.defineProperty.call; change(null,Object,"create",{value:customCreate});',
|
||||
'const {apply:change} = Object.defineProperty; change(null,[Object,"create",{value:customCreate}]);',
|
||||
'const change = Reflect.apply.call; change(null,Object.defineProperty,null,[Object,"create",{value:customCreate}]);',
|
||||
])("rejects intrinsic writes through a bound mutator: %s", (write) => {
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(
|
||||
@@ -593,8 +637,8 @@ describe("Electron module interop bound mutators", () => {
|
||||
'const change = Object.defineProperty.bind(null,Object,"create");',
|
||||
'Object.defineProperty.call(null,metadata,"x",{value:1});',
|
||||
'Object.defineProperty.apply(null,[metadata,"x",{value:1}]);',
|
||||
'const change = Object.defineProperty.call; change(null,metadata,"x",{value:1});',
|
||||
'const {apply:change} = Object.defineProperty; change(null,[metadata,"x",{value:1}]);',
|
||||
'const change = Object.defineProperty.call; change.call(Object.defineProperty,null,metadata,"x",{value:1});',
|
||||
'const {apply:change} = Object.defineProperty; change.call(Object.defineProperty,null,[metadata,"x",{value:1}]);',
|
||||
'Reflect.set(metadata,"x",1,{});',
|
||||
'const receiver = {}; Reflect.set({},"x",1,receiver);',
|
||||
])("keeps a fresh bound target or unused binding separate: %s", (write) => {
|
||||
|
||||
Reference in new issue
Block a user