From db89c5a05dc6752e177c67e541e7b4d7a87fff3d Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 21 Feb 2023 20:29:35 +0100 Subject: [PATCH] No issue - Refactor FindErrorInstanceOrPrototype The logic here wasn't very transparent or easy to follow. Doing a positive check to set the result instead of defaulting to it also potentially prevents issues. --- js/src/vm/ErrorObject.cpp | 42 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/js/src/vm/ErrorObject.cpp b/js/src/vm/ErrorObject.cpp index 2fa36089ed..7c966e0fe5 100644 --- a/js/src/vm/ErrorObject.cpp +++ b/js/src/vm/ErrorObject.cpp @@ -557,34 +557,30 @@ FindErrorInstanceOrPrototype(JSContext* cx, HandleObject obj, MutableHandleObjec // (new NYI).stack // to continue returning stacks that are useless, but at least don't throw. - RootedObject target(cx, CheckedUnwrap(obj)); - if (!target) { - JS_ReportErrorASCII(cx, "Permission denied to access object"); - return false; - } - - RootedObject proto(cx); - while (!IsErrorProtoKey(StandardProtoKeyOrNull(target))) { - if (!GetPrototype(cx, target, &proto)) - return false; - - if (!proto) { - // We walked the whole prototype chain and did not find an Error - // object. - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, - js_Error_str, "(get stack)", obj->getClass()->name); - return false; - } - - target = CheckedUnwrap(proto); + RootedObject curr(cx, obj); + RootedObject target(cx); + do { + target = CheckedUnwrap(curr); if (!target) { JS_ReportErrorASCII(cx, "Permission denied to access object"); return false; } - } + + if (IsErrorProtoKey(StandardProtoKeyOrNull(target))) { + result.set(target); + return true; + } - result.set(target); - return true; + if (!GetPrototype(cx, target, &curr)) { + return false; + } + } while (curr); + + // We walked the whole prototype chain and did not find an Error + // object. + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, + js_Error_str, "(get stack)", obj->getClass()->name); + return false; }