- Don't cast malloc's return value, it's void *.

- Don't double-report a scanner error such as illegal character in
  Function("a@b", "return a*b")
- Do report a "malformed formal parameter" error in
  Function("a,b,", "return a*b")
- Fiddle comments to more precisely rule out the above bugs.
This commit is contained in:
brendan%netscape.com 1998-09-09 09:27:56 +00:00
Родитель 772e4db56c
Коммит 1cf65e15ec
1 изменённых файлов: 51 добавлений и 43 удалений

Просмотреть файл

@ -1437,9 +1437,11 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
* Allocate a string to hold the concatenated arguments, including room * Allocate a string to hold the concatenated arguments, including room
* for a terminating 0. * for a terminating 0.
*/ */
cp = collected_args = (jschar *) JS_malloc(cx, (args_length + 1) * cp = collected_args = JS_malloc(cx, (args_length + 1) * sizeof(jschar));
sizeof(jschar));
/* Concatenate the arguments into the new string, separated by commas. */ /*
* Concatenate the arguments into the new string, separated by commas.
*/
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
arg = JSVAL_TO_STRING(argv[i]); arg = JSVAL_TO_STRING(argv[i]);
(void)js_strncpy(cp, arg->chars, arg->length); (void)js_strncpy(cp, arg->chars, arg->length);
@ -1448,27 +1450,27 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
*(cp++) = (i + 1 < n) ? ',' : 0; *(cp++) = (i + 1 < n) ? ',' : 0;
} }
/* Make a tokenstream that reads from the given string. */ /*
ts = js_NewTokenStream(cx, collected_args, args_length, filename, lineno, * Make a tokenstream that reads from the given string.
principals); */
ts = js_NewTokenStream(cx, collected_args, args_length, filename,
lineno, principals);
if (!ts) { if (!ts) {
JS_free(cx, collected_args); JS_free(cx, collected_args);
return JS_FALSE; return JS_FALSE;
} }
tt = js_GetToken(cx, ts);
/* The argument string may be empty or contain no tokens. */ /* The argument string may be empty or contain no tokens. */
tt = js_GetToken(cx, ts);
if (tt != TOK_EOF) { if (tt != TOK_EOF) {
while (1) { while (1) {
/* /*
* Check that it's a name. This also implicitly guards against * Check that it's a name. This also implicitly guards against
* TOK_ERROR. * TOK_ERROR, which was already reported.
*/ */
if (tt != TOK_NAME) { if (tt != TOK_NAME)
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, goto bad_formal;
JSMSG_NO_FORMAL);
goto badargs;
}
/* /*
* Get the atom corresponding to the name from the tokenstream; * Get the atom corresponding to the name from the tokenstream;
* we're assured at this point that it's a valid identifier. * we're assured at this point that it's a valid identifier.
@ -1476,32 +1478,32 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
atom = ts->token.t_atom; atom = ts->token.t_atom;
if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2, if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2,
(JSProperty **)&sprop)) { (JSProperty **)&sprop)) {
goto badargs; goto bad_formal;
} }
if (sprop && obj2 == obj) { if (sprop && obj2 == obj) {
#ifdef CHECK_ARGUMENT_HIDING #ifdef CHECK_ARGUMENT_HIDING
PR_ASSERT(sprop->getter == js_GetArgument); PR_ASSERT(sprop->getter == js_GetArgument);
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
JS_ReportErrorNumber(cx, JSREPORT_WARNING, JS_ReportErrorNumber(cx, JSREPORT_WARNING,
JSMSG_SAME_FORMAL, ATOM_BYTES(atom)); JSMSG_SAME_FORMAL, ATOM_BYTES(atom));
goto badargs; goto bad_formal;
#else #else
/* /*
* A duplicate parameter name. We create a dummy symbol * A duplicate parameter name. We create a dummy symbol
* entry with property id of the parameter number and set * entry with property id of the parameter number and set
* the id to the name of the parameter. * the id to the name of the parameter. See jsopcode.c:
* The decompiler will know to treat this case specially. * the decompiler knows to treat this case specially.
*/ */
jsid oldArgId = (jsid) sprop->id; jsid oldArgId = (jsid) sprop->id;
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
sprop = NULL; sprop = NULL;
if (!js_DefineProperty(cx, obj, oldArgId, JSVAL_VOID, if (!js_DefineProperty(cx, obj, oldArgId, JSVAL_VOID,
js_GetArgument, js_SetArgument, js_GetArgument, js_SetArgument,
JSPROP_ENUMERATE | JSPROP_PERMANENT, JSPROP_ENUMERATE | JSPROP_PERMANENT,
(JSProperty **)&sprop)) { (JSProperty **)&sprop)) {
goto badargs; goto bad_formal;
} }
sprop->id = (jsid) atom; sprop->id = (jsid) atom;
#endif #endif
} }
if (sprop) if (sprop)
@ -1510,26 +1512,25 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
js_GetArgument, js_SetArgument, js_GetArgument, js_SetArgument,
JSPROP_ENUMERATE | JSPROP_PERMANENT, JSPROP_ENUMERATE | JSPROP_PERMANENT,
(JSProperty **)&sprop)) { (JSProperty **)&sprop)) {
goto badargs; goto bad_formal;
} }
PR_ASSERT(sprop); PR_ASSERT(sprop);
sprop->id = INT_TO_JSVAL(fun->nargs++); sprop->id = INT_TO_JSVAL(fun->nargs++);
OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
/* Done with the NAME; get the next token. */ /*
* Get the next token. Stop on end of stream. Otherwise
* insist on a comma, get another name, and iterate.
*/
tt = js_GetToken(cx, ts); tt = js_GetToken(cx, ts);
/* Stop if we've reached the end of the string. */
if (tt == TOK_EOF) if (tt == TOK_EOF)
break; break;
if (tt != TOK_COMMA)
/* goto bad_formal;
* If a comma is seen, get the next token. Otherwise, let the tt = js_GetToken(cx, ts);
* loop catch the error.
*/
if (tt == TOK_COMMA)
tt = js_GetToken(cx, ts);
} }
} }
/* Clean up. */ /* Clean up. */
JS_free(cx, collected_args); JS_free(cx, collected_args);
if (!js_CloseTokenStream(cx, ts)) if (!js_CloseTokenStream(cx, ts))
@ -1565,7 +1566,14 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return js_ParseFunctionBody(cx, ts, fun) && return js_ParseFunctionBody(cx, ts, fun) &&
js_CloseTokenStream(cx, ts); js_CloseTokenStream(cx, ts);
badargs: bad_formal:
/*
* Report "malformed formal parameter" iff no illegal char or similar
* scanner error was already reported.
*/
if (!(ts->flags & TSF_ERROR))
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_FORMAL);
/* /*
* Clean up the arguments string and tokenstream if we failed to parse * Clean up the arguments string and tokenstream if we failed to parse
* the arguments. * the arguments.