Browse Source

Throw stmt fixes: reject empty val, NL before val

Duktape 0.11.0 would allow an empty throw (e.g. "throw;") and would
also allow automatic semicolon insertion between "throw" and its
argument, e.g.::

    throw
    123;

The above must be rejected with a SyntaxError according to E5.1.

Both empty throw and the above newline case are rejected by V8 and
Rhino, so the previous more lenient behavior should not conflict
with real world code.
v1.0-maintenance
Sami Vaarala 10 years ago
parent
commit
a5eea1d060
  1. 16
      src/duk_js_compiler.c
  2. 1
      src/duk_strings.c
  3. 2
      src/duk_strings.h

16
src/duk_js_compiler.c

@ -5429,19 +5429,13 @@ static void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
duk__advance(comp_ctx); /* eat 'throw' */ duk__advance(comp_ctx); /* eat 'throw' */
if (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || /* explicit semi follows */ /* Unlike break/continue, throw statement does not allow an empty value. */
comp_ctx->curr_token.lineterm || /* automatic semi will be inserted */
comp_ctx->curr_token.allow_auto_semi) { /* automatic semi will be inserted */ if (comp_ctx->curr_token.lineterm) {
DUK_DDD(DUK_DDDPRINT("empty throw value -> undefined")); DUK_ERROR(comp_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_INVALID_THROW);
reg_val = DUK__ALLOCTEMP(comp_ctx);
duk__emit_extraop_bc(comp_ctx,
DUK_EXTRAOP_LDUNDEF,
(duk_regconst_t) reg_val);
} else {
DUK_DDD(DUK_DDDPRINT("throw with a value"));
reg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);
} }
reg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);
duk__emit_extraop_b_c(comp_ctx, duk__emit_extraop_b_c(comp_ctx,
DUK_EXTRAOP_THROW, DUK_EXTRAOP_THROW,
(duk_regconst_t) reg_val, (duk_regconst_t) reg_val,

1
src/duk_strings.c

@ -84,6 +84,7 @@ const char *duk_str_invalid_switch = "invalid switch statement";
const char *duk_str_invalid_break_cont_label = "invalid break/continue label"; const char *duk_str_invalid_break_cont_label = "invalid break/continue label";
const char *duk_str_invalid_return = "invalid return"; const char *duk_str_invalid_return = "invalid return";
const char *duk_str_invalid_try = "invalid try"; const char *duk_str_invalid_try = "invalid try";
const char *duk_str_invalid_throw = "invalid throw";
const char *duk_str_with_in_strict_mode = "with in strict mode"; const char *duk_str_with_in_strict_mode = "with in strict mode";
const char *duk_str_func_stmt_not_allowed = "function statement not allowed"; const char *duk_str_func_stmt_not_allowed = "function statement not allowed";
const char *duk_str_unterminated_stmt = "unterminated statement"; const char *duk_str_unterminated_stmt = "unterminated statement";

2
src/duk_strings.h

@ -151,6 +151,7 @@ extern const char *duk_str_property_is_virtual;
#define DUK_STR_INVALID_BREAK_CONT_LABEL duk_str_invalid_break_cont_label #define DUK_STR_INVALID_BREAK_CONT_LABEL duk_str_invalid_break_cont_label
#define DUK_STR_INVALID_RETURN duk_str_invalid_return #define DUK_STR_INVALID_RETURN duk_str_invalid_return
#define DUK_STR_INVALID_TRY duk_str_invalid_try #define DUK_STR_INVALID_TRY duk_str_invalid_try
#define DUK_STR_INVALID_THROW duk_str_invalid_throw
#define DUK_STR_WITH_IN_STRICT_MODE duk_str_with_in_strict_mode #define DUK_STR_WITH_IN_STRICT_MODE duk_str_with_in_strict_mode
#define DUK_STR_FUNC_STMT_NOT_ALLOWED duk_str_func_stmt_not_allowed #define DUK_STR_FUNC_STMT_NOT_ALLOWED duk_str_func_stmt_not_allowed
#define DUK_STR_UNTERMINATED_STMT duk_str_unterminated_stmt #define DUK_STR_UNTERMINATED_STMT duk_str_unterminated_stmt
@ -175,6 +176,7 @@ extern const char *duk_str_invalid_switch;
extern const char *duk_str_invalid_break_cont_label; extern const char *duk_str_invalid_break_cont_label;
extern const char *duk_str_invalid_return; extern const char *duk_str_invalid_return;
extern const char *duk_str_invalid_try; extern const char *duk_str_invalid_try;
extern const char *duk_str_invalid_throw;
extern const char *duk_str_with_in_strict_mode; extern const char *duk_str_with_in_strict_mode;
extern const char *duk_str_func_stmt_not_allowed; extern const char *duk_str_func_stmt_not_allowed;
extern const char *duk_str_unterminated_stmt; extern const char *duk_str_unterminated_stmt;

Loading…
Cancel
Save