ref: d05415b053599b955ab4a4859f19fab2de4c01d1
parent: 44c0e12d62ee9adcc37d7ff603232c29b9d90101
author: Tor Andersson <tor.andersson@artifex.com>
date: Wed Jan 7 19:00:13 EST 2015
strict mode: No redefining 'eval' or 'arguments'.
--- a/jscompile.c
+++ b/jscompile.c
@@ -118,6 +118,12 @@
static void addlocal(JF, js_Ast *ident, int reuse)
{
const char *name = ident->string;
+ if (J->strict) {
+ if (!strcmp(name, "arguments"))
+ jsC_error(J, ident, "redefining 'arguments' is not allowed in strict mode");
+ if (!strcmp(name, "eval"))
+ jsC_error(J, ident, "redefining 'eval' is not allowed in strict mode");
+ }
if (reuse || J->strict) {
unsigned int i;
for (i = 0; i < F->varlen; ++i) {
@@ -177,11 +183,17 @@
emitraw(J, F, addstring(J, F, str));
}
-static void emitlocal(JF, int oploc, int opvar, const char *name)
+static void emitlocal(JF, int oploc, int opvar, js_Ast *ident)
{
int i;
+ if (J->strict && oploc == OP_SETLOCAL) {
+ if (!strcmp(ident->string, "arguments"))
+ jsC_error(J, ident, "'arguments' is read-only in strict mode");
+ if (!strcmp(ident->string, "eval"))
+ jsC_error(J, ident, "'eval' is read-only in strict mode");
+ }
if (F->lightweight) {
- i = findlocal(J, F, name);
+ i = findlocal(J, F, ident->string);
if (i >= 0) {
emit(J, F, oploc);
emitraw(J, F, i);
@@ -188,7 +200,7 @@
return;
}
}
- emitstring(J, F, opvar, name);
+ emitstring(J, F, opvar, ident->string);
}
static int here(JF)
@@ -229,7 +241,7 @@
static void ctypeof(JF, js_Ast *exp)
{
if (exp->type == EXP_IDENTIFIER)
- emitlocal(J, F, OP_GETLOCAL, OP_HASVAR, exp->string);
+ emitlocal(J, F, OP_GETLOCAL, OP_HASVAR, exp);
else
cexp(J, F, exp);
emit(J, F, OP_TYPEOF);
@@ -300,7 +312,7 @@
else if (prop->type == EXP_NUMBER)
emitnumber(J, F, prop->number);
else
- jsC_error(J, prop, "illegal property name in object initializer");
+ jsC_error(J, prop, "invalid property name in object initializer");
if (J->strict)
checkdup(J, F, head, kv);
@@ -342,7 +354,7 @@
switch (lhs->type) {
case EXP_IDENTIFIER:
cexp(J, F, rhs);
- emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->string);
+ emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
break;
case EXP_INDEX:
cexp(J, F, lhs->a);
@@ -367,7 +379,7 @@
if (stm->type == STM_FOR_IN_VAR) {
if (lhs->b)
jsC_error(J, lhs->b, "more than one loop variable in for-in statement");
- emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->a->a->string); /* list(var-init(ident)) */
+ emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->a->a); /* list(var-init(ident)) */
emit(J, F, OP_POP);
return;
}
@@ -374,7 +386,7 @@
switch (lhs->type) {
case EXP_IDENTIFIER:
- emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->string);
+ emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
emit(J, F, OP_POP);
break;
case EXP_INDEX:
@@ -399,7 +411,7 @@
{
switch (lhs->type) {
case EXP_IDENTIFIER:
- emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, lhs->string);
+ emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, lhs);
break;
case EXP_INDEX:
cexp(J, F, lhs->a);
@@ -422,7 +434,7 @@
switch (lhs->type) {
case EXP_IDENTIFIER:
if (postfix) emit(J, F, OP_ROT2);
- emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->string);
+ emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
break;
case EXP_INDEX:
if (postfix) emit(J, F, OP_ROT4);
@@ -453,7 +465,7 @@
case EXP_IDENTIFIER:
if (J->strict)
jsC_error(J, exp, "delete on an unqualified name is not allowed in strict mode");
- emitlocal(J, F, OP_DELLOCAL, OP_DELVAR, exp->string);
+ emitlocal(J, F, OP_DELLOCAL, OP_DELVAR, exp);
break;
case EXP_INDEX:
cexp(J, F, exp->a);
@@ -547,7 +559,7 @@
break;
case EXP_IDENTIFIER:
- emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, exp->string);
+ emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, exp);
break;
case EXP_INDEX:
@@ -852,6 +864,12 @@
L1 = emitjump(J, F, OP_TRY);
{
/* if we get here, we have caught an exception in the try block */
+ if (J->strict) {
+ if (!strcmp(catchvar->string, "arguments"))
+ jsC_error(J, catchvar, "redefining 'arguments' is not allowed in strict mode");
+ if (!strcmp(catchvar->string, "eval"))
+ jsC_error(J, catchvar, "redefining 'eval' is not allowed in strict mode");
+ }
emitstring(J, F, OP_CATCH, catchvar->string);
cstm(J, F, catchstm);
emit(J, F, OP_ENDCATCH);
@@ -876,6 +894,12 @@
emit(J, F, OP_THROW); /* rethrow exception */
}
label(J, F, L2);
+ if (J->strict) {
+ if (!strcmp(catchvar->string, "arguments"))
+ jsC_error(J, catchvar, "redefining 'arguments' is not allowed in strict mode");
+ if (!strcmp(catchvar->string, "eval"))
+ jsC_error(J, catchvar, "redefining 'eval' is not allowed in strict mode");
+ }
emitstring(J, F, OP_CATCH, catchvar->string);
cstm(J, F, catchstm);
emit(J, F, OP_ENDCATCH);
@@ -939,7 +963,7 @@
js_Ast *var = list->a;
if (var->b) {
cexp(J, F, var->b);
- emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, var->a->string);
+ emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, var->a);
emit(J, F, OP_POP);
}
list = list->b;
@@ -1185,7 +1209,7 @@
} else if (!strcmp(node->string, "eval")) {
/* eval may only be used as a direct function call */
if (!node->parent || node->parent->type != EXP_CALL || node->parent->a != node)
- js_evalerror(J, "%s:%d: illegal use of 'eval'", J->filename, node->line);
+ js_evalerror(J, "%s:%d: invalid use of 'eval'", J->filename, node->line);
F->lightweight = 0;
}
}