зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1054755 - Part 3: Use IsRegExp in String.prototype.{contains,startsWith,endsWith}. r=till
This commit is contained in:
Родитель
1c0d394afc
Коммит
058a4ec235
|
@ -1508,7 +1508,7 @@ RopeMatch(JSContext* cx, JSRope* text, JSLinearString* pat, int* match)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ES6 20121026 draft 15.5.4.24. */
|
||||
/* ES6 draft rc3 21.1.3.7. */
|
||||
static bool
|
||||
str_contains(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -1520,11 +1520,23 @@ str_contains(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
|
||||
// Steps 4 and 5
|
||||
bool isRegExp;
|
||||
if (!IsRegExp(cx, args.get(0), &isRegExp))
|
||||
return false;
|
||||
|
||||
// Step 6
|
||||
if (isRegExp) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INVALID_ARG_TYPE,
|
||||
"first", "", "Regular Expression");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 7 and 8
|
||||
RootedLinearString searchStr(cx, ArgToRootedString(cx, args, 0));
|
||||
if (!searchStr)
|
||||
return false;
|
||||
|
||||
// Steps 6 and 7
|
||||
// Steps 9 and 10
|
||||
uint32_t pos = 0;
|
||||
if (args.hasDefined(1)) {
|
||||
if (args[1].isInt32()) {
|
||||
|
@ -1538,13 +1550,13 @@ str_contains(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
// Step 8
|
||||
// Step 11
|
||||
uint32_t textLen = str->length();
|
||||
|
||||
// Step 9
|
||||
// Step 12
|
||||
uint32_t start = Min(Max(pos, 0U), textLen);
|
||||
|
||||
// Steps 10 and 11
|
||||
// Steps 13 and 14
|
||||
JSLinearString* text = str->ensureLinear(cx);
|
||||
if (!text)
|
||||
return false;
|
||||
|
@ -1720,7 +1732,7 @@ HasSubstringAt(JSLinearString* text, JSLinearString* pat, size_t start)
|
|||
return EqualChars(pat->latin1Chars(nogc), textChars, patLen);
|
||||
}
|
||||
|
||||
/* ES6 20131108 draft 21.1.3.18. */
|
||||
/* ES6 draft rc3 21.1.3.18. */
|
||||
bool
|
||||
js::str_startsWith(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -1731,19 +1743,24 @@ js::str_startsWith(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (!str)
|
||||
return false;
|
||||
|
||||
// Step 4
|
||||
if (args.get(0).isObject() && IsObjectWithClass(args[0], ESClass_RegExp, cx)) {
|
||||
// Steps 4 and 5
|
||||
bool isRegExp;
|
||||
if (!IsRegExp(cx, args.get(0), &isRegExp))
|
||||
return false;
|
||||
|
||||
// Step 6
|
||||
if (isRegExp) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INVALID_ARG_TYPE,
|
||||
"first", "", "Regular Expression");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 5 and 6
|
||||
// Steps 7 and 8
|
||||
RootedLinearString searchStr(cx, ArgToRootedString(cx, args, 0));
|
||||
if (!searchStr)
|
||||
return false;
|
||||
|
||||
// Steps 7 and 8
|
||||
// Steps 9 and 10
|
||||
uint32_t pos = 0;
|
||||
if (args.hasDefined(1)) {
|
||||
if (args[1].isInt32()) {
|
||||
|
@ -1757,22 +1774,22 @@ js::str_startsWith(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
// Step 9
|
||||
// Step 11
|
||||
uint32_t textLen = str->length();
|
||||
|
||||
// Step 10
|
||||
// Step 12
|
||||
uint32_t start = Min(Max(pos, 0U), textLen);
|
||||
|
||||
// Step 11
|
||||
// Step 13
|
||||
uint32_t searchLen = searchStr->length();
|
||||
|
||||
// Step 12
|
||||
// Step 14
|
||||
if (searchLen + start < searchLen || searchLen + start > textLen) {
|
||||
args.rval().setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Steps 13 and 14
|
||||
// Steps 15 and 16
|
||||
JSLinearString* text = str->ensureLinear(cx);
|
||||
if (!text)
|
||||
return false;
|
||||
|
@ -1781,7 +1798,7 @@ js::str_startsWith(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ES6 20131108 draft 21.1.3.7. */
|
||||
/* ES6 draft rc3 21.1.3.6. */
|
||||
static bool
|
||||
str_endsWith(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -1792,22 +1809,27 @@ str_endsWith(JSContext* cx, unsigned argc, Value* vp)
|
|||
if (!str)
|
||||
return false;
|
||||
|
||||
// Step 4
|
||||
if (args.get(0).isObject() && IsObjectWithClass(args[0], ESClass_RegExp, cx)) {
|
||||
// Steps 4 and 5
|
||||
bool isRegExp;
|
||||
if (!IsRegExp(cx, args.get(0), &isRegExp))
|
||||
return false;
|
||||
|
||||
// Step 6
|
||||
if (isRegExp) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INVALID_ARG_TYPE,
|
||||
"first", "", "Regular Expression");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 5 and 6
|
||||
// Steps 7 and 8
|
||||
RootedLinearString searchStr(cx, ArgToRootedString(cx, args, 0));
|
||||
if (!searchStr)
|
||||
return false;
|
||||
|
||||
// Step 7
|
||||
// Step 9
|
||||
uint32_t textLen = str->length();
|
||||
|
||||
// Steps 8 and 9
|
||||
// Steps 10 and 11
|
||||
uint32_t pos = textLen;
|
||||
if (args.hasDefined(1)) {
|
||||
if (args[1].isInt32()) {
|
||||
|
@ -1821,22 +1843,22 @@ str_endsWith(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
// Step 10
|
||||
// Step 12
|
||||
uint32_t end = Min(Max(pos, 0U), textLen);
|
||||
|
||||
// Step 11
|
||||
// Step 13
|
||||
uint32_t searchLen = searchStr->length();
|
||||
|
||||
// Step 13 (reordered)
|
||||
// Step 15 (reordered)
|
||||
if (searchLen > end) {
|
||||
args.rval().setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 12
|
||||
// Step 14
|
||||
uint32_t start = end - searchLen;
|
||||
|
||||
// Steps 14 and 15
|
||||
// Steps 16 and 17
|
||||
JSLinearString* text = str->ensureLinear(cx);
|
||||
if (!text)
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
var BUGNUMBER = 1054755;
|
||||
var summary = 'String.prototype.{startsWith,endsWith,contains} should call IsRegExp.';
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
for (var method of ["startsWith", "endsWith", "contains"]) {
|
||||
for (var re of [/foo/, new RegExp()]) {
|
||||
assertThrowsInstanceOf(() => "foo"[method](re), TypeError);
|
||||
|
||||
re[Symbol.match] = false;
|
||||
"foo"[method](re);
|
||||
}
|
||||
|
||||
for (var v1 of [true, 1, "bar", [], {}, Symbol.iterator]) {
|
||||
assertThrowsInstanceOf(() => "foo"[method]({ [Symbol.match]: v1 }), TypeError);
|
||||
}
|
||||
|
||||
for (var v2 of [false, 0, undefined, ""]) {
|
||||
"foo"[method]({ [Symbol.match]: v2 });
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
Загрузка…
Ссылка в новой задаче