summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2019-02-25 11:44:31 -0500
committerJason Carey <jcarey@argv.me>2019-02-26 16:17:29 -0500
commit3b2e02cb27fd4e1814066ebfe7e67699ffbe4581 (patch)
tree5ebbd929d9a7845dc9bd815571e20ff792ed1cf9 /src
parent76bea9daaf67deee934c50e6ebcb4e5d5bbb397e (diff)
downloadmongo-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.cpp2
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.cpp42
-rw-r--r--src/mongo/scripting/mozjs/objectwrapper.h7
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,