1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * NASHORN-207 : Implement strict mode.
  26  *
  27  * @test
  28  * @run
  29  */
  30 
  31 // make sure that 'use strict' as first directive inside eval
  32 // also works the same way (as eval called from strict mode caller).
  33 
  34 try {
  35     eval("'use strict'; foo = 4;");
  36     fail("#1 should have thrown ReferenceError");
  37 } catch (e) {
  38     if (! (e instanceof ReferenceError)) {
  39         fail("#2 expected ReferenceError but got " + e);
  40     }
  41 }
  42 
  43 if (typeof foo !== 'undefined') {
  44     fail("#3 strict mode eval defined var in global scope!");
  45 }
  46 
  47 try {
  48     eval("'use strict'; var let = 23;");
  49     fail("#4 should have thrown SyntaxError");
  50 } catch (e) {
  51     if (! (e instanceof SyntaxError)) {
  52         fail("#5 SyntaxError expected but got " + e);
  53     }
  54 }
  55 
  56 // non-strict mode, some of the future reserved words can be used
  57 // as identifiers. These include "let", "implements", "yield" etc.
  58 var let = 30;
  59 var implements = "hello";
  60 function yield() {}
  61 function public() {}
  62 var private = false;
  63 var protected = "hello";
  64 var interface = "interface";
  65 function f(package) {}
  66 function static() {}
  67 
  68 // in strict mode, arguments does not alias named access
  69 function func(x, y) {
  70     'use strict';
  71 
  72     if (x !== arguments[0]) {
  73         fail("#6 arguments[0] !== x");
  74     }
  75 
  76     if (y !== arguments[1]) {
  77         fail("#7 arguments[1] !== y");
  78     }
  79 
  80     arguments[0] = 1;
  81     arguments[1] = 2;
  82 
  83     if (x === arguments[0]) {
  84         fail("#8 arguments[0] === x after assignment to it");
  85     }
  86 
  87     if (y === arguments[1]) {
  88         fail("#9 arguments[1] === y after assignment to it ");
  89     }
  90 }
  91 
  92 func();
  93 
  94 // functions can not be declared everywhere!!
  95 try {
  96     eval("'use strict'; if (true) { function func() {} }");
  97     fail("#10 should have thrown SyntaxError");
  98 } catch (e) {
  99     if (! (e instanceof SyntaxError)) {
 100         fail("#11 SyntaxError expected got " + e);
 101     }
 102 }
 103 
 104 // arguments.caller and arguments.callee can't read or written in strict mode
 105 function func2() {
 106     'use strict';
 107 
 108     try {
 109         print(arguments.callee);
 110         fail("#12 arguments.callee should have thrown TypeError");
 111     } catch (e) {
 112         if (! (e instanceof TypeError)) {
 113             fail("#13 TypeError expected, got " + e);
 114         }
 115     }
 116 
 117     try {
 118         print(arguments.caller);
 119         fail("#14 arguments.caller should have thrown TypeError");
 120     } catch (e) {
 121         if (! (e instanceof TypeError)) {
 122             fail("#15 TypeError expected, got " + e);
 123         }
 124     }
 125 
 126     try {
 127         arguments.caller = 10;
 128         fail("#16 arguments.caller assign should have thrown TypeError");
 129     } catch (e) {
 130         if (! (e instanceof TypeError)) {
 131             fail("#17 TypeError expected, got " + e);
 132         }
 133     }
 134 
 135     try {
 136         arguments.callee = true;
 137         fail("#18 arguments.callee assign should have thrown TypeError");
 138     } catch (e) {
 139         if (! (e instanceof TypeError)) {
 140             fail("#19 TypeError expected, got " + e);
 141         }
 142     }
 143 }
 144 
 145 func2();
 146 
 147 // func.caller and func.arguments can't read or written in strict mode
 148 function func3() {
 149     'use strict';
 150 
 151     try {
 152         print(func3.arguments);
 153         fail("#20 func.arguments should have thrown TypeError");
 154     } catch (e) {
 155         if (! (e instanceof TypeError)) {
 156             fail("#21 TypeError expected, got " + e);
 157         }
 158     }
 159 
 160     try {
 161         print(func3.caller);
 162         fail("#22 func3.caller should have thrown TypeError");
 163     } catch (e) {
 164         if (! (e instanceof TypeError)) {
 165             fail("#23 TypeError expected, got " + e);
 166         }
 167     }
 168 
 169     try {
 170         func3.arguments = 10;
 171         fail("#24 func3.arguments assign should have thrown TypeError");
 172     } catch (e) {
 173         if (! (e instanceof TypeError)) {
 174             fail("#25 TypeError expected, got " + e);
 175         }
 176     }
 177 
 178     try {
 179         func3.caller = true;
 180         fail("#26 func3.caller assign should have thrown TypeError");
 181     } catch (e) {
 182         if (! (e instanceof TypeError)) {
 183             fail("#27 TypeError expected, got " + e);
 184         }
 185     }
 186 }
 187 
 188 func3();
 189 
 190 try {
 191     eval("function eval() { 'use strict'; }");
 192     fail("#28 should have thrown SyntaxError");
 193 } catch (e) {
 194     if (! (e instanceof SyntaxError)) {
 195         fail("#29 SyntaxError expected, got " + e);
 196     }
 197 }
 198 
 199 function func4() {
 200   'use \
 201 strict';
 202 
 203     // The use strict directive can't contain line continuation.
 204     // So this is not a strict mode function!!
 205     with({}) {}
 206 }
 207 
 208 func4();
 209 
 210 function func5() {
 211    'use\u2028strict';
 212 
 213     // The use strict directive can't contain unicode whitespace escapes
 214     // So this is not a strict mode function!!
 215     with({}) {}
 216 }
 217 
 218 func5();
 219 
 220 function func6() {
 221    'use\u2029strict';
 222 
 223     // The use strict directive can't contain unicode whitespace escapes
 224     // So this is not a strict mode function!!
 225     with({}) {}
 226 }
 227 
 228 func6();
 229 
 230 try {
 231     eval("'bogus directive'; 'use strict'; eval = 10");
 232     fail("#30 SyntaxError expected from eval");
 233 } catch (e) {
 234     if (! (e instanceof SyntaxError)) {
 235         fail("#31 SyntaxError expected but got " + e);
 236     }
 237 }