Assertion failure in VM/JSObject.h: "getParent cannot be used with proxy objects"
- Dominant language
- JavaScript
- Stars
- 11.3k
- Forks
- 859
- Avg merge
- 1h 30m
- Merged PRs (30d)
- 3
Description
## Bug Description
Hello, I found a crash in Hermes where valid JavaScript triggers an assertion failure. It seems Hermes incorrectly treats a proxy like an ordinary object
Hermes git revision (if applicable): https://github.com/facebook/hermes/commit/aa4dc53995121184faadceecf2d9d0a535f962c7, the latest commit on static_h
OS: Linux
## Steps To Reproduce
1. build the debug version of the Hermes CLI
2. run `hermes crash.js`
crash.js
```js
class A {}
let h = {};
class B extends new Proxy(A, h) {}
class C extends B {
static f() {
B.y = 0;
super.x;
}
}
Object.setPrototypeOf(C.prototype, new Proxy({}, {}));
h.get = (a, b, r) => r.y = 1;
C.f();
```
output:
```sh
hermes: hermes/include/hermes/VM/JSObject.h:464: const hermes::vm::GCPointer& hermes::vm::JSObject::getParentGCPtr() const: Assertion `!flags_.proxyObject && "getParent cannot be used with proxy objects"' failed.
Aborted (core dumped)
```
backtrace:
```sh
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007ffff704527e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff70288ff in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff702881b in __assert_fail_base (fmt=0x7ffff71d01e8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x5555565c1950 "!flags_.proxyObject && \"getParent cannot be used with proxy objects\"",
file=file@entry=0x5555565c1920 "hermes/include/hermes/VM/JSObject.h", line=line@entry=464,
function=function@entry=0x5555565c18c0 "const hermes::vm::GCPointer& hermes::vm::JSObject::getParentGCPtr() const") at ./assert/assert.c:96
#6 0x00007ffff703b517 in __assert_fail (
assertion=0x5555565c1950 "!flags_.proxyObject && \"getParent cannot be used with proxy objects\"",
file=0x5555565c1920 "hermes/include/hermes/VM/JSObject.h", line=464,
function=0x5555565c18c0 "const hermes::vm::GCPointer& hermes::vm::JSObject::getParentGCPtr() const")
at ./assert/assert.c:105
#7 0x0000555555d59909 in hermes::vm::JSObject::getParentGCPtr (this=0x7ffff44482d8)
at hermes/include/hermes/VM/JSObject.h:464
#8 0x0000555555d598ae in hermes::vm::JSObject::getParent (this=0x7ffff44482d8, runtime=...)
at hermes/include/hermes/VM/JSObject.h:459
#9 0x0000555555dc01d3 in hermes::vm::JSObject::tryCacheAddProperty (self=0x7ffff4448600, runtime=...,
runtimeModule=0x555556c58df0, unit=0x0, writeCacheEntry=0x555556c6fc28, startClazz=0x7ffff37e9788, slot=7,
resultClazz=0x7ffff37e96d0) at hermes/lib/VM/JSObject.cpp:2942
#10 0x0000555555dc0786 in hermes::vm::JSObject::addOwnPropertyImpl (selfHandle=..., runtime=..., name=..., propertyFlags=...,
valueOrAccessor=..., runtimeModule=0x555556c58df0, unit=0x0, cacheEntry=0x555556c6fc28)
at hermes/lib/VM/JSObject.cpp:3028
#11 0x0000555555dbffc2 in hermes::vm::JSObject::addOwnProperty (selfHandle=..., runtime=..., name=..., dpFlags=...,
valueOrAccessor=..., opFlags=..., runtimeModule=0x555556c58df0, unit=0x0, cacheEntry=0x555556c6fc28)
at hermes/lib/VM/JSObject.cpp:2898
--Type for more, q to quit, c to continue without paging--
#12 0x0000555555db9dd5 in hermes::vm::JSObject::putNamedWithReceiver_RJS (selfHandle=..., runtime=..., name=..., valueHandle=...,
receiver=..., opFlags=..., runtimeModule=0x555556c58df0, unit=0x0, cacheEntry=0x555556c6fc28)
at hermes/lib/VM/JSObject.cpp:1600
#13 0x000055555575fcb3 in hermes::vm::JSObject::putNamed_RJS (selfHandle=..., runtime=..., name=..., valueHandle=...,
opFlags=..., runtimeModule=0x555556c58df0, unit=0x0, cacheEntry=0x555556c6fc28)
at hermes/include/hermes/VM/JSObject.h:2126
#14 0x0000555555d90f3a in hermes::vm::Interpreter::putByIdSlowPath_RJS (runtime=..., curCodeBlock=0x555556c6fc00,
base=0x7ffff7700180, value=0x7ffff7700178, cacheIdx=0 '\000', id=..., strictMode=false, tryProp=false)
at hermes/lib/VM/Interpreter-slowpaths.cpp:1807
#15 0x0000555555d90ac5 in hermes::vm::doPutByIdSlowPath_RJS (runtime=..., frameRegs=0x7ffff7700178, ip=0x555556c59906,
curCodeBlock=0x555556c6fc00, idVal=8, strictMode=false, tryProp=false)
at hermes/lib/VM/Interpreter-slowpaths.cpp:1740
#16 0x0000555555d67182 in hermes::vm::Interpreter::interpretFunction (runtime=..., state=...)
at hermes/lib/VM/Interpreter.cpp:2091
#17 0x0000555555d5c054 in hermes::vm::Runtime::interpretFunctionImpl (this=0x555556c63e70, newCodeBlock=0x555556c6fc00)
at hermes/lib/VM/Interpreter.cpp:437
#18 0x0000555555d5c13c in hermes::vm::Runtime::interpretFunction (this=0x555556c63e70, newCodeBlock=0x555556c6fc00)
at hermes/lib/VM/Interpreter.cpp:457
#19 0x0000555555d1ccda in hermes::vm::JSFunction::_interpret (this=0x7ffff44488f8, runtime=...)
at hermes/include/hermes/VM/Callable.h:1041
#20 0x0000555555d221c1 in hermes::vm::JSFunction::_callImpl (selfHandle=..., runtime=...)
at hermes/lib/VM/Callable.cpp:1447
#21 0x0000555555760133 in hermes::vm::Callable::call (selfHandle=..., runtime=...)
at hermes/include/hermes/VM/Callable.h:286
#22 0x0000555555d1e573 in hermes::vm::Callable::executeCall3 (selfHandle=..., runtime=..., thisArgHandle=..., param1=...,
param2=..., param3=..., construct=false) at hermes/lib/VM/Callable.cpp:384
#23 0x0000555555dd0cbc in hermes::vm::(anonymous namespace)::getWithTrap (runtime=..., nameValHandle=..., trap=..., handler=...,
target=..., receiver=...) at hermes/lib/VM/JSProxy.cpp:891
--Type for more, q to quit, c to continue without paging--
#24 0x0000555555dd141e in hermes::vm::JSProxy::getNamed (selfHandle=..., runtime=..., name=..., receiver=...)
at hermes/lib/VM/JSProxy.cpp:969
#25 0x0000555555db7697 in hermes::vm::JSObject::getNamedWithReceiver_RJS (selfHandle=..., runtime=..., name=..., receiver=...,
opFlags=..., cacheEntry=0x555556c6fbc8) at hermes/lib/VM/JSObject.cpp:1201
#26 0x0000555555d8fd71 in hermes::vm::doGetByIdWithReceiverSlowPath_RJS (runtime=..., frameRegs=0x7ffff77000f8,
ip=0x555556c54c79, curCodeBlock=0x555556c6fba0) at hermes/lib/VM/Interpreter-slowpaths.cpp:1609
#27 0x0000555555d668c6 in hermes::vm::Interpreter::interpretFunction (runtime=..., state=...)
at hermes/lib/VM/Interpreter.cpp:1981
#28 0x0000555555d5c054 in hermes::vm::Runtime::interpretFunctionImpl (this=0x555556c63e70, newCodeBlock=0x555556c57840)
at hermes/lib/VM/Interpreter.cpp:437
#29 0x0000555555d5c13c in hermes::vm::Runtime::interpretFunction (this=0x555556c63e70, newCodeBlock=0x555556c57840)
at hermes/lib/VM/Interpreter.cpp:457
#30 0x0000555555e2929f in hermes::vm::Runtime::runBytecode (this=0x555556c63e70, bytecode=..., flags=..., sourceURL=...,
environment=..., thisArg=..., newTarget=...) at hermes/lib/VM/Runtime.cpp:1251
#31 0x00005555556b77a3 in hermes::vm::Runtime::runBytecode (this=0x555556c63e70, bytecode=..., runtimeModuleFlags=...,
sourceURL=..., environment=...) at hermes/include/hermes/VM/Runtime.h:332
#32 0x00005555556bdb39 in hermes::(anonymous namespace)::executeHBCBytecodeImpl (bytecode=..., options=...,
filename=0x7fffffffde38) at hermes/lib/ConsoleHost/ConsoleHost.cpp:1051
#33 0x00005555556be245 in operator() (__closure=0x7fffffffd6a0) at hermes/lib/ConsoleHost/ConsoleHost.cpp:1181
#34 0x00005555556c1b72 in hermes::(anonymous namespace)::maybeCatchException&&, const ExecuteOptions&, const std::string*):: >(const struct {...} &) (f=...)
at hermes/lib/ConsoleHost/ConsoleHost.cpp:746
#35 0x00005555556be299 in hermes::executeHBCBytecode (bytecode=..., options=..., filename=0x7fffffffde38)
at hermes/lib/ConsoleHost/ConsoleHost.cpp:1180
#36 0x00005555556d1b88 in executeHBCBytecodeFromCL (bytecode=std::unique_ptr = {...}, info=...)
at hermes/tools/hermes/hermes.cpp:186
#37 0x00005555556d2346 in main (argc=2, argv=0x7fffffffe078) at hermes/tools/hermes/hermes.cpp:305
```
## The Expected Behavior
There should be no crash as the code is valid.
Contributor guide
Research direction
Build the debug Hermes CLI and reproduce the failure with the supplied crash.js. Start in hermes/lib/VM/JSObject.cpp at tryCacheAddProperty and inspect the related proxy path in hermes/lib/VM/JSProxy.cpp, using the backtrace as the entry point. Done means the valid program runs without the getParent assertion failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, javascript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100