| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
…cessary napi_unwrap returns void* and does no type check, so it cannot answer "is this JS object one of my type". The Node-API answer is napi_type_tag_object / napi_check_object_type_tag, and until now no engine here exposed them: NAPI_VERSION is pinned to 5 and the whole type-tag surface sits behind NAPI_VERSION >= 8, so even the V8 body was dead code -- and would not have compiled, since the NAPI_PRIVATE_KEY it calls was commented out. Raising NAPI_VERSION is the wrong lever, because napi_get_version returns that macro and Chakra and JavaScriptCore implement none of v6/v7. So the type-tag declarations, the napi_type_tag struct and the Napi::TypeTaggable wrappers are ungated instead and NAPI_VERSION stays at 5, understating capability rather than overstating it. V8 keeps the tag under a v8::Private, which script cannot reach. QuickJS, Chakra and JavaScriptCore have no per-object native slot for an arbitrary object, so each stores the tag in a WeakMap held only on napi_env__. A hidden own property would not do: even under a symbol, Object.getOwnPropertySymbols hands script the key, and the tag could then be read off a real instance and replayed onto a spoofed object. Three unwrap holes are fixed alongside, because a type tag is only useful once unwrap itself is sound. The first two are BabylonJS#226; the third was found by the new test: - The V8 internal-field optimisation replaced a private-property lookup and dropped its IsExternal() validity check with it, so Unwrap read field 0 off any object and dereferenced it. napi_wrap had the mirror gap, writing field 0 of an object that has none. Both now require InternalFieldCount() >= 1, and Unwrap rejects the null that napi_remove_wrap leaves behind -- two integer compares, still cheaper than the private-property lookup upstream does. - QuickJS napi_unwrap searched the prototype chain, so Object.create(realInstance) resolved to the real instance's native pointer. The chain walk is gone from unwrap, remove_wrap and wrap, so only an object created by a napi class constructor can be wrapped -- the same constraint the V8 internal field already imposes. - JavaScriptCore had the identical defect one layer down: NativeInfo::Query used JSObjectHasPropertyForKey / JSObjectGetPropertyForKey, both of which search the prototype chain. It applies to references too, so two distinct objects reported the same object id. JSC's C API has no own-property accessor, so the env caches Object.prototype.hasOwnProperty, which is what the Chakra and QuickJS ports already do. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Please can you look at #189? after merging it we can it go onto proper NAPI v8 support instead of a non-standard offshoot that will keep BabylonNative users locked out of the modern NodeJS addon ecosystem. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
[Created by Copilot on behalf of @bghgary]
Context
napi_unwrap returns void* and does no type check, so it cannot answer "is this JS object one of my type". BabylonNative#1844 hand-rolls a ~100-line registry to get that answer, because the Node-API primitive for it — napi_type_tag_object / napi_check_object_type_tag — is unreachable here: NAPI_VERSION is pinned to 5 and the whole type-tag surface sits behind NAPI_VERSION >= 8. Even the V8 body was dead code, and would not have compiled, since the NAPI_PRIVATE_KEY it calls is commented out.
Worth a look
Verification
Built and ran the full suite on all six engine configurations: V8, Chakra, QuickJS, JSI and Hermes on Windows x64, and JavaScriptCore on Ubuntu 24.04. The new NodeApi.TypeTags test was also run against each guard reverted in turn — V8 dies with an access violation, QuickJS and JavaScriptCore hand back the wrong object's pointer.
Fixes #226.