Bug 1140317: Make sure chars created by DecompileValueGenerator won't ever leak; r=Waldo

--HG--
extra : rebase_source : 826d3b85b3b0b094f9d4d570a13915a99e985598
This commit is contained in:
Benjamin Bouvier 2015-03-10 19:34:00 +01:00
Родитель 0e1b8d416c
Коммит 98c2be829a
11 изменённых файлов: 57 добавлений и 50 удалений

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

@ -661,12 +661,12 @@ js::obj_create(JSContext *cx, unsigned argc, Value *vp)
if (!args[0].isObjectOrNull()) {
RootedValue v(cx, args[0]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
bytes, "not an object or null");
js_free(bytes);
bytes.get(), "not an object or null");
return false;
}

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

@ -123,10 +123,11 @@ WeakSetObject::construct(JSContext *cx, unsigned argc, Value *vp)
if (isOriginalAdder) {
if (keyVal.isPrimitive()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return false;
}

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

@ -52,6 +52,7 @@ using mozilla::CeilingLog2;
using mozilla::CheckedInt;
using mozilla::DebugOnly;
using mozilla::IsNaN;
using mozilla::UniquePtr;
using JS::AutoCheckCannotGC;
using JS::ToUint32;
@ -3546,19 +3547,18 @@ js::ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
for (unsigned i = 0; i < args.length(); i++) {
RootedValue arg(cx, args[i]);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, NullPtr());
if (!bytes)
return false;
if (arg.isPrimitive() ||
!(obj = arg.toObjectOrNull())->is<ArrayObject>()) {
fprintf(stderr, "%s: not array\n", bytes);
js_free(bytes);
fprintf(stderr, "%s: not array\n", bytes.get());
continue;
}
fprintf(stderr, "%s: (len %u", bytes, obj->as<ArrayObject>().length());
fprintf(stderr, "%s: (len %u", bytes.get(), obj->as<ArrayObject>().length());
fprintf(stderr, ", capacity %u", obj->as<ArrayObject>().getDenseCapacity());
fputs(")\n", stderr);
js_free(bytes);
}
args.rval().setUndefined();

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

@ -803,33 +803,32 @@ bool
js::ReportIsNullOrUndefined(JSContext *cx, int spindex, HandleValue v,
HandleString fallback)
{
char *bytes;
bool ok;
bytes = DecompileValueGenerator(cx, spindex, v, fallback);
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, spindex, v, fallback);
if (!bytes)
return false;
if (strcmp(bytes, js_undefined_str) == 0 ||
strcmp(bytes, js_null_str) == 0) {
if (strcmp(bytes.get(), js_undefined_str) == 0 ||
strcmp(bytes.get(), js_null_str) == 0) {
ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
GetErrorMessage, nullptr,
JSMSG_NO_PROPERTIES, bytes,
JSMSG_NO_PROPERTIES, bytes.get(),
nullptr, nullptr);
} else if (v.isUndefined()) {
ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
GetErrorMessage, nullptr,
JSMSG_UNEXPECTED_TYPE, bytes,
JSMSG_UNEXPECTED_TYPE, bytes.get(),
js_undefined_str, nullptr);
} else {
MOZ_ASSERT(v.isNull());
ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
GetErrorMessage, nullptr,
JSMSG_UNEXPECTED_TYPE, bytes,
JSMSG_UNEXPECTED_TYPE, bytes.get(),
js_null_str, nullptr);
}
js_free(bytes);
return ok;
}
@ -837,22 +836,19 @@ void
js::ReportMissingArg(JSContext *cx, HandleValue v, unsigned arg)
{
char argbuf[11];
char *bytes;
UniquePtr<char[], JS::FreePolicy> bytes;
RootedAtom atom(cx);
JS_snprintf(argbuf, sizeof argbuf, "%u", arg);
bytes = nullptr;
if (IsFunctionObject(v)) {
atom = v.toObject().as<JSFunction>().atom();
bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
v, atom);
bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, atom);
if (!bytes)
return;
}
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
JSMSG_MISSING_FUN_ARG, argbuf,
bytes ? bytes : "");
js_free(bytes);
bytes ? bytes.get() : "");
}
bool
@ -860,7 +856,7 @@ js::ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNum
int spindex, HandleValue v, HandleString fallback,
const char *arg1, const char *arg2)
{
char *bytes;
UniquePtr<char[], JS::FreePolicy> bytes;
bool ok;
MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1);
@ -870,8 +866,7 @@ js::ReportValueErrorFlags(JSContext *cx, unsigned flags, const unsigned errorNum
return false;
ok = JS_ReportErrorFlagsAndNumber(cx, flags, GetErrorMessage,
nullptr, errorNumber, bytes, arg1, arg2);
js_free(bytes);
nullptr, errorNumber, bytes.get(), arg1, arg2);
return ok;
}

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

@ -94,10 +94,11 @@ js::NonNullObject(JSContext *cx, const Value &v)
{
if (v.isPrimitive()) {
RootedValue value(cx, v);
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, value, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, value, NullPtr());
if (!bytes)
return nullptr;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return nullptr;
}
return &v.toObject();
@ -249,12 +250,12 @@ js::GetFirstArgumentAsObject(JSContext *cx, const CallArgs &args, const char *me
HandleValue v = args[0];
if (!v.isObject()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
bytes, "not an object");
js_free(bytes);
bytes.get(), "not an object");
return false;
}
@ -285,10 +286,11 @@ PropDesc::initialize(JSContext *cx, const Value &origval, bool checkAccessors)
/* 8.10.5 step 1 */
if (v.isPrimitive()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return false;
}
RootedObject desc(cx, &v.toObject());

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

@ -1819,7 +1819,9 @@ DecompileExpressionFromStack(JSContext *cx, int spindex, int skipStackHits, Hand
return ed.getOutput(res);
}
char *
typedef mozilla::UniquePtr<char[], JS::FreePolicy> UniquePtrChars;
UniquePtrChars
js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
HandleString fallbackArg, int skipStackHits)
{
@ -1830,19 +1832,19 @@ js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
return nullptr;
if (result) {
if (strcmp(result, "(intermediate value)"))
return result;
return UniquePtrChars(result);
js_free(result);
}
}
if (!fallback) {
if (v.isUndefined())
return JS_strdup(cx, js_undefined_str); // Prevent users from seeing "(void 0)"
return UniquePtrChars(JS_strdup(cx, js_undefined_str)); // Prevent users from seeing "(void 0)"
fallback = ValueToSource(cx, v);
if (!fallback)
return nullptr;
return UniquePtrChars(nullptr);
}
return JS_EncodeString(cx, fallback);
return UniquePtrChars(JS_EncodeString(cx, fallback));
}
static bool

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

@ -11,6 +11,8 @@
* JS bytecode definitions.
*/
#include "mozilla/UniquePtr.h"
#include "jsbytecode.h"
#include "jstypes.h"
#include "NamespaceImports.h"
@ -560,7 +562,7 @@ GetVariableBytecodeLength(jsbytecode *pc);
*
* The caller must call JS_free on the result after a successful call.
*/
char *
mozilla::UniquePtr<char[], JS::FreePolicy>
DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
HandleString fallback, int skipStackHits = 0);

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

@ -388,10 +388,11 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
MOZ_ASSERT(IsWeakMap(args.thisv()));
if (!args.get(0).isObject()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, args.get(0), NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, args.get(0), NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return false;
}
@ -572,10 +573,11 @@ WeakMap_construct(JSContext *cx, unsigned argc, Value *vp)
// Steps 12k-l.
if (isOriginalAdder) {
if (keyVal.isPrimitive()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return false;
}

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

@ -210,10 +210,11 @@ static PerfMeasurement*
GetPM(JSContext* cx, JS::HandleValue value, const char* fname)
{
if (!value.isObject()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, value, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes =
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, value, NullPtr());
if (!bytes)
return nullptr;
JS_ReportErrorNumber(cx, GetErrorMessage, 0, JSMSG_NOT_NONNULL_OBJECT, bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, 0, JSMSG_NOT_NONNULL_OBJECT, bytes.get());
return nullptr;
}
RootedObject obj(cx, &value.toObject());

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

@ -17,6 +17,8 @@
using namespace js;
using JS::ForOfIterator;
using mozilla::UniquePtr;
bool
ForOfIterator::init(HandleValue iterable, NonIterableBehavior nonIterableBehavior)
{
@ -69,11 +71,11 @@ ForOfIterator::init(HandleValue iterable, NonIterableBehavior nonIterableBehavio
// throw an inscrutable error message about |method| rather than this nice
// one about |obj|.
if (!callee.isObject() || !callee.toObject().isCallable()) {
char *bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, iterable, NullPtr());
UniquePtr<char[], JS::FreePolicy> bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
iterable, NullPtr());
if (!bytes)
return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, bytes);
js_free(bytes);
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, bytes.get());
return false;
}

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

@ -173,7 +173,7 @@ js::intrinsic_ThrowError(JSContext *cx, unsigned argc, Value *vp)
} else if (val.isString()) {
errorArgs[i - 1].encodeLatin1(cx, val.toString());
} else {
errorArgs[i - 1].initBytes(DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr()));
errorArgs[i - 1].initBytes(DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, NullPtr()).release());
}
if (!errorArgs[i - 1])
return false;