Bug 1290422 - Part 1: Remove JSErrorReport.messageArgs. r=jwalden

This commit is contained in:
Tooru Fujisawa 2016-08-03 18:09:42 +09:00
parent f9e30f8e42
commit ad44dc986e
6 changed files with 142 additions and 184 deletions

View File

@ -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;
}

View File

@ -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));

View File

@ -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 {

View File

@ -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;
}

View File

@ -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. */

View File

@ -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;
}