From cc606364e61f8a92ba1aca2156e165f2e384b265 Mon Sep 17 00:00:00 2001 From: Ashley Hauck Date: Wed, 31 Oct 2018 17:28:41 +0000 Subject: [PATCH] Bug 1487022 - Use MOZ_RELEASE_ASSERT for builtins that take int32 values. r=tcampbell The arguments to the intrinsics here are not guaranteed to be int32s, however, if a double enters the intrinsic, that's probably a bug in our builtin javascript. Values should be converted to int32 before being passed in, with `|0`. Differential Revision: https://phabricator.services.mozilla.com/D8446 --HG-- extra : moz-landing-system : lando --- js/src/builtin/TypedObject.cpp | 14 +++++----- js/src/builtin/TypedObject.js | 50 +++++++++++++++++----------------- js/src/vm/SelfHosting.cpp | 38 ++++++++++++++++++-------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 6030dc927f0c..23475bf39f1f 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -2551,7 +2551,7 @@ js::NewDerivedTypedObject(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 3); MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); MOZ_ASSERT(args[1].isObject() && args[1].toObject().is()); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); Rooted descr(cx, &args[0].toObject().as()); Rooted typedObj(cx, &args[1].toObject().as()); @@ -2572,7 +2572,7 @@ js::AttachTypedObject(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 3); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); OutlineTypedObject& handle = args[0].toObject().as(); TypedObject& target = args[1].toObject().as(); @@ -2590,7 +2590,7 @@ js::SetTypedObjectOffset(JSContext*, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); - MOZ_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[1].isInt32()); OutlineTypedObject& typedObj = args[0].toObject().as(); int32_t offset = args[1].toInt32(); @@ -2709,7 +2709,7 @@ js::StoreScalar##T::Func(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); \ MOZ_ASSERT(args.length() == 3); \ MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); \ - MOZ_ASSERT(args[1].isInt32()); \ + MOZ_RELEASE_ASSERT(args[1].isInt32()); \ MOZ_ASSERT(args[2].isNumber()); \ \ TypedObject& typedObj = args[0].toObject().as(); \ @@ -2733,7 +2733,7 @@ js::StoreReference##_name::Func(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); \ MOZ_ASSERT(args.length() == 4); \ MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); \ - MOZ_ASSERT(args[1].isInt32()); \ + MOZ_RELEASE_ASSERT(args[1].isInt32()); \ MOZ_ASSERT(args[2].isString() || args[2].isNull()); \ \ TypedObject& typedObj = args[0].toObject().as(); \ @@ -2761,7 +2761,7 @@ js::LoadScalar##T::Func(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); \ MOZ_ASSERT(args.length() == 2); \ MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); \ - MOZ_ASSERT(args[1].isInt32()); \ + MOZ_RELEASE_ASSERT(args[1].isInt32()); \ \ TypedObject& typedObj = args[0].toObject().as(); \ int32_t offset = args[1].toInt32(); \ @@ -2782,7 +2782,7 @@ js::LoadReference##_name::Func(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); \ MOZ_ASSERT(args.length() == 2); \ MOZ_ASSERT(args[0].isObject() && args[0].toObject().is()); \ - MOZ_ASSERT(args[1].isInt32()); \ + MOZ_RELEASE_ASSERT(args[1].isInt32()); \ \ TypedObject& typedObj = args[0].toObject().as(); \ int32_t offset = args[1].toInt32(); \ diff --git a/js/src/builtin/TypedObject.js b/js/src/builtin/TypedObject.js index 5aaa6b427d2b..c2911ccea727 100644 --- a/js/src/builtin/TypedObject.js +++ b/js/src/builtin/TypedObject.js @@ -65,7 +65,7 @@ function TypedObjectGet(descr, typedObj, offset) { function TypedObjectGetDerived(descr, typedObj, offset) { assert(!TypeDescrIsSimpleType(descr), "getDerived() used with simple type"); - return NewDerivedTypedObject(descr, typedObj, offset); + return NewDerivedTypedObject(descr, typedObj, offset | 0); } function TypedObjectGetDerivedIf(descr, typedObj, offset, cond) { @@ -76,7 +76,7 @@ function TypedObjectGetOpaque(descr, typedObj, offset) { assert(!TypeDescrIsSimpleType(descr), "getDerived() used with simple type"); var opaqueTypedObj = NewOpaqueTypedObject(descr); - AttachTypedObject(opaqueTypedObj, typedObj, offset); + AttachTypedObject(opaqueTypedObj, typedObj, offset | 0); return opaqueTypedObj; } @@ -88,29 +88,29 @@ function TypedObjectGetScalar(descr, typedObj, offset) { var type = DESCR_TYPE(descr); switch (type) { case JS_SCALARTYPEREPR_INT8: - return Load_int8(typedObj, offset); + return Load_int8(typedObj, offset | 0); case JS_SCALARTYPEREPR_UINT8: case JS_SCALARTYPEREPR_UINT8_CLAMPED: - return Load_uint8(typedObj, offset); + return Load_uint8(typedObj, offset | 0); case JS_SCALARTYPEREPR_INT16: - return Load_int16(typedObj, offset); + return Load_int16(typedObj, offset | 0); case JS_SCALARTYPEREPR_UINT16: - return Load_uint16(typedObj, offset); + return Load_uint16(typedObj, offset | 0); case JS_SCALARTYPEREPR_INT32: - return Load_int32(typedObj, offset); + return Load_int32(typedObj, offset | 0); case JS_SCALARTYPEREPR_UINT32: - return Load_uint32(typedObj, offset); + return Load_uint32(typedObj, offset | 0); case JS_SCALARTYPEREPR_FLOAT32: - return Load_float32(typedObj, offset); + return Load_float32(typedObj, offset | 0); case JS_SCALARTYPEREPR_FLOAT64: - return Load_float64(typedObj, offset); + return Load_float64(typedObj, offset | 0); } assert(false, "Unhandled scalar type: " + type); @@ -121,13 +121,13 @@ function TypedObjectGetReference(descr, typedObj, offset) { var type = DESCR_TYPE(descr); switch (type) { case JS_REFERENCETYPEREPR_ANY: - return Load_Any(typedObj, offset); + return Load_Any(typedObj, offset | 0); case JS_REFERENCETYPEREPR_OBJECT: - return Load_Object(typedObj, offset); + return Load_Object(typedObj, offset | 0); case JS_REFERENCETYPEREPR_STRING: - return Load_string(typedObj, offset); + return Load_string(typedObj, offset | 0); } assert(false, "Unhandled scalar type: " + type); @@ -212,38 +212,38 @@ function TypedObjectSetScalar(descr, typedObj, offset, fromValue) { var type = DESCR_TYPE(descr); switch (type) { case JS_SCALARTYPEREPR_INT8: - return Store_int8(typedObj, offset, + return Store_int8(typedObj, offset | 0, TO_INT32(fromValue) & 0xFF); case JS_SCALARTYPEREPR_UINT8: - return Store_uint8(typedObj, offset, + return Store_uint8(typedObj, offset | 0, TO_UINT32(fromValue) & 0xFF); case JS_SCALARTYPEREPR_UINT8_CLAMPED: var v = ClampToUint8(+fromValue); - return Store_int8(typedObj, offset, v); + return Store_int8(typedObj, offset | 0, v); case JS_SCALARTYPEREPR_INT16: - return Store_int16(typedObj, offset, + return Store_int16(typedObj, offset | 0, TO_INT32(fromValue) & 0xFFFF); case JS_SCALARTYPEREPR_UINT16: - return Store_uint16(typedObj, offset, + return Store_uint16(typedObj, offset | 0, TO_UINT32(fromValue) & 0xFFFF); case JS_SCALARTYPEREPR_INT32: - return Store_int32(typedObj, offset, + return Store_int32(typedObj, offset | 0, TO_INT32(fromValue)); case JS_SCALARTYPEREPR_UINT32: - return Store_uint32(typedObj, offset, + return Store_uint32(typedObj, offset | 0, TO_UINT32(fromValue)); case JS_SCALARTYPEREPR_FLOAT32: - return Store_float32(typedObj, offset, +fromValue); + return Store_float32(typedObj, offset | 0, +fromValue); case JS_SCALARTYPEREPR_FLOAT64: - return Store_float64(typedObj, offset, +fromValue); + return Store_float64(typedObj, offset | 0, +fromValue); } assert(false, "Unhandled scalar type: " + type); @@ -254,14 +254,14 @@ function TypedObjectSetReference(descr, typedObj, offset, name, fromValue) { var type = DESCR_TYPE(descr); switch (type) { case JS_REFERENCETYPEREPR_ANY: - return Store_Any(typedObj, offset, name, fromValue); + return Store_Any(typedObj, offset | 0, name, fromValue); case JS_REFERENCETYPEREPR_OBJECT: var value = (fromValue === null ? fromValue : ToObject(fromValue)); - return Store_Object(typedObj, offset, name, value); + return Store_Object(typedObj, offset | 0, name, value); case JS_REFERENCETYPEREPR_STRING: - return Store_string(typedObj, offset, name, ToString(fromValue)); + return Store_string(typedObj, offset | 0, name, ToString(fromValue)); } assert(false, "Unhandled scalar type: " + type); diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 1f98dc49e6c9..e2dbb5ed5db3 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -314,8 +314,8 @@ intrinsic_SubstringKernel(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args[0].isString()); - MOZ_ASSERT(args[1].isInt32()); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); RootedString str(cx, args[0].toString()); int32_t begin = args[1].toInt32(); @@ -333,6 +333,7 @@ intrinsic_SubstringKernel(JSContext* cx, unsigned argc, Value* vp) static void ThrowErrorWithType(JSContext* cx, JSExnType type, const CallArgs& args) { + MOZ_RELEASE_ASSERT(args[0].isInt32()); uint32_t errorNumber = args[0].toInt32(); #ifdef DEBUG @@ -407,7 +408,7 @@ intrinsic_GetErrorMessage(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 1); - MOZ_ASSERT(args[0].isInt32()); + MOZ_RELEASE_ASSERT(args[0].isInt32()); const JSErrorFormatString* errorString = GetErrorMessage(nullptr, args[0].toInt32()); MOZ_ASSERT(errorString); @@ -428,8 +429,8 @@ intrinsic_CreateModuleSyntaxError(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 4); MOZ_ASSERT(args[0].isObject()); - MOZ_ASSERT(args[1].isInt32()); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); MOZ_ASSERT(args[3].isString()); RootedModuleObject module(cx, &args[0].toObject().as()); @@ -551,7 +552,7 @@ intrinsic_FinishBoundFunctionInit(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 3); MOZ_ASSERT(IsCallable(args[1])); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); RootedFunction bound(cx, &args[0].toObject().as()); RootedObject targetObj(cx, &args[1].toObject()); @@ -574,6 +575,7 @@ intrinsic_DecompileArg(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); + MOZ_RELEASE_ASSERT(args[0].isInt32()); HandleValue value = args[1]; JSString* str = DecompileArgument(cx, args[0].toInt32(), value); @@ -593,6 +595,7 @@ intrinsic_DefineDataProperty(JSContext* cx, unsigned argc, Value* vp) // JSOP_INITELEM in the bytecode emitter so we shouldn't get here. MOZ_ASSERT(args.length() == 4); MOZ_ASSERT(args[0].isObject()); + MOZ_RELEASE_ASSERT(args[3].isInt32()); RootedObject obj(cx, &args[0].toObject()); RootedId id(cx); @@ -641,7 +644,7 @@ intrinsic_DefineProperty(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 6); MOZ_ASSERT(args[0].isObject()); MOZ_ASSERT(args[1].isString() || args[1].isNumber() || args[1].isSymbol()); - MOZ_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); MOZ_ASSERT(args[5].isBoolean()); RootedObject obj(cx, &args[0].toObject()); @@ -742,7 +745,7 @@ intrinsic_UnsafeSetReservedSlot(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 3); MOZ_ASSERT(args[0].isObject()); - MOZ_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[1].isInt32()); args[0].toObject().as().setReservedSlot(args[1].toPrivateUint32(), args[2]); args.rval().setUndefined(); @@ -755,7 +758,7 @@ intrinsic_UnsafeGetReservedSlot(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); MOZ_ASSERT(args[0].isObject()); - MOZ_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[1].isInt32()); args.rval().set(args[0].toObject().as().getReservedSlot(args[1].toPrivateUint32())); return true; @@ -1012,6 +1015,9 @@ intrinsic_ArrayBufferCopyData(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 6); + MOZ_RELEASE_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[3].isInt32()); + MOZ_RELEASE_ASSERT(args[4].isInt32()); bool isWrapped = args[5].toBoolean(); Rooted toBuffer(cx); @@ -1191,6 +1197,9 @@ intrinsic_MoveTypedArrayElements(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 4); + MOZ_RELEASE_ASSERT(args[1].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[3].isInt32()); Rooted tarray(cx, &args[0].toObject().as()); uint32_t to = uint32_t(args[1].toInt32()); @@ -1286,6 +1295,7 @@ intrinsic_SetFromTypedArrayApproach(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 4); + MOZ_RELEASE_ASSERT(args[3].isInt32()); Rooted target(cx, &args[0].toObject().as()); MOZ_ASSERT(!target->hasDetachedBuffer(), @@ -1532,6 +1542,7 @@ intrinsic_SetDisjointTypedElements(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 3); + MOZ_RELEASE_ASSERT(args[1].isInt32()); Rooted target(cx, &args[0].toObject().as()); MOZ_ASSERT(!target->hasDetachedBuffer(), @@ -1559,6 +1570,7 @@ intrinsic_SetOverlappingTypedElements(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 3); + MOZ_RELEASE_ASSERT(args[1].isInt32()); Rooted target(cx, &args[0].toObject().as()); cx->check(target); @@ -1642,8 +1654,8 @@ intrinsic_TypedArrayBitwiseSlice(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 4); MOZ_ASSERT(args[0].isObject()); MOZ_ASSERT(args[1].isObject()); - MOZ_ASSERT(args[2].isInt32()); - MOZ_ASSERT(args[3].isInt32()); + MOZ_RELEASE_ASSERT(args[2].isInt32()); + MOZ_RELEASE_ASSERT(args[3].isInt32()); Rooted source(cx, &args[0].toObject().as()); MOZ_ASSERT(!source->hasDetachedBuffer()); @@ -2013,12 +2025,14 @@ intrinsic_AddContentTelemetry(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); + MOZ_RELEASE_ASSERT(args[0].isInt32()); int id = args[0].toInt32(); MOZ_ASSERT(id < JS_TELEMETRY_END); MOZ_ASSERT(id >= 0); if (!cx->realm()->isProbablySystemCode()) { + MOZ_RELEASE_ASSERT(args[1].isInt32()); cx->runtime()->addTelemetry(id, args[1].toInt32()); } @@ -2031,7 +2045,7 @@ intrinsic_WarnDeprecatedStringMethod(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); - MOZ_ASSERT(args[0].isInt32()); + MOZ_RELEASE_ASSERT(args[0].isInt32()); MOZ_ASSERT(args[1].isString()); uint32_t id = uint32_t(args[0].toInt32());