[ES6] Allow undefined/null for Symbol.search and Symbol.match
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Mar 2016 09:11:56 +0000 (09:11 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Mar 2016 09:11:56 +0000 (09:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155785

Reviewed by Saam Barati.

Undefined and null for Symbol.search and Symbol.match properties of the given RegExp (like) object are allowed.
When they are specified, we go to the fallback path; creating the RegExp with the given object and matching.

* builtins/StringPrototype.js:
(match):
(search):
* tests/stress/string-symbol-customization.js: Added.
(shouldBe):
(shouldThrow):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198581 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/StringPrototype.js
Source/JavaScriptCore/tests/stress/string-symbol-customization.js [new file with mode: 0644]

index f64d324..0049afa 100644 (file)
@@ -1,3 +1,20 @@
+2016-03-23  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Allow undefined/null for Symbol.search and Symbol.match
+        https://bugs.webkit.org/show_bug.cgi?id=155785
+
+        Reviewed by Saam Barati.
+
+        Undefined and null for Symbol.search and Symbol.match properties of the given RegExp (like) object are allowed.
+        When they are specified, we go to the fallback path; creating the RegExp with the given object and matching.
+
+        * builtins/StringPrototype.js:
+        (match):
+        (search):
+        * tests/stress/string-symbol-customization.js: Added.
+        (shouldBe):
+        (shouldThrow):
+
 2016-03-22  Caitlin Potter  <caitp@igalia.com>
 
         [JSC] correctly handle indexed properties in Object.getOwnPropertyDescriptors
 2016-03-22  Caitlin Potter  <caitp@igalia.com>
 
         [JSC] correctly handle indexed properties in Object.getOwnPropertyDescriptors
index 2d07035..56cca6a 100644 (file)
@@ -24,8 +24,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// @conditional=ENABLE(INTL)
-
 function match(regexp)
 {
     "use strict";
 function match(regexp)
 {
     "use strict";
@@ -38,7 +36,7 @@ function match(regexp)
 
     if (regexp != null) {
         var matcher = regexp[@symbolMatch];
 
     if (regexp != null) {
         var matcher = regexp[@symbolMatch];
-        if (matcher !== @undefined)
+        if (matcher != @undefined)
             return matcher.@call(regexp, this);
     }
 
             return matcher.@call(regexp, this);
     }
 
@@ -59,7 +57,7 @@ function search(regexp)
 
     if (regexp != null) {
          var searcher = regexp[@symbolSearch];
 
     if (regexp != null) {
          var searcher = regexp[@symbolSearch];
-         if (searcher !== @undefined)
+         if (searcher != @undefined)
             return searcher.@call(regexp, this);
     }
 
             return searcher.@call(regexp, this);
     }
 
diff --git a/Source/JavaScriptCore/tests/stress/string-symbol-customization.js b/Source/JavaScriptCore/tests/stress/string-symbol-customization.js
new file mode 100644 (file)
index 0000000..5ecaf0c
--- /dev/null
@@ -0,0 +1,108 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+function shouldThrow(func, errorMessage) {
+    var errorThrown = false;
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        errorThrown = true;
+        error = e;
+    }
+    if (!errorThrown)
+        throw new Error('not thrown');
+    if (String(error) !== errorMessage)
+        throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldThrow(() => {
+    "Cocoa".search({
+        [Symbol.search]: 42
+    });
+}, `TypeError: 42 is not a function`);
+
+shouldThrow(() => {
+    "Cocoa".match({
+        [Symbol.match]: 42
+    });
+}, `TypeError: 42 is not a function`);
+
+shouldThrow(() => {
+    "Cocoa".search({
+        [Symbol.search]: {}
+    });
+}, `TypeError: Object is not a function`);
+
+shouldThrow(() => {
+    "Cocoa".match({
+        [Symbol.match]: {}
+    });
+}, `TypeError: Object is not a function`);
+
+shouldBe("Cocoa".search({
+    [Symbol.search]: null,
+    toString()
+    {
+        return "C"
+    }
+}), 0);
+
+shouldBe("Cocoa".match({
+    [Symbol.match]: null,
+    toString()
+    {
+        return "C"
+    }
+})[0], "C");
+
+shouldBe("Cocoa".search({
+    [Symbol.search]: undefined,
+    toString()
+    {
+        return "C"
+    }
+}), 0);
+
+shouldBe("Cocoa".match({
+    [Symbol.match]: undefined,
+    toString()
+    {
+        return "C"
+    }
+})[0], "C");
+
+shouldBe("Cocoa".search({
+    [Symbol.search]()
+    {
+        return 42;
+    }
+}), 42);
+
+shouldBe("Cocoa".match({
+    [Symbol.match]()
+    {
+        return 42;
+    }
+}), 42);
+
+RegExp.prototype[Symbol.search] = function () { return 42; };
+RegExp.prototype[Symbol.match] = function () { return 42; };
+
+shouldBe("Cocoa".search({
+    [Symbol.search]: null
+}), 42);
+
+shouldBe("Cocoa".match({
+    [Symbol.match]: null
+}), 42);
+
+shouldBe("Cocoa".search({
+    [Symbol.search]: undefined
+}), 42);
+
+shouldBe("Cocoa".match({
+    [Symbol.match]: undefined
+}), 42);