Bug 1142351 - Part 2: Warn about deprecated flag argument for String.prototype.{search,match,replace}. r=jandem
authorTooru Fujisawa <arai_a@mac.com>
Wed, 25 Mar 2015 00:36:35 +0900
changeset 265670 d802bf89d877f75874dc3c1db97d38db90acedca
parent 265669 a7556816cb5f9f9468bddeed3a208871e0295785
child 265671 f12794ccc9882e6e8a8a728acbb771cec4c8b77a
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1142351
milestone39.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 1142351 - Part 2: Warn about deprecated flag argument for String.prototype.{search,match,replace}. r=jandem
js/src/js.msg
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsstr.cpp
js/src/tests/js1_5/String/replace-flags.js
js/src/vm/Xdr.h
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -227,16 +227,17 @@ MSG_DEF(JSMSG_CURLY_BEFORE_CATCH,      0
 MSG_DEF(JSMSG_CURLY_BEFORE_CLASS,      0, JSEXN_SYNTAXERR, "missing { before class body")
 MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    0, JSEXN_SYNTAXERR, "missing { before finally block")
 MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing { before switch body")
 MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        0, JSEXN_SYNTAXERR, "missing { before try block")
 MSG_DEF(JSMSG_CURLY_IN_COMPOUND,       0, JSEXN_SYNTAXERR, "missing } in compound statement")
 MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
 MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
 MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
+MSG_DEF(JSMSG_DEPRECATED_FLAGS_ARG,    0, JSEXN_NONE, "flags argument of String.prototype.{search,match,replace} is deprecated")
 MSG_DEF(JSMSG_DEPRECATED_LET_BLOCK,      0, JSEXN_NONE, "JavaScript 1.7's let blocks are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_FOR_EACH,     0, JSEXN_NONE, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead")
 MSG_DEF(JSMSG_DEPRECATED_LET_EXPRESSION, 0, JSEXN_NONE, "JavaScript 1.7's let expressions are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
 MSG_DEF(JSMSG_DEPRECATED_PRAGMA,       1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
 MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
 MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
 MSG_DEF(JSMSG_DUPLICATE_PROPERTY,      1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -41,16 +41,17 @@ JSCompartment::JSCompartment(Zone *zone,
   : options_(options),
     zone_(zone),
     runtime_(zone->runtimeFromMainThread()),
     principals(nullptr),
     isSystem(false),
     isSelfHosting(false),
     marked(true),
     warnedAboutNoSuchMethod(false),
+    warnedAboutFlagsArgument(false),
     addonId(options.addonIdOrNull()),
 #ifdef DEBUG
     firedOnNewGlobalObject(false),
 #endif
     global_(nullptr),
     enterCompartmentDepth(0),
     totalTime(0),
     data(nullptr),
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -144,16 +144,17 @@ struct JSCompartment
     JSRuntime                    *runtime_;
 
   public:
     JSPrincipals                 *principals;
     bool                         isSystem;
     bool                         isSelfHosting;
     bool                         marked;
     bool                         warnedAboutNoSuchMethod;
+    bool                         warnedAboutFlagsArgument;
 
     // A null add-on ID means that the compartment is not associated with an
     // add-on.
     JSAddonId                    *addonId;
 
 #ifdef DEBUG
     bool                         firedOnNewGlobalObject;
 #endif
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2132,16 +2132,23 @@ class MOZ_STACK_CLASS StringRegExpGuard
         /* Build RegExp from pattern string. */
         RootedString opt(cx);
         if (optarg < args.length()) {
             if (JSScript *script = cx->currentScript()) {
                 const char *filename = script->filename();
                 cx->compartment()->addTelemetry(filename, JSCompartment::DeprecatedFlagsArgument);
             }
 
+            if (!cx->compartment()->warnedAboutFlagsArgument) {
+                if (!JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
+                                                  JSMSG_DEPRECATED_FLAGS_ARG))
+                    return false;
+                cx->compartment()->warnedAboutFlagsArgument = true;
+            }
+
             opt = ToString<CanGC>(cx, args[optarg]);
             if (!opt)
                 return false;
         } else {
             opt = nullptr;
         }
 
         Rooted<JSAtom *> pat(cx);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/js1_5/String/replace-flags.js
@@ -0,0 +1,15 @@
+// |reftest| skip-if(!xulRuntime.shell)
+
+var BUGNUMBER = 1142351;
+var summary = 'Add console warnings for non-standard flag argument of String.prototype.{search,match,replace}.';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+options("werror");
+assertEq(evaluate("'aaaA'.match('a', 'i')", {catchTermination: true}), "terminated");
+assertEq(evaluate("'aaaA'.search('a', 'i')", {catchTermination: true}), "terminated");
+assertEq(evaluate("'aaaA'.replace('a', 'b', 'g')", {catchTermination: true}), "terminated");
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -24,21 +24,21 @@ namespace js {
  * versions.  If deserialization fails, the data should be invalidated if
  * possible.
  *
  * When you change this, run make_opcode_doc.py and copy the new output into
  * this wiki page:
  *
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  */
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 267;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 268;
 static const uint32_t XDR_BYTECODE_VERSION =
     uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
 
-static_assert(JSErr_Limit == 388,
+static_assert(JSErr_Limit == 389,
               "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
               "removed MSG_DEFs from js.msg, you should increment "
               "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
               "expected JSErr_Limit value.");
 
 class XDRBuffer {
   public:
     explicit XDRBuffer(JSContext *cx)