mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1290422 - Part 1: Remove JSErrorReport.messageArgs. r=jwalden
This commit is contained in:
parent
f9e30f8e42
commit
ad44dc986e
@ -593,13 +593,6 @@ CompileError::~CompileError()
|
||||
js_free(message);
|
||||
message = nullptr;
|
||||
|
||||
if (report.messageArgs) {
|
||||
unsigned i = 0;
|
||||
while (report.messageArgs[i])
|
||||
js_free((void*)report.messageArgs[i++]);
|
||||
js_free(report.messageArgs);
|
||||
}
|
||||
|
||||
PodZero(&report);
|
||||
}
|
||||
|
||||
@ -648,7 +641,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
}
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber, &err.message,
|
||||
ArgumentsAreASCII, &err.report, args))
|
||||
nullptr, ArgumentsAreASCII, &err.report, args))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsprf.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
@ -31,6 +33,13 @@ class AutoInflatedString {
|
||||
abort();
|
||||
}
|
||||
|
||||
void operator=(const char* str) {
|
||||
length_ = strlen(str);
|
||||
chars_ = InflateString(cx, str, &length_);
|
||||
if (!chars_)
|
||||
abort();
|
||||
}
|
||||
|
||||
const char16_t* chars() const { return chars_; }
|
||||
size_t length() const { return length_; }
|
||||
};
|
||||
@ -170,75 +179,75 @@ END_TEST(testParseJSON_success)
|
||||
|
||||
BEGIN_TEST(testParseJSON_error)
|
||||
{
|
||||
CHECK(Error(cx, "" , "1", "1"));
|
||||
CHECK(Error(cx, "\n" , "2", "1"));
|
||||
CHECK(Error(cx, "\r" , "2", "1"));
|
||||
CHECK(Error(cx, "\r\n" , "2", "1"));
|
||||
CHECK(Error(cx, "" , 1, 1));
|
||||
CHECK(Error(cx, "\n" , 2, 1));
|
||||
CHECK(Error(cx, "\r" , 2, 1));
|
||||
CHECK(Error(cx, "\r\n" , 2, 1));
|
||||
|
||||
CHECK(Error(cx, "[" , "1", "2"));
|
||||
CHECK(Error(cx, "[,]" , "1", "2"));
|
||||
CHECK(Error(cx, "[1,]" , "1", "4"));
|
||||
CHECK(Error(cx, "{a:2}" , "1", "2"));
|
||||
CHECK(Error(cx, "{\"a\":2,}" , "1", "8"));
|
||||
CHECK(Error(cx, "]" , "1", "1"));
|
||||
CHECK(Error(cx, "\"" , "1", "2"));
|
||||
CHECK(Error(cx, "{]" , "1", "2"));
|
||||
CHECK(Error(cx, "[}" , "1", "2"));
|
||||
CHECK(Error(cx, "'wrongly-quoted string'" , "1", "1"));
|
||||
CHECK(Error(cx, "[" , 1, 2));
|
||||
CHECK(Error(cx, "[,]" , 1, 2));
|
||||
CHECK(Error(cx, "[1,]" , 1, 4));
|
||||
CHECK(Error(cx, "{a:2}" , 1, 2));
|
||||
CHECK(Error(cx, "{\"a\":2,}" , 1, 8));
|
||||
CHECK(Error(cx, "]" , 1, 1));
|
||||
CHECK(Error(cx, "\"" , 1, 2));
|
||||
CHECK(Error(cx, "{]" , 1, 2));
|
||||
CHECK(Error(cx, "[}" , 1, 2));
|
||||
CHECK(Error(cx, "'wrongly-quoted string'" , 1, 1));
|
||||
|
||||
CHECK(Error(cx, "{\"a\":2 \n b:3}" , "2", "2"));
|
||||
CHECK(Error(cx, "\n[" , "2", "2"));
|
||||
CHECK(Error(cx, "\n[,]" , "2", "2"));
|
||||
CHECK(Error(cx, "\n[1,]" , "2", "4"));
|
||||
CHECK(Error(cx, "\n{a:2}" , "2", "2"));
|
||||
CHECK(Error(cx, "\n{\"a\":2,}" , "2", "8"));
|
||||
CHECK(Error(cx, "\n]" , "2", "1"));
|
||||
CHECK(Error(cx, "\"bad string\n\"" , "1", "12"));
|
||||
CHECK(Error(cx, "\r'wrongly-quoted string'" , "2", "1"));
|
||||
CHECK(Error(cx, "\n\"" , "2", "2"));
|
||||
CHECK(Error(cx, "\n{]" , "2", "2"));
|
||||
CHECK(Error(cx, "\n[}" , "2", "2"));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\n\"b\":,5,6}" , "2", "5"));
|
||||
CHECK(Error(cx, "{\"a\":2 \n b:3}" , 2, 2));
|
||||
CHECK(Error(cx, "\n[" , 2, 2));
|
||||
CHECK(Error(cx, "\n[,]" , 2, 2));
|
||||
CHECK(Error(cx, "\n[1,]" , 2, 4));
|
||||
CHECK(Error(cx, "\n{a:2}" , 2, 2));
|
||||
CHECK(Error(cx, "\n{\"a\":2,}" , 2, 8));
|
||||
CHECK(Error(cx, "\n]" , 2, 1));
|
||||
CHECK(Error(cx, "\"bad string\n\"" , 1, 12));
|
||||
CHECK(Error(cx, "\r'wrongly-quoted string'" , 2, 1));
|
||||
CHECK(Error(cx, "\n\"" , 2, 2));
|
||||
CHECK(Error(cx, "\n{]" , 2, 2));
|
||||
CHECK(Error(cx, "\n[}" , 2, 2));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\n\"b\":,5,6}" , 2, 5));
|
||||
|
||||
CHECK(Error(cx, "{\"a\":2 \r b:3}" , "2", "2"));
|
||||
CHECK(Error(cx, "\r[" , "2", "2"));
|
||||
CHECK(Error(cx, "\r[,]" , "2", "2"));
|
||||
CHECK(Error(cx, "\r[1,]" , "2", "4"));
|
||||
CHECK(Error(cx, "\r{a:2}" , "2", "2"));
|
||||
CHECK(Error(cx, "\r{\"a\":2,}" , "2", "8"));
|
||||
CHECK(Error(cx, "\r]" , "2", "1"));
|
||||
CHECK(Error(cx, "\"bad string\r\"" , "1", "12"));
|
||||
CHECK(Error(cx, "\r'wrongly-quoted string'" , "2", "1"));
|
||||
CHECK(Error(cx, "\r\"" , "2", "2"));
|
||||
CHECK(Error(cx, "\r{]" , "2", "2"));
|
||||
CHECK(Error(cx, "\r[}" , "2", "2"));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\r\"b\":,5,6}" , "2", "5"));
|
||||
CHECK(Error(cx, "{\"a\":2 \r b:3}" , 2, 2));
|
||||
CHECK(Error(cx, "\r[" , 2, 2));
|
||||
CHECK(Error(cx, "\r[,]" , 2, 2));
|
||||
CHECK(Error(cx, "\r[1,]" , 2, 4));
|
||||
CHECK(Error(cx, "\r{a:2}" , 2, 2));
|
||||
CHECK(Error(cx, "\r{\"a\":2,}" , 2, 8));
|
||||
CHECK(Error(cx, "\r]" , 2, 1));
|
||||
CHECK(Error(cx, "\"bad string\r\"" , 1, 12));
|
||||
CHECK(Error(cx, "\r'wrongly-quoted string'" , 2, 1));
|
||||
CHECK(Error(cx, "\r\"" , 2, 2));
|
||||
CHECK(Error(cx, "\r{]" , 2, 2));
|
||||
CHECK(Error(cx, "\r[}" , 2, 2));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\r\"b\":,5,6}" , 2, 5));
|
||||
|
||||
CHECK(Error(cx, "{\"a\":2 \r\n b:3}" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n[" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n[,]" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n[1,]" , "2", "4"));
|
||||
CHECK(Error(cx, "\r\n{a:2}" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n{\"a\":2,}" , "2", "8"));
|
||||
CHECK(Error(cx, "\r\n]" , "2", "1"));
|
||||
CHECK(Error(cx, "\"bad string\r\n\"" , "1", "12"));
|
||||
CHECK(Error(cx, "\r\n'wrongly-quoted string'" , "2", "1"));
|
||||
CHECK(Error(cx, "\r\n\"" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n{]" , "2", "2"));
|
||||
CHECK(Error(cx, "\r\n[}" , "2", "2"));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\r\n\"b\":,5,6}" , "2", "5"));
|
||||
CHECK(Error(cx, "{\"a\":2 \r\n b:3}" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n[" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n[,]" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n[1,]" , 2, 4));
|
||||
CHECK(Error(cx, "\r\n{a:2}" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n{\"a\":2,}" , 2, 8));
|
||||
CHECK(Error(cx, "\r\n]" , 2, 1));
|
||||
CHECK(Error(cx, "\"bad string\r\n\"" , 1, 12));
|
||||
CHECK(Error(cx, "\r\n'wrongly-quoted string'" , 2, 1));
|
||||
CHECK(Error(cx, "\r\n\"" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n{]" , 2, 2));
|
||||
CHECK(Error(cx, "\r\n[}" , 2, 2));
|
||||
CHECK(Error(cx, "{\"a\":[2,3],\r\n\"b\":,5,6}" , 2, 5));
|
||||
|
||||
CHECK(Error(cx, "\n\"bad string\n\"" , "2", "12"));
|
||||
CHECK(Error(cx, "\r\"bad string\r\"" , "2", "12"));
|
||||
CHECK(Error(cx, "\r\n\"bad string\r\n\"" , "2", "12"));
|
||||
CHECK(Error(cx, "\n\"bad string\n\"" , 2, 12));
|
||||
CHECK(Error(cx, "\r\"bad string\r\"" , 2, 12));
|
||||
CHECK(Error(cx, "\r\n\"bad string\r\n\"" , 2, 12));
|
||||
|
||||
CHECK(Error(cx, "{\n\"a\":[2,3],\r\"b\":,5,6}" , "3", "5"));
|
||||
CHECK(Error(cx, "{\r\"a\":[2,3],\n\"b\":,5,6}" , "3", "5"));
|
||||
CHECK(Error(cx, "[\"\\t\\q" , "1", "6"));
|
||||
CHECK(Error(cx, "[\"\\t\x00" , "1", "5"));
|
||||
CHECK(Error(cx, "[\"\\t\x01" , "1", "5"));
|
||||
CHECK(Error(cx, "[\"\\t\\\x00" , "1", "6"));
|
||||
CHECK(Error(cx, "[\"\\t\\\x01" , "1", "6"));
|
||||
CHECK(Error(cx, "{\n\"a\":[2,3],\r\"b\":,5,6}" , 3, 5));
|
||||
CHECK(Error(cx, "{\r\"a\":[2,3],\n\"b\":,5,6}" , 3, 5));
|
||||
CHECK(Error(cx, "[\"\\t\\q" , 1, 6));
|
||||
CHECK(Error(cx, "[\"\\t\x00" , 1, 5));
|
||||
CHECK(Error(cx, "[\"\\t\x01" , 1, 5));
|
||||
CHECK(Error(cx, "[\"\\t\\\x00" , 1, 6));
|
||||
CHECK(Error(cx, "[\"\\t\\\x01" , 1, 6));
|
||||
|
||||
// Unicode escape errors are messy. The first bad character could be
|
||||
// non-hexadecimal, or it could be absent entirely. Include tests where
|
||||
@ -253,36 +262,36 @@ BEGIN_TEST(testParseJSON_error)
|
||||
// as invalid by the same code path [ignoring which precise subexpression
|
||||
// triggers failure of a single condition], but the computation of the
|
||||
// first invalid character follows a different code path for each.)
|
||||
CHECK(Error(cx, "[\"\\t\\u" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\uZ" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZ" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZ" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZZ" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZZZ" , "1", "7"));
|
||||
CHECK(Error(cx, "[\"\\t\\u" , 1, 7));
|
||||
CHECK(Error(cx, "[\"\\t\\uZ" , 1, 7));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZ" , 1, 7));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZ" , 1, 7));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZZ" , 1, 7));
|
||||
CHECK(Error(cx, "[\"\\t\\uZZZZZ" , 1, 7));
|
||||
|
||||
CHECK(Error(cx, "[\"\\t\\u0" , "1", "8"));
|
||||
CHECK(Error(cx, "[\"\\t\\u0Z" , "1", "8"));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZ" , "1", "8"));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZZ" , "1", "8"));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZZZ" , "1", "8"));
|
||||
CHECK(Error(cx, "[\"\\t\\u0" , 1, 8));
|
||||
CHECK(Error(cx, "[\"\\t\\u0Z" , 1, 8));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZ" , 1, 8));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZZ" , 1, 8));
|
||||
CHECK(Error(cx, "[\"\\t\\u0ZZZZ" , 1, 8));
|
||||
|
||||
CHECK(Error(cx, "[\"\\t\\u00" , "1", "9"));
|
||||
CHECK(Error(cx, "[\"\\t\\u00Z" , "1", "9"));
|
||||
CHECK(Error(cx, "[\"\\t\\u00ZZ" , "1", "9"));
|
||||
CHECK(Error(cx, "[\"\\t\\u00ZZZ" , "1", "9"));
|
||||
CHECK(Error(cx, "[\"\\t\\u00" , 1, 9));
|
||||
CHECK(Error(cx, "[\"\\t\\u00Z" , 1, 9));
|
||||
CHECK(Error(cx, "[\"\\t\\u00ZZ" , 1, 9));
|
||||
CHECK(Error(cx, "[\"\\t\\u00ZZZ" , 1, 9));
|
||||
|
||||
CHECK(Error(cx, "[\"\\t\\u000" , "1", "10"));
|
||||
CHECK(Error(cx, "[\"\\t\\u000Z" , "1", "10"));
|
||||
CHECK(Error(cx, "[\"\\t\\u000ZZ" , "1", "10"));
|
||||
CHECK(Error(cx, "[\"\\t\\u000" , 1, 10));
|
||||
CHECK(Error(cx, "[\"\\t\\u000Z" , 1, 10));
|
||||
CHECK(Error(cx, "[\"\\t\\u000ZZ" , 1, 10));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t N, size_t M, size_t L> inline bool
|
||||
Error(JSContext* cx, const char (&input)[N], const char (&expectedLine)[M],
|
||||
const char (&expectedColumn)[L])
|
||||
template<size_t N> inline bool
|
||||
Error(JSContext* cx, const char (&input)[N], uint32_t expectedLine,
|
||||
uint32_t expectedColumn)
|
||||
{
|
||||
AutoInflatedString str(cx), line(cx), column(cx);
|
||||
AutoInflatedString str(cx);
|
||||
RootedValue dummy(cx);
|
||||
str = input;
|
||||
|
||||
@ -297,10 +306,9 @@ Error(JSContext* cx, const char (&input)[N], const char (&expectedLine)[M],
|
||||
CHECK(report.init(cx, exn, js::ErrorReport::WithSideEffects));
|
||||
CHECK(report.report()->errorNumber == JSMSG_JSON_BAD_PARSE);
|
||||
|
||||
column = expectedColumn;
|
||||
CHECK(js_strcmp(column.chars(), report.report()->messageArgs[2]) == 0);
|
||||
line = expectedLine;
|
||||
CHECK(js_strcmp(line.chars(), report.report()->messageArgs[1]) == 0);
|
||||
const char* lineAndColumnASCII = JS_smprintf("line %d column %d", expectedLine, expectedColumn);
|
||||
CHECK(strstr(report.message(), lineAndColumnASCII) != nullptr);
|
||||
js_free((void*)lineAndColumnASCII);
|
||||
|
||||
/* We do not execute JS, so there should be no exception thrown. */
|
||||
CHECK(!JS_IsExceptionPending(cx));
|
||||
|
@ -5168,7 +5168,7 @@ class JSErrorReport
|
||||
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
|
||||
filename(nullptr), lineno(0), column(0), isMuted(false),
|
||||
flags(0), errorNumber(0), ucmessage(nullptr),
|
||||
messageArgs(nullptr), exnType(0)
|
||||
exnType(0)
|
||||
{}
|
||||
|
||||
const char* filename; /* source file name, URL, etc., or null */
|
||||
@ -5178,7 +5178,6 @@ class JSErrorReport
|
||||
unsigned flags; /* error/warning, etc. */
|
||||
unsigned errorNumber; /* the error number, e.g. see js.msg */
|
||||
const char16_t* ucmessage; /* the (default) error message */
|
||||
const char16_t** messageArgs; /* arguments for the error message */
|
||||
int16_t exnType; /* One of the JSExnType constants */
|
||||
|
||||
const char16_t* linebuf() const {
|
||||
|
@ -459,6 +459,21 @@ js::PrintError(JSContext* cx, FILE* file, const char* message, JSErrorReport* re
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeMessageArgs(const char16_t** messageArgs, ErrorArgumentsType argumentsType)
|
||||
{
|
||||
if (!messageArgs)
|
||||
return;
|
||||
|
||||
/* free the arguments only if we allocated them */
|
||||
if (argumentsType == ArgumentsAreASCII) {
|
||||
uint16_t i = 0;
|
||||
while (messageArgs[i])
|
||||
js_free((void*)messageArgs[i++]);
|
||||
}
|
||||
js_free(messageArgs);
|
||||
}
|
||||
|
||||
/*
|
||||
* The arguments from ap need to be packaged up into an array and stored
|
||||
* into the report struct.
|
||||
@ -473,12 +488,13 @@ js::PrintError(JSContext* cx, FILE* file, const char* message, JSErrorReport* re
|
||||
bool
|
||||
js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
char** messagep, ErrorArgumentsType argumentsType,
|
||||
char** messagep, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap)
|
||||
{
|
||||
const JSErrorFormatString* efs;
|
||||
uint16_t argCount;
|
||||
bool messageArgsPassed = !!reportp->messageArgs;
|
||||
bool messageArgsPassed = !!messageArgs;
|
||||
|
||||
*messagep = nullptr;
|
||||
|
||||
@ -505,13 +521,12 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
* pointers later.
|
||||
*/
|
||||
if (messageArgsPassed) {
|
||||
MOZ_ASSERT(!reportp->messageArgs[argCount]);
|
||||
MOZ_ASSERT(!messageArgs[argCount]);
|
||||
} else {
|
||||
reportp->messageArgs = cx->pod_malloc<const char16_t*>(argCount + 1);
|
||||
if (!reportp->messageArgs)
|
||||
messageArgs = cx->pod_malloc<const char16_t*>(argCount + 1);
|
||||
if (!messageArgs)
|
||||
return false;
|
||||
/* nullptr-terminate for easy copying. */
|
||||
reportp->messageArgs[argCount] = nullptr;
|
||||
messageArgs[argCount] = nullptr;
|
||||
}
|
||||
for (uint16_t i = 0; i < argCount; i++) {
|
||||
if (messageArgsPassed) {
|
||||
@ -519,13 +534,13 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
} else if (argumentsType == ArgumentsAreASCII) {
|
||||
char* charArg = va_arg(ap, char*);
|
||||
size_t charArgLength = strlen(charArg);
|
||||
reportp->messageArgs[i] = InflateString(cx, charArg, &charArgLength);
|
||||
if (!reportp->messageArgs[i])
|
||||
messageArgs[i] = InflateString(cx, charArg, &charArgLength);
|
||||
if (!messageArgs[i])
|
||||
goto error;
|
||||
} else {
|
||||
reportp->messageArgs[i] = va_arg(ap, char16_t*);
|
||||
messageArgs[i] = va_arg(ap, char16_t*);
|
||||
}
|
||||
argLengths[i] = js_strlen(reportp->messageArgs[i]);
|
||||
argLengths[i] = js_strlen(messageArgs[i]);
|
||||
totalArgsLength += argLengths[i];
|
||||
}
|
||||
}
|
||||
@ -563,8 +578,7 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
if (isdigit(fmt[1])) {
|
||||
int d = JS7_UNDEC(fmt[1]);
|
||||
MOZ_RELEASE_ASSERT(d < argCount);
|
||||
js_strncpy(out, reportp->messageArgs[d],
|
||||
argLengths[d]);
|
||||
js_strncpy(out, messageArgs[d], argLengths[d]);
|
||||
out += argLengths[d];
|
||||
fmt += 3;
|
||||
expandedArgs++;
|
||||
@ -585,7 +599,7 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
}
|
||||
} else {
|
||||
/* Non-null messageArgs should have at least one non-null arg. */
|
||||
MOZ_ASSERT(!reportp->messageArgs);
|
||||
MOZ_ASSERT(!messageArgsPassed);
|
||||
/*
|
||||
* Zero arguments: the format string (if it exists) is the
|
||||
* entire message.
|
||||
@ -612,19 +626,13 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
goto error;
|
||||
snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
|
||||
}
|
||||
if (!messageArgsPassed)
|
||||
FreeMessageArgs(messageArgs, argumentsType);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (!messageArgsPassed && reportp->messageArgs) {
|
||||
/* free the arguments only if we allocated them */
|
||||
if (argumentsType == ArgumentsAreASCII) {
|
||||
uint16_t i = 0;
|
||||
while (reportp->messageArgs[i])
|
||||
js_free((void*)reportp->messageArgs[i++]);
|
||||
}
|
||||
js_free((void*)reportp->messageArgs);
|
||||
reportp->messageArgs = nullptr;
|
||||
}
|
||||
if (!messageArgsPassed)
|
||||
FreeMessageArgs(messageArgs, argumentsType);
|
||||
if (reportp->ucmessage) {
|
||||
js_free((void*)reportp->ucmessage);
|
||||
reportp->ucmessage = nullptr;
|
||||
@ -654,25 +662,13 @@ js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
PopulateReportBlame(cx, &report);
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
|
||||
&message, argumentsType, &report, ap)) {
|
||||
&message, nullptr, argumentsType, &report, ap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
js_free(message);
|
||||
if (report.messageArgs) {
|
||||
/*
|
||||
* ExpandErrorArgumentsVA owns its messageArgs only if it had to
|
||||
* inflate the arguments (from regular |char*|s).
|
||||
*/
|
||||
if (argumentsType == ArgumentsAreASCII) {
|
||||
int i = 0;
|
||||
while (report.messageArgs[i])
|
||||
js_free((void*)report.messageArgs[i++]);
|
||||
}
|
||||
js_free((void*)report.messageArgs);
|
||||
}
|
||||
js_free((void*)report.ucmessage);
|
||||
|
||||
return warning;
|
||||
@ -681,13 +677,14 @@ js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
static bool
|
||||
ExpandErrorArguments(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
char** messagep, ErrorArgumentsType argumentsType,
|
||||
char** messagep, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, reportp);
|
||||
bool expanded = js::ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
|
||||
messagep, argumentsType, reportp, ap);
|
||||
messagep, messageArgs, argumentsType, reportp, ap);
|
||||
va_end(ap);
|
||||
return expanded;
|
||||
}
|
||||
@ -705,11 +702,11 @@ js::ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback call
|
||||
report.flags = flags;
|
||||
report.errorNumber = errorNumber;
|
||||
PopulateReportBlame(cx, &report);
|
||||
report.messageArgs = args;
|
||||
|
||||
char* message;
|
||||
if (!ExpandErrorArguments(cx, callback, userRef, errorNumber,
|
||||
&message, ArgumentsAreUnicode, &report)) {
|
||||
&message, args, ArgumentsAreUnicode, &report))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -578,7 +578,8 @@ ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback callback
|
||||
extern bool
|
||||
ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
char** message, ErrorArgumentsType argumentsType,
|
||||
char** message, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap);
|
||||
|
||||
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
|
||||
|
@ -148,8 +148,6 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
* We use a single malloc block to make a deep copy of JSErrorReport with
|
||||
* the following layout:
|
||||
* JSErrorReport
|
||||
* array of copies of report->messageArgs
|
||||
* char16_t array with characters for all messageArgs
|
||||
* char16_t array with characters for ucmessage
|
||||
* char16_t array with characters for linebuf
|
||||
* char array with characters for filename
|
||||
@ -166,27 +164,14 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
if (report->linebuf())
|
||||
linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
|
||||
size_t ucmessageSize = 0;
|
||||
size_t argsArraySize = 0;
|
||||
size_t argsCopySize = 0;
|
||||
if (report->ucmessage) {
|
||||
if (report->ucmessage)
|
||||
ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
|
||||
if (report->messageArgs) {
|
||||
size_t i = 0;
|
||||
for (; report->messageArgs[i]; ++i)
|
||||
argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);
|
||||
|
||||
/* Non-null messageArgs should have at least one non-null arg. */
|
||||
MOZ_ASSERT(i != 0);
|
||||
argsArraySize = (i + 1) * sizeof(const char16_t*);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The mallocSize can not overflow since it represents the sum of the
|
||||
* sizes of already allocated objects.
|
||||
*/
|
||||
size_t mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
|
||||
ucmessageSize + linebufSize + filenameSize;
|
||||
size_t mallocSize = sizeof(JSErrorReport) + ucmessageSize + linebufSize + filenameSize;
|
||||
uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
|
||||
if (!cursor)
|
||||
return nullptr;
|
||||
@ -194,20 +179,6 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
JSErrorReport* copy = (JSErrorReport*)cursor;
|
||||
cursor += sizeof(JSErrorReport);
|
||||
|
||||
if (argsArraySize != 0) {
|
||||
copy->messageArgs = (const char16_t**)cursor;
|
||||
cursor += argsArraySize;
|
||||
size_t i = 0;
|
||||
for (; report->messageArgs[i]; ++i) {
|
||||
copy->messageArgs[i] = (const char16_t*)cursor;
|
||||
size_t argSize = JS_CHARS_SIZE(report->messageArgs[i]);
|
||||
js_memcpy(cursor, report->messageArgs[i], argSize);
|
||||
cursor += argSize;
|
||||
}
|
||||
copy->messageArgs[i] = nullptr;
|
||||
MOZ_ASSERT(cursor == (uint8_t*)copy->messageArgs[0] + argsCopySize);
|
||||
}
|
||||
|
||||
if (report->ucmessage) {
|
||||
copy->ucmessage = (const char16_t*)cursor;
|
||||
js_memcpy(cursor, report->ucmessage, ucmessageSize);
|
||||
@ -674,17 +645,6 @@ ErrorReport::~ErrorReport()
|
||||
return;
|
||||
|
||||
js_free(ownedMessage);
|
||||
if (ownedReport.messageArgs) {
|
||||
/*
|
||||
* ExpandErrorArgumentsVA owns its messageArgs only if it had to
|
||||
* inflate the arguments (from regular |char*|s), which is always in
|
||||
* our case.
|
||||
*/
|
||||
size_t i = 0;
|
||||
while (ownedReport.messageArgs[i])
|
||||
js_free(const_cast<char16_t*>(ownedReport.messageArgs[i++]));
|
||||
js_free(ownedReport.messageArgs);
|
||||
}
|
||||
js_free(const_cast<char16_t*>(ownedReport.ucmessage));
|
||||
}
|
||||
|
||||
@ -945,7 +905,7 @@ ErrorReport::populateUncaughtExceptionReportVA(JSContext* cx, va_list ap)
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_UNCAUGHT_EXCEPTION, &ownedMessage,
|
||||
ArgumentsAreASCII, &ownedReport, ap)) {
|
||||
nullptr, ArgumentsAreASCII, &ownedReport, ap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user