зеркало из https://github.com/mozilla/pjs.git
Fixes for bugs #66234 (57572, 57631, 61266, 61766) sr=brendan, r=mccabe,
r=rginda,r=rogerl. Also 60925, 60926 by virtue of being subsumed by above.
This commit is contained in:
Родитель
67f05b57e3
Коммит
52a07b9666
|
@ -99,11 +99,11 @@ MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_TYPEERR, "{0} is not a const
|
|||
MSG_DEF(JSMSG_STACK_OVERFLOW, 24, 1, JSEXN_INTERNALERR, "stack overflow in {0}")
|
||||
MSG_DEF(JSMSG_NOT_EXPORTED, 25, 1, JSEXN_NONE, "{0} is not exported")
|
||||
MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion")
|
||||
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 0, JSEXN_ERR, "target of 'in' operator must be an object")
|
||||
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
|
||||
MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_NONE, "invalid new expression result {0}")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
|
||||
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_ERR, "invalid instanceof operand {0}")
|
||||
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
|
||||
MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
|
||||
MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
|
||||
MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number")
|
||||
|
@ -237,3 +237,4 @@ MSG_DEF(JSMSG_TRAILING_COMMA, 161, 0, JSEXN_SYNTAXERR, "trailing comma i
|
|||
MSG_DEF(JSMSG_UNDEFINED_PROP, 162, 1, JSEXN_TYPEERR, "reference to undefined property {0}")
|
||||
MSG_DEF(JSMSG_USELESS_EXPR, 163, 0, JSEXN_TYPEERR, "useless expression")
|
||||
MSG_DEF(JSMSG_REDECLARED_PARAM, 164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
|
||||
MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
|
||||
|
|
|
@ -1486,13 +1486,18 @@ js_Interpret(JSContext *cx, jsval *result)
|
|||
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
case JSOP_IN:
|
||||
rval = POP_OPND();
|
||||
rval = FETCH_OPND(-1);
|
||||
if (JSVAL_IS_PRIMITIVE(rval)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_IN_NOT_OBJECT);
|
||||
str = js_DecompileValueGenerator(cx, -1, rval, NULL);
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_IN_NOT_OBJECT,
|
||||
JS_GetStringBytes(str));
|
||||
}
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
sp--;
|
||||
obj = JSVAL_TO_OBJECT(rval);
|
||||
FETCH_ELEMENT_ID(-1, id);
|
||||
ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
|
||||
|
|
|
@ -846,35 +846,42 @@ ParseAtom(CompilerState *state)
|
|||
}
|
||||
}
|
||||
if (op == REOP_END) {
|
||||
num = state->parenCount++; /* \1 is numbered 0, etc. */
|
||||
num = state->parenCount++; /* \1 is numbered 0, etc. */
|
||||
op = REOP_LPAREN;
|
||||
state->cp = cp + 1;
|
||||
cp++;
|
||||
}
|
||||
else
|
||||
state->cp = cp + 3;
|
||||
ren2 = ParseRegExp(state);
|
||||
if (!ren2)
|
||||
cp += 3;
|
||||
state->cp = cp;
|
||||
/* Handle empty paren */
|
||||
if (*cp == ')') {
|
||||
ren2 = NewRENode(state, REOP_EMPTY, NULL);
|
||||
}
|
||||
else {
|
||||
ren2 = ParseRegExp(state);
|
||||
if (!ren2)
|
||||
return NULL;
|
||||
cp = state->cp;
|
||||
if (*cp != ')') {
|
||||
js_ReportCompileErrorNumber(state->context, state->tokenStream,
|
||||
NULL,
|
||||
JSREPORT_ERROR,
|
||||
JSMSG_MISSING_PAREN, ocp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
ren = NewRENode(state, op, ren2);
|
||||
if (!ren)
|
||||
return NULL;
|
||||
cp = state->cp;
|
||||
if (*cp != ')') {
|
||||
js_ReportCompileErrorNumber(state->context, state->tokenStream,
|
||||
NULL,
|
||||
JSREPORT_ERROR,
|
||||
JSMSG_MISSING_PAREN, ocp);
|
||||
return NULL;
|
||||
}
|
||||
cp++;
|
||||
ren = NewRENode(state, op, ren2);
|
||||
if (!ren)
|
||||
return NULL;
|
||||
ren->flags = ren2->flags & (RENODE_ANCHORED | RENODE_NONEMPTY);
|
||||
ren->u.num = num;
|
||||
ren->flags = ren2->flags & (RENODE_ANCHORED | RENODE_NONEMPTY);
|
||||
ren->u.num = num;
|
||||
if ((op == REOP_LPAREN) || (op == REOP_LPARENNON)) {
|
||||
/* Assume RPAREN ops immediately succeed LPAREN ops */
|
||||
ren2 = NewRENode(state, (REOp)(op + 1), NULL);
|
||||
if (!ren2 || !SetNext(state, ren, ren2))
|
||||
return NULL;
|
||||
ren2->u.num = num;
|
||||
ren2 = NewRENode(state, (REOp)(op + 1), NULL);
|
||||
if (!ren2 || !SetNext(state, ren, ren2))
|
||||
return NULL;
|
||||
ren2->u.num = num;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1112,6 +1119,7 @@ nothex:
|
|||
break;
|
||||
|
||||
default:
|
||||
|
||||
do_flat:
|
||||
while ((c = *++cp) && (cp != state->cpend) && !js_strchr(metachars, c))
|
||||
;
|
||||
|
@ -1872,7 +1880,6 @@ static const jschar *matchRENodes(MatchState *state, RENode *ren, RENode *stop,
|
|||
for (cp2 = cp; cp2 < cpend; cp2++)
|
||||
if (*cp2 == '\n')
|
||||
break;
|
||||
if (cp2 == cp) return NULL;
|
||||
while (cp2 >= cp) {
|
||||
const jschar *cp3 = matchRENodes(state, ren->next, NULL, cp2);
|
||||
if (cp3 != NULL) {
|
||||
|
@ -2588,6 +2595,7 @@ regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
JSString *opt, *str;
|
||||
JSRegExp *oldre, *re;
|
||||
JSBool ok;
|
||||
JSObject *obj2;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
|
||||
return JS_FALSE;
|
||||
|
@ -2601,22 +2609,52 @@ regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
goto out;
|
||||
}
|
||||
} else {
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (JSVAL_IS_OBJECT(argv[0])) {
|
||||
obj2 = JSVAL_TO_OBJECT(argv[0]);
|
||||
/*
|
||||
* If we get passed in a RegExp object we construct a new
|
||||
* RegExp that is a duplicate of it by re-compiling the
|
||||
* original source code. ECMA requires that it be an error
|
||||
* here if the flags are specified. (We must use the flags
|
||||
* from the original RegExp also).
|
||||
*/
|
||||
if (obj2 && OBJ_GET_CLASS(cx, obj2) == &js_RegExpClass) {
|
||||
if (argc >= 2 && !JSVAL_IS_VOID(argv[1])) { /* 'flags' defined */
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NEWREGEXP_FLAGGED);
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
re = (JSRegExp*) JS_GetPrivate(cx, obj2);
|
||||
if (!re) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
re = js_NewRegExp(cx, NULL, re->source, re->flags, JS_FALSE);
|
||||
goto madeit;
|
||||
}
|
||||
}
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (!str) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
argv[0] = STRING_TO_JSVAL(str);
|
||||
if (argc > 1) {
|
||||
opt = js_ValueToString(cx, argv[1]);
|
||||
if (!opt) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
argv[1] = STRING_TO_JSVAL(opt);
|
||||
}
|
||||
if (argc > 1) {
|
||||
if (JSVAL_IS_VOID(argv[1]))
|
||||
opt = NULL;
|
||||
else {
|
||||
opt = js_ValueToString(cx, argv[1]);
|
||||
if (!opt) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
argv[1] = STRING_TO_JSVAL(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE);
|
||||
madeit:
|
||||
if (!re) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
|
@ -2713,8 +2751,19 @@ static JSFunctionSpec regexp_methods[] = {
|
|||
static JSBool
|
||||
RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
/* If not constructing, replace obj with a new RegExp object. */
|
||||
if (!cx->fp->constructing) {
|
||||
/*
|
||||
* If first arg is regexp and no flags are given, just return the arg.
|
||||
* (regexp_compile detects the regexp + flags case and throws a
|
||||
* TypeError.) See 10.15.3.1.
|
||||
*/
|
||||
if ((argc < 2 || JSVAL_IS_VOID(argv[1])) && JSVAL_IS_OBJECT(argv[0]) &&
|
||||
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0])) == &js_RegExpClass) {
|
||||
*rval = argv[0];
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Otherwise, replace obj with a new RegExp object. */
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
|
|
@ -515,7 +515,7 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts,
|
|||
|
||||
js_AddRoot(cx, &linestr, "error line buffer");
|
||||
|
||||
JS_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
|
||||
JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
|
||||
onError = cx->errorReporter;
|
||||
if (onError) {
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче