1 /*
   2  * Copyright (c) 2015 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  * JDK-8098578: Global scope is not accessible with indirect load call
  26  *
  27  * @test
  28  * @run
  29  */
  30 
  31 var obj = { foo: 343 };
  32 var global = this;
  33 var x = 434;
  34 
  35 // indirect load call
  36 var res = load.call(obj, {
  37    name: "t.js",
  38    // global is accessible. All declarations go into
  39    // intermediate inaccessible scope. "this" is global
  40    // User's passed object's properties are accessible
  41    // as variables.
  42    script: "foo -= 300; var bar = x; Assert.assertTrue(bar == 434); function func() {}; this"
  43 })
  44 
  45 // 'this' for the evaluated code is global
  46 Assert.assertTrue(res === global);
  47 
  48 // properties of passed object are accessible in evaluated code
  49 Assert.assertTrue(obj.foo == 43);
  50 
  51 // vars, functions definined in evaluated code don't go into passed object
  52 Assert.assertTrue(typeof obj.bar == "undefined");
  53 Assert.assertTrue(typeof obj.func == "undefined");
  54 
  55 // vars, functions definined in evaluated code don't go leak into global
  56 Assert.assertTrue(typeof bar == "undefined");
  57 Assert.assertTrue(typeof func == "undefined");
  58 Assert.assertTrue(typeof foo == "undefined");
  59 
  60 var res = load.call(undefined, {
  61     name: "t1.js",
  62     // still global is accessible and 'this' is global
  63     script: "Assert.assertTrue(x == 434); this"
  64 });
  65 
  66 // indirect load with 'undefined' this is same as as direct load
  67 // or load on global itself.
  68 Assert.assertTrue(res === global);
  69 
  70 // indirect load with 'undefined' this is same as as direct load
  71 // or load on global itself.
  72 var res = load.call(null, {
  73     name: "t2.js",
  74     // still global is accessible and 'this' is global
  75     script: "Assert.assertTrue(x == 434); this"
  76 });
  77 Assert.assertTrue(res === global);
  78 
  79 // indirect load with mirror object
  80 var mirror = loadWithNewGlobal({
  81     name: "t3.js",
  82     script: "({ foo: 'hello', x: Math.PI })"
  83 });
  84 
  85 var res = load.call(mirror, {
  86     name: "t4.js",
  87     script: "Assert.assertTrue(foo == 'hello'); Assert.assertTrue(x == Math.PI); this"
  88 });
  89 Assert.assertTrue(res === global);
  90 
  91 // indirect load on non-script object, non-mirror results in TypeError
  92 function tryLoad(obj) {
  93     try {
  94         load.call(obj, {
  95             name: "t5.js", script: "this"
  96         });
  97         throw new Error("should thrown TypeError for: " + obj);
  98     } catch (e if TypeError) {}
  99 }
 100 
 101 tryLoad("hello");
 102 tryLoad(Math.E);
 103 tryLoad(true);
 104 tryLoad(false);
 105 
 106 // indirect load of a large script
 107 load.call({}, __DIR__ + "JDK-8098807-payload.js");