diff options
author | Jason Carey <jcarey@argv.me> | 2019-02-25 11:44:31 -0500 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2019-02-26 16:17:29 -0500 |
commit | 3b2e02cb27fd4e1814066ebfe7e67699ffbe4581 (patch) | |
tree | 5ebbd929d9a7845dc9bd815571e20ff792ed1cf9 /src | |
parent | 76bea9daaf67deee934c50e6ebcb4e5d5bbb397e (diff) | |
download | mongo-3b2e02cb27fd4e1814066ebfe7e67699ffbe4581.tar.gz |
SERVER-39521 Don't skip _id in ObjWrapper::toBSON
We incorrectly checked for _id with alreadyHasOwnField, instead of
hasOwnField, which caused us to miss _id fields set from c++.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/scripting/mozjs/db.cpp | 2 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/objectwrapper.cpp | 42 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/objectwrapper.h | 7 |
3 files changed, 49 insertions, 2 deletions
diff --git a/src/mongo/scripting/mozjs/db.cpp b/src/mongo/scripting/mozjs/db.cpp index 228cd3d4acc..4748e9a308b 100644 --- a/src/mongo/scripting/mozjs/db.cpp +++ b/src/mongo/scripting/mozjs/db.cpp @@ -75,7 +75,7 @@ void DBInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* } // Check if this exists on the parent, ie. DBCollection::resolve case - if (parentWrapper.hasOwnField(id)) { + if (parentWrapper.alreadyHasOwnField(id)) { parentWrapper.getValue(id, &coll); o.defineProperty(id, coll, 0); diff --git a/src/mongo/scripting/mozjs/objectwrapper.cpp b/src/mongo/scripting/mozjs/objectwrapper.cpp index 306c1f4ef64..3c57e262029 100644 --- a/src/mongo/scripting/mozjs/objectwrapper.cpp +++ b/src/mongo/scripting/mozjs/objectwrapper.cpp @@ -203,6 +203,41 @@ bool ObjectWrapper::Key::hasOwn(JSContext* cx, JS::HandleObject o) { switch (_type) { case Type::Field: + if (JS_HasOwnProperty(cx, o, _field, &has)) + return has; + break; + case Type::Index: { + JS::RootedId id(cx); + + // This is a little different because there is no JS_HasOwnElement + if (JS_IndexToId(cx, _idx, &id) && JS_HasOwnPropertyById(cx, o, id, &has)) + return has; + break; + } + case Type::Id: { + JS::RootedId id(cx, _id); + + if (JS_HasOwnPropertyById(cx, o, id, &has)) + return has; + break; + } + case Type::InternedString: { + InternedStringId id(cx, _internedString); + + if (JS_HasOwnPropertyById(cx, o, id, &has)) + return has; + break; + } + } + + throwCurrentJSException(cx, ErrorCodes::InternalError, "Failed to hasOwn value on a JSObject"); +} + +bool ObjectWrapper::Key::alreadyHasOwn(JSContext* cx, JS::HandleObject o) { + bool has; + + switch (_type) { + case Type::Field: if (JS_AlreadyHasOwnProperty(cx, o, _field, &has)) return has; break; @@ -226,7 +261,8 @@ bool ObjectWrapper::Key::hasOwn(JSContext* cx, JS::HandleObject o) { } } - throwCurrentJSException(cx, ErrorCodes::InternalError, "Failed to hasOwn value on a JSObject"); + throwCurrentJSException( + cx, ErrorCodes::InternalError, "Failed to alreadyHasOwn value on a JSObject"); } void ObjectWrapper::Key::del(JSContext* cx, JS::HandleObject o) { @@ -456,6 +492,10 @@ bool ObjectWrapper::hasOwnField(Key key) { return key.hasOwn(_context, _object); } +bool ObjectWrapper::alreadyHasOwnField(Key key) { + return key.alreadyHasOwn(_context, _object); +} + void ObjectWrapper::callMethod(const char* field, const JS::HandleValueArray& args, JS::MutableHandleValue out) { diff --git a/src/mongo/scripting/mozjs/objectwrapper.h b/src/mongo/scripting/mozjs/objectwrapper.h index 7516807b130..ea006f82523 100644 --- a/src/mongo/scripting/mozjs/objectwrapper.h +++ b/src/mongo/scripting/mozjs/objectwrapper.h @@ -85,6 +85,7 @@ public: void set(JSContext* cx, JS::HandleObject o, JS::HandleValue value); bool has(JSContext* cx, JS::HandleObject o); bool hasOwn(JSContext* cx, JS::HandleObject o); + bool alreadyHasOwn(JSContext* cx, JS::HandleObject o); void define( JSContext* cx, JS::HandleObject o, unsigned attrs, JSNative getter, JSNative setter); void define(JSContext* cx, JS::HandleObject o, JS::HandleValue value, unsigned attrs); @@ -138,9 +139,15 @@ public: void rename(Key key, const char* to); + // has field walks the prototype heirarchy bool hasField(Key key); + + // has own field checks for the field directly on the object bool hasOwnField(Key key); + // already how own field checks for the field directly on the object, ignoring C++ hooks + bool alreadyHasOwnField(Key key); + void callMethod(const char* name, const JS::HandleValueArray& args, JS::MutableHandleValue out); void callMethod(const char* name, JS::MutableHandleValue out); void callMethod(JS::HandleValue fun, |