Bug 635017 - /undefined/.match() should succeed. r=jorendorff.

This commit is contained in:
Tom Schuster 2011-07-22 09:46:07 -05:00
parent 55b2a4bd7e
commit ffe5a02597
10 changed files with 64 additions and 245 deletions

View File

@ -19,13 +19,13 @@ function test0() {
assertEq(script1.call(null, 1), 1);
assertEq(script1.call(null, 1,2), 2);
assertEq(native1.call("aabc", /b/), 2);
assertEq(native1.call("abc"), -1);
assertEq(native1.call("abc"), 0);
assertEq(tricky1.call(null, 9), 9);
assertEq(script1.apply(null), 0);
assertEq(script1.apply(null, [1]), 1);
assertEq(script1.apply(null, [1,2]), 2);
assertEq(native1.apply("aabc", [/b/]), 2);
assertEq(native1.apply("abc"), -1);
assertEq(native1.apply("abc"), 0);
assertEq(tricky1.apply(null, 1), 1);
}
test0();

View File

@ -598,12 +598,7 @@ ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
if (!obj)
return false;
if (!obj->isRegExp()) {
JSFunction *fun = vp[0].toObject().getFunctionPrivate();
JSAutoByteString funNameBytes;
if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
"RegExp", funName, obj->getClass()->name);
}
ReportIncompatibleMethod(cx, vp, &js_RegExpClass);
return false;
}
@ -619,29 +614,10 @@ ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
RegExpStatics *res = cx->regExpStatics();
/* Step 2. */
JSString *input;
if (argc > 0) {
input = js_ValueToString(cx, vp[2]);
if (!input)
return false;
vp[2] = StringValue(input);
} else {
/* NON-STANDARD: Grab input from statics. */
input = res->getPendingInput();
if (!input) {
JSAutoByteString sourceBytes(cx, re->getSource());
if (!!sourceBytes) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_INPUT,
sourceBytes.ptr(),
re->global() ? "g" : "",
re->ignoreCase() ? "i" : "",
re->multiline() ? "m" : "",
re->sticky() ? "y" : "");
}
return false;
}
}
JSString *input = js_ValueToString(cx, argc > 0 ? vp[2] : UndefinedValue());
if (!input)
return false;
/* Step 3. */
size_t length = input->length();

View File

@ -341,11 +341,12 @@ RegExp::executeInternal(JSContext *cx, RegExpStatics *res, JSString *inputstr,
*/
for (int *it = buf; it != buf + matchItemCount; ++it)
*it = -1;
JSLinearString *input = inputstr->ensureLinear(cx);
if (!input)
return false;
JS::Anchor<JSString *> anchor(input);
size_t len = input->length();
const jschar *chars = input->chars();

View File

@ -1339,11 +1339,16 @@ class RegExpGuard
/* init must succeed in order to call tryFlatMatch or normalizeRegExp. */
bool
init(uintN argc, Value *vp)
init(uintN argc, Value *vp, bool convertVoid = false)
{
if (argc != 0 && VALUE_IS_REGEXP(cx, vp[2])) {
rep.reset(vp[2].toObject());
} else {
if (convertVoid && (argc == 0 || vp[2].isUndefined())) {
fm.patstr = cx->runtime->emptyString;
return true;
}
fm.patstr = ArgToRootedString(cx, argc, vp, 0);
if (!fm.patstr)
return false;
@ -1542,9 +1547,9 @@ str_match(JSContext *cx, uintN argc, Value *vp)
JSString *str = ThisToStringForStringProto(cx, vp);
if (!str)
return false;
RegExpGuard g(cx);
if (!g.init(argc, vp))
if (!g.init(argc, vp, true))
return false;
if (const FlatMatch *fm = g.tryFlatMatch(cx, str, 1, argc))
return BuildFlatMatchArray(cx, str, *fm, vp);
@ -1577,7 +1582,7 @@ str_search(JSContext *cx, uintN argc, Value *vp)
return false;
RegExpGuard g(cx);
if (!g.init(argc, vp))
if (!g.init(argc, vp, true))
return false;
if (const FlatMatch *fm = g.tryFlatMatch(cx, str, 1, argc)) {
vp->setInt32(fm->match());
@ -1585,6 +1590,7 @@ str_search(JSContext *cx, uintN argc, Value *vp)
}
if (cx->isExceptionPending()) /* from tryFlatMatch */
return false;
const RegExpPair *rep = g.normalizeRegExp(false, 1, argc, vp);
if (!rep)
return false;

View File

@ -13,4 +13,5 @@ script builtin-methods-reject-null-undefined-this.js
script regress-bug632003.js
script new-with-non-constructor.js
script error-undefined-message.js
script regexp-functions-with-undefined.js
script unnamed-function.js

View File

@ -0,0 +1,43 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var a = /undefined/.exec();
assertEq(a[0], 'undefined');
assertEq(a.length, 1);
a = /undefined/.exec(undefined);
assertEq(a[0], 'undefined');
assertEq(a.length, 1);
assertEq(/undefined/.test(), true);
assertEq(/undefined/.test(undefined), true);
assertEq(/aaaa/.exec(), null);
assertEq(/aaaa/.exec(undefined), null);
assertEq(/aaaa/.test(), false);
assertEq(/aaaa/.test(undefined), false);
assertEq("undefined".search(), 0);
assertEq("undefined".search(undefined), 0);
assertEq("aaaa".search(), 0);
assertEq("aaaa".search(undefined), 0);
a = "undefined".match();
assertEq(a[0], "");
assertEq(a.length, 1);
a = "undefined".match(undefined);
assertEq(a[0], "");
assertEq(a.length, 1);
a = "aaaa".match();
assertEq(a[0], "");
assertEq(a.length, 1);
a = "aaaa".match(undefined);
assertEq(a[0], "");
assertEq(a.length, 1);
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -1,103 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
Filename: RegExp_input.js
Description: 'Tests RegExps input property'
Author: Nick Lerissa
Date: March 13, 1998
*/
var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"';
var VERSION = 'no version';
startTest();
var TITLE = 'RegExp: input';
writeHeaderToLog('Executing script: RegExp_input.js');
writeHeaderToLog( SECTION + " "+ TITLE);
RegExp.input = "abcd12357efg";
// RegExp.input = "abcd12357efg"; RegExp.input
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; RegExp.input",
"abcd12357efg", RegExp.input);
// RegExp.input = "abcd12357efg"; /\d+/.exec('2345')
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.exec('2345')",
String(["2345"]), String(/\d+/.exec('2345')));
// RegExp.input = "abcd12357efg"; /\d+/.exec()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.exec()",
String(["12357"]), String(/\d+/.exec()));
// RegExp.input = "abcd12357efg"; /[h-z]+/.exec()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.exec()",
null, /[h-z]+/.exec());
// RegExp.input = "abcd12357efg"; /\d+/.test('2345')
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.test('2345')",
true, /\d+/.test('2345'));
// RegExp.input = "abcd12357efg"; /\d+/.test()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /\\d+/.test()",
true, /\d+/.test());
// RegExp.input = "abcd12357efg"; (new RegExp('d+')).test()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('d+')).test()",
true, (new RegExp('d+')).test());
// RegExp.input = "abcd12357efg"; /[h-z]+/.test()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; /[h-z]+/.test()",
false, /[h-z]+/.test());
// RegExp.input = "abcd12357efg"; (new RegExp('[h-z]+')).test()
RegExp.input = "abcd12357efg";
new TestCase ( SECTION, "RegExp.input = 'abcd12357efg'; (new RegExp('[h-z]+')).test()",
false, (new RegExp('[h-z]+')).test());
test();

View File

@ -1,103 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
Filename: RegExp_input_as_array.js
Description: 'Tests RegExps $_ property (same tests as RegExp_input.js but using $_)'
Author: Nick Lerissa
Date: March 13, 1998
*/
var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"';
var VERSION = 'no version';
startTest();
var TITLE = 'RegExp: input';
writeHeaderToLog('Executing script: RegExp_input.js');
writeHeaderToLog( SECTION + " "+ TITLE);
RegExp['$_'] = "abcd12357efg";
// RegExp['$_'] = "abcd12357efg"; RegExp['$_']
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; RegExp['$_']",
"abcd12357efg", RegExp['$_']);
// RegExp['$_'] = "abcd12357efg"; /\d+/.exec('2345')
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.exec('2345')",
String(["2345"]), String(/\d+/.exec('2345')));
// RegExp['$_'] = "abcd12357efg"; /\d+/.exec()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.exec()",
String(["12357"]), String(/\d+/.exec()));
// RegExp['$_'] = "abcd12357efg"; /[h-z]+/.exec()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.exec()",
null, /[h-z]+/.exec());
// RegExp['$_'] = "abcd12357efg"; /\d+/.test('2345')
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.test('2345')",
true, /\d+/.test('2345'));
// RegExp['$_'] = "abcd12357efg"; /\d+/.test()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /\\d+/.test()",
true, /\d+/.test());
// RegExp['$_'] = "abcd12357efg"; /[h-z]+/.test()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; /[h-z]+/.test()",
false, /[h-z]+/.test());
// RegExp['$_'] = "abcd12357efg"; (new RegExp('\d+')).test()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('\d+')).test()",
true, (new RegExp('\d+')).test());
// RegExp['$_'] = "abcd12357efg"; (new RegExp('[h-z]+')).test()
RegExp['$_'] = "abcd12357efg";
new TestCase ( SECTION, "RegExp['$_'] = 'abcd12357efg'; (new RegExp('[h-z]+')).test()",
false, (new RegExp('[h-z]+')).test());
test();

View File

@ -1,7 +1,5 @@
url-prefix ../../jsreftest.html?test=js1_2/regexp/
script RegExp_dollar_number.js
script RegExp_input.js
script RegExp_input_as_array.js
skip script RegExp_lastIndex.js # obsolete test
script RegExp_lastMatch.js
script RegExp_lastMatch_as_array.js

View File

@ -2,7 +2,7 @@ function f(code) {
code.replace(/s/, "")
eval(code)
}
this.__defineGetter__("x", function() { return /x/.exec(); })
this.__defineGetter__("x", function() { return /x/.exec('x'); })
f("function a() {\
x = Proxy.createFunction((function () {\
return {\