tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

envChain_frame-evalWithBindings.js (5419B)


      1 // Verify the environment chain for Debugger.Frame described in
      2 // js/src/vm/EnvironmentObject.h.
      3 
      4 const g = newGlobal({ newCompartment: true });
      5 const dbg = Debugger(g);
      6 
      7 dbg.onEnterFrame = frame => {
      8  if (frame.script.displayName !== "target") {
      9    return;
     10  }
     11  dbg.onEnterFrame = () => {};
     12 
     13  const bindings = {
     14    bindings_prop: 50,
     15 
     16    bindings_prop_var: 61,
     17    bindings_prop_lexical: 71,
     18    bindings_prop_unqualified: 81,
     19  };
     20 
     21  const {envs, vars} = JSON.parse(frame.evalWithBindings(`
     22 var qualified = 10;
     23 unqualified = 20;
     24 let lexical = 30;
     25 this.prop = 40;
     26 
     27 var bindings_prop_var = 60;
     28 let bindings_prop_lexical = 70;
     29 bindings_prop_unqualified = 80;
     30 
     31 const vars = {
     32  bindings_prop_var,
     33  bindings_prop_lexical,
     34  bindings_prop_unqualified,
     35 };
     36 
     37 const envs = [];
     38 let env = getInnerMostEnvironmentObject();
     39 while (env) {
     40  envs.push({
     41    type: getEnvironmentObjectType(env) || "*global*",
     42    qualified: !!Object.getOwnPropertyDescriptor(env, "qualified"),
     43    unqualified: !!Object.getOwnPropertyDescriptor(env, "unqualified"),
     44    lexical: !!Object.getOwnPropertyDescriptor(env, "lexical"),
     45    prop: !!Object.getOwnPropertyDescriptor(env, "prop"),
     46    bindings_prop: !!Object.getOwnPropertyDescriptor(env, "bindings_prop"),
     47 
     48    bindings_prop_var: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_var"),
     49    bindings_prop_var_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_var")?.value,
     50    bindings_prop_lexical: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_lexical"),
     51    bindings_prop_lexical_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_lexical")?.value,
     52    bindings_prop_unqualified: !!Object.getOwnPropertyDescriptor(env, "bindings_prop_unqualified"),
     53    bindings_prop_unqualified_value: Object.getOwnPropertyDescriptor(env, "bindings_prop_unqualified")?.value,
     54  });
     55 
     56  env = getEnclosingEnvironmentObject(env);
     57 }
     58 JSON.stringify({envs, vars});
     59 `, bindings).return);
     60 
     61  assertEq(vars.bindings_prop_var, 60,
     62           "qualified var should read the value set by the declaration");
     63  assertEq(vars.bindings_prop_lexical, 70,
     64           "lexical should read the value set by the declaration");
     65  assertEq(vars.bindings_prop_unqualified, 80,
     66           "unqualified name should read the value set by the assignment");
     67 
     68  assertEq(bindings.bindings_prop_var, 61,
     69          "the original bindings property must not be overwritten for var");
     70  assertEq(bindings.bindings_prop_lexical, 71,
     71          "the original bindings property must not be overwritten for lexical");
     72  assertEq(bindings.bindings_prop_unqualified, 81,
     73          "the original bindings property must not be overwritten for unqualified");
     74 
     75  assertEq(envs.length, 4);
     76 
     77  let i = 0, env;
     78 
     79  // NOTE: lexical is optimized and uses frame slot, even if it conflicts with
     80  //       bindings object properties.
     81 
     82  env = envs[i]; i++;
     83  assertEq(env.type, "WithEnvironmentObject");
     84  assertEq(env.qualified, false);
     85  assertEq(env.unqualified, false);
     86  assertEq(env.lexical, false);
     87  assertEq(env.prop, false);
     88  assertEq(env.bindings_prop, true, "bindings property must live in the with env for bindings");
     89 
     90  assertEq(env.bindings_prop_var, true,
     91           "bindings property must live in the with env for bindings");
     92  assertEq(env.bindings_prop_var_value, 60,
     93           "bindings property must be overwritten for var");
     94  assertEq(env.bindings_prop_lexical, true,
     95           "bindings property must live in the with env for bindings");
     96  assertEq(env.bindings_prop_lexical_value, 71,
     97           "bindings property must not be overwritten for lexical");
     98  assertEq(env.bindings_prop_unqualified, true,
     99           "bindings property must live in the with env for bindings");
    100  assertEq(env.bindings_prop_unqualified_value, 80,
    101           "bindings property must be overwritten for unqualified");
    102 
    103  env = envs[i]; i++;
    104  assertEq(env.type, "[DebugProxy] CallObject");
    105  assertEq(env.qualified, true, "qualified var must live in the CallObject");
    106  assertEq(env.unqualified, false);
    107  assertEq(env.lexical, false);
    108  assertEq(env.prop, false);
    109  assertEq(env.bindings_prop, false);
    110 
    111  assertEq(env.bindings_prop_var, true,
    112           "qualified var binding must be created in the CallObject even if it conflicts with the bindings object property");
    113  assertEq(env.bindings_prop_var_value, undefined,
    114           "qualified var value must not be set if it conflicts with the bindings object property");
    115  assertEq(env.bindings_prop_lexical, false);
    116  assertEq(env.bindings_prop_unqualified, false);
    117 
    118  env = envs[i]; i++;
    119  assertEq(env.type, "[DebugProxy] GlobalLexicalEnvironmentObject");
    120  assertEq(env.qualified, false);
    121  assertEq(env.unqualified, false);
    122  assertEq(env.lexical, false);
    123  assertEq(env.prop, false);
    124  assertEq(env.bindings_prop, false);
    125 
    126  assertEq(env.bindings_prop_var, false);
    127  assertEq(env.bindings_prop_lexical, false);
    128  assertEq(env.bindings_prop_unqualified, false);
    129 
    130  env = envs[i]; i++;
    131  assertEq(env.type, "*global*");
    132  assertEq(env.qualified, false);
    133  assertEq(env.unqualified, true, "unqualified name must live in the global");
    134  assertEq(env.lexical, false);
    135  assertEq(env.prop, true, "this property must live in the global");
    136  assertEq(env.bindings_prop, false);
    137 
    138  assertEq(env.bindings_prop_var, false);
    139  assertEq(env.bindings_prop_lexical, false);
    140  assertEq(env.bindings_prop_unqualified, false);
    141 };
    142 
    143 g.eval(`
    144 function target() {
    145 }
    146 target();
    147 `);