Reviewers: maoziqing,

Description:
Change cajita.js prepareModule to be more paranoid about what it exposes
to the Cajita programmer. We wish to preserve the invariant that the
module
object exposed to Cajita is transitively immutable.

In the old way, the debugging information on top-level modules was not
being
frozen, and was being copied into the module exposed to Cajita, thus
serving
as a communication channel.

Please review this at http://codereview.appspot.com/115041

Affected files:
  M     src/com/google/caja/cajita.js
  M     tests/com/google/caja/parser/quasiliteral/CajitaRewriterTest.java


Index: tests/com/google/caja/parser/quasiliteral/CajitaRewriterTest.java
===================================================================
--- tests/com/google/caja/parser/quasiliteral/CajitaRewriterTest.java (revision 3698) +++ tests/com/google/caja/parser/quasiliteral/CajitaRewriterTest.java (working copy)
@@ -33,19 +33,23 @@
 import com.google.caja.parser.js.StringLiteral;
 import com.google.caja.parser.js.SyntheticNodes;
 import com.google.caja.parser.js.UncajoledModule;
+import com.google.caja.parser.js.CajoledModule;
 import com.google.caja.plugin.PluginEnvironment;
 import com.google.caja.reporting.MessageLevel;
 import com.google.caja.reporting.MessageType;
 import com.google.caja.reporting.TestBuildInfo;
 import com.google.caja.util.RhinoTestBed;
+import com.google.caja.util.Callback;

 import java.io.IOException;
+import java.io.StringWriter;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
+import java.util.HashMap;

 import junit.framework.AssertionFailedError;

@@ -2405,6 +2409,14 @@
         + "assertEquals(r, 9);");

     rewriteAndExecute(
+        "var m = load('foo/testPrimordials'); "
+        + "assertTrue(m.cajolerName !== undefined);"
+        + "assertTrue(m.cajolerVersion !== undefined);"
+        + "assertTrue(m.cajoledDate !== undefined);"
+        + "assertThrows(function() { m.cajolerName = 'bar'; });"
+        + "assertThrows(function() { m.foo = 'bar'; });");
+
+    rewriteAndExecute(
         "var r = load('foo/b')({x: 6, y: 3}); "
         + "assertEquals(r, 11);");

Index: src/com/google/caja/cajita.js
===================================================================
--- src/com/google/caja/cajita.js       (revision 3698)
+++ src/com/google/caja/cajita.js       (working copy)
@@ -2705,12 +2705,14 @@
       return module.instantiate(___, primFreeze(completeImports));
     }
     theModule.FUNC___ = 'theModule';
-
-    forOwnKeys(module, markFuncFreeze(function(k, v) {
-      if (k != 'instantiate') {
-        setStatic(theModule, k, v);
-      }
-    }));
+
+    // Whitelist certain module properties as visible to Cajita code. These
+    // are all primitive values that do not allow two Cajita entities with
+    // access to the same module object to communicate.
+    setStatic(theModule, 'cajolerName', module.cajolerName);
+    setStatic(theModule, 'cajolerVersion', module.cajolerName);
+    setStatic(theModule, 'cajoledDate', module.cajolerName);
+
     return primFreeze(theModule);
   }



Reply via email to