author | Bobby Holley <bobbyholley@gmail.com> |
Fri, 11 Jul 2014 09:09:21 -0700 | |
changeset 193612 | 4e45b8a55bfbdf96b6ca113efab4bbb926decf8e |
parent 193611 | 8fed72d0f4961bedc9e726b229e66a3d92914580 |
child 193613 | e171c0317b8279076ce884ec756a204afb774290 |
push id | 27123 |
push user | ryanvm@gmail.com |
push date | Fri, 11 Jul 2014 20:35:05 +0000 |
treeherder | mozilla-central@84bd8d9f4256 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gabor |
bugs | 987669 |
milestone | 33.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -82,16 +82,21 @@ const char* const XPCJSRuntime::mStrings "__exposedProps__", // IDX_EXPOSEDPROPS "eval", // IDX_EVAL "controllers", // IDX_CONTROLLERS "realFrameElement", // IDX_REALFRAMEELEMENT "length", // IDX_LENGTH "name", // IDX_NAME "undefined", // IDX_UNDEFINED "", // IDX_EMPTYSTRING + "fileName", // IDX_FILENAME + "lineNumber", // IDX_LINENUMBER + "columnNumber", // IDX_COLUMNNUMBER + "stack", // IDX_STACK + "message" // IDX_MESSAGE }; /***************************************************************************/ static mozilla::Atomic<bool> sDiscardSystemSource(false); bool xpc::ShouldDiscardSystemSource() { return sDiscardSystemSource; }
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -477,16 +477,21 @@ public: IDX_EXPOSEDPROPS , IDX_EVAL , IDX_CONTROLLERS , IDX_REALFRAMEELEMENT , IDX_LENGTH , IDX_NAME , IDX_UNDEFINED , IDX_EMPTYSTRING , + IDX_FILENAME , + IDX_LINENUMBER , + IDX_COLUMNNUMBER , + IDX_STACK , + IDX_MESSAGE , IDX_TOTAL_COUNT // just a count of the above }; JS::HandleId GetStringID(unsigned index) const { MOZ_ASSERT(index < IDX_TOTAL_COUNT, "index out of range"); // fromMarkedLocation() is safe because the string is interned. return JS::HandleId::fromMarkedLocation(&mStrIDs[index]);
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -688,16 +688,43 @@ JSXrayTraits::resolveOwnProperty(JSConte } if (!JS_WrapObject(cx, &standardProto)) return false; FillPropertyDescriptor(desc, wrapper, JSPROP_PERMANENT | JSPROP_READONLY, ObjectValue(*standardProto)); return true; } } + } else if (IsErrorObjectKey(key)) { + // The useful state of error objects is (unfortunately) represented + // as own data properties per-spec. This means that we can't have a + // a clean representation of the data (free from tampering) without + // doubling the slots of Error objects, which isn't great. So we + // forward these properties to the underlying object and then just + // censor any values with the wrong type. This limits the ability + // of content to do anything all that confusing. + bool isErrorIntProperty = + id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LINENUMBER) || + id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_COLUMNNUMBER); + bool isErrorStringProperty = + id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_FILENAME) || + id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_STACK) || + id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_MESSAGE); + if (isErrorIntProperty || isErrorStringProperty) { + RootedObject waiver(cx, wrapper); + if (!WrapperFactory::WaiveXrayAndWrap(cx, &waiver)) + return false; + if (!JS_GetOwnPropertyDescriptorById(cx, waiver, id, desc)) + return false; + bool valueMatchesType = (isErrorIntProperty && desc.value().isInt32()) || + (isErrorStringProperty && desc.value().isString()); + if (desc.hasGetterOrSetter() || !valueMatchesType) + FillPropertyDescriptor(desc, nullptr, 0, UndefinedValue()); + return true; + } } // The rest of this function applies only to prototypes. return true; } // The non-HasPrototypes semantics implemented by traditional Xrays are kind // of broken with respect to |own|-ness and the holder. The common code @@ -955,16 +982,25 @@ JSXrayTraits::enumerateNames(JSContext * return false; if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_NAME))) return false; // Handle the .prototype property on standard constructors. if (constructorFor(holder) != JSProto_Null) { if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTOTYPE))) return false; } + } else if (IsErrorObjectKey(key)) { + if (!props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_FILENAME)) || + !props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_LINENUMBER)) || + !props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_COLUMNNUMBER)) || + !props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_STACK)) || + !props.append(GetRTIdByIndex(cx, XPCJSRuntime::IDX_MESSAGE))) + { + return false; + } } // The rest of this function applies only to prototypes. return true; } // Grab the JSClass. We require all Xrayable classes to have a ClassSpec. const js::Class *clasp = js::GetObjectClass(target);