Skip to content

Commit

Permalink
Remove parent from JSCallableProxy
Browse files Browse the repository at this point in the history
Summary:
Original Author: [email protected]
Original Git:
Original Reviewed By: avp
Original Revision: D68907619

Like regular Proxy, JSCallableProxy should not have a parent, which may
be observed by the prototype traversal in the `stack` accessor.

Reviewed By: avp

Differential Revision: D68939221

fbshipit-source-id: a353066acea6e266173a001c54409bdadd6f0a06
  • Loading branch information
neildhar authored and facebook-github-bot committed Jan 31, 2025
1 parent 6bf2a6a commit 94c132c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
4 changes: 0 additions & 4 deletions include/hermes/VM/JSCallableProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ class JSCallableProxy : public NativeFunction {

static PseudoHandle<JSCallableProxy> create(Runtime &runtime);

static CallResult<HermesValue> create(
Runtime &runtime,
Handle<JSObject> prototype);

void setTargetAndHandler(
Runtime &runtime,
Handle<JSObject> target,
Expand Down
14 changes: 2 additions & 12 deletions lib/VM/JSCallableProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,15 @@ void JSCallableProxyBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
PseudoHandle<JSCallableProxy> JSCallableProxy::create(Runtime &runtime) {
auto *cproxy = runtime.makeAFixed<JSCallableProxy>(
runtime,
Handle<JSObject>::vmcast(&runtime.objectPrototype),
HandleRootOwner::makeNullHandle<JSObject>(),
runtime.getHiddenClassForPrototype(
runtime.objectPrototypeRawPtr,
JSObject::numOverlapSlots<JSCallableProxy>()));
nullptr, JSObject::numOverlapSlots<JSCallableProxy>()));

cproxy->flags_.proxyObject = true;

return JSObjectInit::initToPseudoHandle(runtime, cproxy);
}

CallResult<HermesValue> JSCallableProxy::create(
Runtime &runtime,
Handle<JSObject> prototype) {
assert(
prototype.get() == runtime.objectPrototypeRawPtr &&
"JSCallableProxy::create() can only be used with object prototype");
return create(runtime).getHermesValue();
}

void JSCallableProxy::setTargetAndHandler(
Runtime &runtime,
Handle<JSObject> target,
Expand Down
37 changes: 37 additions & 0 deletions test/hermes/regress-proxy-parent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// RUN: %hermes %s | %FileCheck --match-full-lines %s
// RUN: %shermes -exec %s | %FileCheck --match-full-lines %s

// We previously set the parent of a proxy to Object.prototype, which is
// incorrect and may be observed by the prototype traversal in the error stack
// getter. Test this by installing stack trace information on Object.prototype
// and verifying that the stack trace getter does not find it.

// Install stack trace information on Object.prototype.
Error.captureStackTrace(Object.prototype);

// Check that lookup on a regular proxy fails.
try{
var p = new Proxy(new Error(), {});
p.stack;
} catch (e) {
print(e);
}
// CHECK: TypeError: Error.stack getter called with an invalid receiver

// Check that lookup on a callable proxy fails.
try {
function foo(){}
foo.__proto__ = new Error();
var cp = new Proxy(foo, {});
cp.stack;
} catch (e) {
print(e);
}
// CHECK-NEXT: TypeError: Error.stack getter called with an invalid receiver

0 comments on commit 94c132c

Please sign in to comment.