Bug 871177. Fix rooting hazard in IsNotDateOrRegexp. r=smaug

This commit is contained in:
Boris Zbarsky 2013-05-15 21:46:44 -04:00
Родитель a091ae2c0c
Коммит 42f794f96b
3 изменённых файлов: 50 добавлений и 40 удалений

Просмотреть файл

@ -248,41 +248,43 @@ NS_IMETHODIMP
nsScreen::MozLockOrientation(const JS::Value& aOrientation, JSContext* aCx,
bool* aReturn)
{
if (aOrientation.isObject() && IsArrayLike(aCx, &aOrientation.toObject())) {
if (aOrientation.isObject()) {
JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
uint32_t length;
// JS_GetArrayLength actually works on all objects
if (!JS_GetArrayLength(aCx, seq, &length)) {
return NS_ERROR_FAILURE;
}
Sequence<nsString> orientations;
if (!orientations.SetCapacity(length)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t i = 0; i < length; ++i) {
JS::Rooted<JS::Value> temp(aCx);
if (!JS_GetElement(aCx, seq, i, temp.address())) {
if (IsArrayLike(aCx, seq)) {
uint32_t length;
// JS_GetArrayLength actually works on all objects
if (!JS_GetArrayLength(aCx, seq, &length)) {
return NS_ERROR_FAILURE;
}
JS::RootedString jsString(aCx, JS_ValueToString(aCx, temp));
if (!jsString) {
return NS_ERROR_FAILURE;
Sequence<nsString> orientations;
if (!orientations.SetCapacity(length)) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsDependentJSString str;
if (!str.init(aCx, jsString)) {
return NS_ERROR_FAILURE;
for (uint32_t i = 0; i < length; ++i) {
JS::Rooted<JS::Value> temp(aCx);
if (!JS_GetElement(aCx, seq, i, temp.address())) {
return NS_ERROR_FAILURE;
}
JS::RootedString jsString(aCx, JS_ValueToString(aCx, temp));
if (!jsString) {
return NS_ERROR_FAILURE;
}
nsDependentJSString str;
if (!str.init(aCx, jsString)) {
return NS_ERROR_FAILURE;
}
*orientations.AppendElement() = str;
}
*orientations.AppendElement() = str;
ErrorResult rv;
*aReturn = MozLockOrientation(orientations, rv);
return rv.ErrorCode();
}
ErrorResult rv;
*aReturn = MozLockOrientation(orientations, rv);
return rv.ErrorCode();
}
JS::RootedString jsString(aCx, JS_ValueToString(aCx, aOrientation));

Просмотреть файл

@ -186,33 +186,35 @@ UnwrapObject(JSContext* cx, JSObject* obj, U& value)
}
inline bool
IsNotDateOrRegExp(JSContext* cx, JSObject* obj)
IsNotDateOrRegExp(JSContext* cx, JS::Handle<JSObject*> obj)
{
MOZ_ASSERT(obj);
return !JS_ObjectIsDate(cx, obj) && !JS_ObjectIsRegExp(cx, obj);
}
MOZ_ALWAYS_INLINE bool
IsArrayLike(JSContext* cx, JSObject* obj)
IsArrayLike(JSContext* cx, JS::Handle<JSObject*> obj)
{
return IsNotDateOrRegExp(cx, obj);
}
MOZ_ALWAYS_INLINE bool
IsConvertibleToDictionary(JSContext* cx, JSObject* obj)
IsObjectValueConvertibleToDictionary(JSContext* cx,
JS::Handle<JS::Value> objVal)
{
JS::Rooted<JSObject*> obj(cx, &objVal.toObject());
return IsNotDateOrRegExp(cx, obj);
}
MOZ_ALWAYS_INLINE bool
IsConvertibleToDictionary(JSContext* cx, JS::Value val)
IsConvertibleToDictionary(JSContext* cx, JS::Handle<JS::Value> val)
{
return val.isNullOrUndefined() ||
(val.isObject() && IsConvertibleToDictionary(cx, &val.toObject()));
(val.isObject() && IsObjectValueConvertibleToDictionary(cx, val));
}
MOZ_ALWAYS_INLINE bool
IsConvertibleToCallbackInterface(JSContext* cx, JSObject* obj)
IsConvertibleToCallbackInterface(JSContext* cx, JS::Handle<JSObject*> obj)
{
return IsNotDateOrRegExp(cx, obj);
}

Просмотреть файл

@ -2738,7 +2738,7 @@ for (uint32_t i = 0; i < length; ++i) {
memberType = arrayObjectMemberTypes[0]
name = memberType.name
arrayObject = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${valHandle}, ${valPtr}, tryNext)) || !tryNext;" % (unionArgumentObj, name))
arrayObject = CGIfWrapper(arrayObject, "IsArrayLike(cx, &argObj)")
arrayObject = CGIfWrapper(arrayObject, "IsArrayLike(cx, argObj)")
names.append(name)
else:
arrayObject = None
@ -2750,7 +2750,7 @@ for (uint32_t i = 0; i < length; ++i) {
name = memberType.name
dateObject = CGGeneric("%s.SetTo%s(cx, ${val}, ${valPtr});\n"
"done = true;" % (unionArgumentObj, name))
dateObject = CGIfWrapper(dateObject, "JS_ObjectIsDate(cx, &argObj)");
dateObject = CGIfWrapper(dateObject, "JS_ObjectIsDate(cx, argObj)");
names.append(name)
else:
dateObject = None
@ -2774,7 +2774,7 @@ for (uint32_t i = 0; i < length; ++i) {
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
if len(objectMemberTypes) > 0:
object = CGGeneric("%s.SetToObject(cx, &argObj);\n"
object = CGGeneric("%s.SetToObject(cx, argObj);\n"
"done = true;" % unionArgumentObj)
else:
object = None
@ -2804,8 +2804,8 @@ for (uint32_t i = 0; i < length; ++i) {
if any([arrayObject, dateObject, callbackObject, dictionaryObject,
object]):
templateBody.prepend(CGGeneric("JSObject& argObj = ${val}.toObject();"))
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${valHandle}.toObject());"))
templateBody = CGIfWrapper(templateBody, "${valHandle}.isObject()")
else:
templateBody = CGGeneric()
@ -2955,12 +2955,18 @@ for (uint32_t i = 0; i < length; ++i) {
templateBody = ""
if descriptor.interface.isCallback():
templateBody += str(CallbackObjectUnwrapper(
# NOTE: This is only used for EventListener at this point
callbackConversion = str(CallbackObjectUnwrapper(
descriptor,
"&${val}.toObject()",
"callbackObj",
"${declName}",
exceptionCode,
codeOnFailure=failureCode))
templateBody += (
"{ // Scope for callbackObj\n"
" JS::Rooted<JSObject*> callbackObj(cx, &${valHandle}.toObject());\n" +
CGIndenter(CGGeneric(callbackConversion)).define() +
"\n}")
elif not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
if failureCode is not None:
templateBody += str(CastableObjectUnwrapper(
@ -3307,7 +3313,7 @@ for (uint32_t i = 0; i < length; ++i) {
# a dictionary, and return failureCode if not.
template = CGIfWrapper(
CGGeneric(failureCode),
"!IsConvertibleToDictionary(cx, &${valHandle}.toObject())").define() + "\n\n"
"!IsObjectValueConvertibleToDictionary(cx, ${valHandle})").define() + "\n\n"
else:
template = ""