Bug 1282795 - Don't make the last non-ellipsis argument to ExpandErrorArgumentsVA an enumeration that would be subject to integral promotion, because this would invoke undefined behavior. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Tue, 28 Jun 2016 17:11:01 +0100
changeset 303016 9c4675f6970fe850de47cffb3b1fb504d35fa563
parent 303015 1aeffbc50a98ca81547cb46d9759d5fe0a11bdfe
child 303017 ddd5a4c1edc8774f7a0179856ecfec36164a4795
push id78958
push userjwalden@mit.edu
push dateWed, 29 Jun 2016 09:35:06 +0000
treeherdermozilla-inbound@00aadbafd114 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1282795
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1282795 - Don't make the last non-ellipsis argument to ExpandErrorArgumentsVA an enumeration that would be subject to integral promotion, because this would invoke undefined behavior. r=froydnj
js/src/frontend/TokenStream.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsexn.cpp
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -647,17 +647,17 @@ TokenStream::reportCompileErrorNumberVA(
             err.report.filename = iter.filename();
             err.report.lineno = iter.computeLine(&err.report.column);
         }
     }
 
     err.argumentsType = (flags & JSREPORT_UC) ? ArgumentsAreUnicode : ArgumentsAreASCII;
 
     if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber, &err.message,
-                                &err.report, err.argumentsType, args))
+                                err.argumentsType, &err.report, args))
     {
         return false;
     }
 
     // Given a token, T, that we want to complain about: if T's (starting)
     // lineno doesn't match TokenStream's lineno, that means we've scanned past
     // the line that T starts on, which makes it hard to print some or all of
     // T's (starting) line for context.
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -479,18 +479,18 @@ js::PrintError(JSContext* cx, FILE* file
  * is to be replaced by the Nth argument from the va_list. The complete
  * message is placed into reportp->ucmessage converted to a JSString.
  *
  * Returns true if the expansion succeeds (can fail if out of memory).
  */
 bool
 js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
                            void* userRef, const unsigned errorNumber,
-                           char** messagep, JSErrorReport* reportp,
-                           ErrorArgumentsType argumentsType, va_list ap)
+                           char** messagep, ErrorArgumentsType argumentsType,
+                           JSErrorReport* reportp, va_list ap)
 {
     const JSErrorFormatString* efs;
     uint16_t argCount;
     bool messageArgsPassed = !!reportp->messageArgs;
 
     *messagep = nullptr;
 
     if (!callback)
@@ -660,17 +660,17 @@ js::ReportErrorNumberVA(JSContext* cx, u
         return true;
     warning = JSREPORT_IS_WARNING(flags);
 
     report.flags = flags;
     report.errorNumber = errorNumber;
     PopulateReportBlame(cx, &report);
 
     if (!ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
-                                &message, &report, argumentsType, ap)) {
+                                &message, argumentsType, &report, ap)) {
         return false;
     }
 
     ReportError(cx, message, &report, callback, userRef);
 
     js_free(message);
     if (report.messageArgs) {
         /*
@@ -687,23 +687,23 @@ js::ReportErrorNumberVA(JSContext* cx, u
     js_free((void*)report.ucmessage);
 
     return warning;
 }
 
 static bool
 ExpandErrorArguments(ExclusiveContext* cx, JSErrorCallback callback,
                      void* userRef, const unsigned errorNumber,
-                     char** messagep, JSErrorReport* reportp,
-                     ErrorArgumentsType argumentsType, ...)
+                     char** messagep, ErrorArgumentsType argumentsType,
+                     JSErrorReport* reportp, ...)
 {
     va_list ap;
-    va_start(ap, argumentsType);
+    va_start(ap, reportp);
     bool expanded = js::ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
-                                               messagep, reportp, argumentsType, ap);
+                                               messagep, argumentsType, reportp, ap);
     va_end(ap);
     return expanded;
 }
 
 bool
 js::ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback callback,
                              void* userRef, const unsigned errorNumber,
                              const char16_t** args)
@@ -715,17 +715,17 @@ js::ReportErrorNumberUCArray(JSContext* 
     JSErrorReport report;
     report.flags = flags;
     report.errorNumber = errorNumber;
     PopulateReportBlame(cx, &report);
     report.messageArgs = args;
 
     char* message;
     if (!ExpandErrorArguments(cx, callback, userRef, errorNumber,
-                              &message, &report, ArgumentsAreUnicode)) {
+                              &message, ArgumentsAreUnicode, &report)) {
         return false;
     }
 
     ReportError(cx, message, &report, callback, userRef);
 
     js_free(message);
     js_free((void*)report.ucmessage);
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -542,18 +542,18 @@ extern bool
 ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback callback,
                          void* userRef, const unsigned errorNumber,
                          const char16_t** args);
 #endif
 
 extern bool
 ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
                        void* userRef, const unsigned errorNumber,
-                       char** message, JSErrorReport* reportp,
-                       ErrorArgumentsType argumentsType, va_list ap);
+                       char** message, ErrorArgumentsType argumentsType,
+                       JSErrorReport* reportp, va_list ap);
 
 /* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
 extern void
 ReportUsageError(JSContext* cx, HandleObject callee, const char* msg);
 
 /*
  * Prints a full report and returns true if the given report is non-nullptr
  * and the report doesn't have the JSREPORT_WARNING flag set or reportWarnings
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -939,17 +939,17 @@ ErrorReport::populateUncaughtExceptionRe
         // which is how SpiderMonkey stores it internally. This will be
         // unnecessary once bug 1144340 is fixed.
         ++ownedReport.column;
         ownedReport.isMuted = iter.mutedErrors();
     }
 
     if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr,
                                 JSMSG_UNCAUGHT_EXCEPTION, &ownedMessage,
-                                &ownedReport, ArgumentsAreASCII, ap)) {
+                                ArgumentsAreASCII, &ownedReport, ap)) {
         return false;
     }
 
     reportp = &ownedReport;
     message_ = ownedMessage;
     ownsMessageAndReport = true;
     return true;
 }