Giter Site home page Giter Site logo

googlearchive / caja Goto Github PK

View Code? Open in Web Editor NEW
1.1K 57.0 127.0 654.13 MB

Caja is a tool for safely embedding third party HTML, CSS and JavaScript in your website.

License: Apache License 2.0

Shell 0.22% Python 2.51% HTML 18.18% Java 42.52% JavaScript 35.17% CSS 0.51% Perl 0.43% XSLT 0.46%

caja's People

Contributors

adrifelt avatar benlaurie avatar cepm-nate avatar erights avatar felix9 avatar ihab avatar jasvir avatar johnfargo avatar kpreid avatar metaweta avatar mikesamuel avatar mschilder123 avatar slayer95 avatar styfle avatar terjanq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

caja's Issues

switch() is not recognized

Original issue 27 created by andrea.campi on 2008-01-14T14:01:57.000Z:

What steps will reproduce the problem?

Translate:

var foo = 1;

switch (foo) {
case 1: break;
default: break;
}

What is the expected output? What do you see instead?

java.lang.RuntimeException: Unrecognized node: SwitchStmt :

What version of the product are you using? On what operating system?

r359

Please provide any additional information below.

Typo: wrong variable name

Original issue 4 created by erights on 2007-11-11T00:14:24.000Z:

Reported by Sol at:
http://groups.google.com/group/google-caja-discuss/browse_thread/thread/8e75113d0b3e9573
(Thanks). Sol says:

The following code in
http://google-caja.googlecode.com/svn/trunk/src/js/com/google/caja/ca...
is incorrect.
The variable "length" in the for loop is undefined. So indexOf will
always return -1.
I think you meant to use "len" instead.

...
Array.prototype.indexOf = function(specimen) {
    ...
    var len = this.length;
    for (var i = 0; i < length; i += 1) {
        ...

Global constructor names aren't being rewritten as properties of __OUTERS__

Original issue 36 created by metaweta on 2008-01-17T00:11:31.000Z:

What steps will reproduce the problem?
1.
function F() {};
f = new F();

What is the expected output? What do you see instead?

Expected:
{
_OUTERS.F = .simpleFunc(function () {
});
___OUTERS
.f = new (
.asCtor(___OUTERS_.F))();
}

Actual:
{
_OUTERS.F = .simpleFunc(function () {
});
___OUTERS
.f = new (
__.asCtor(F))();
}

Constructors are frozen prematurely

Original issue 11 created by andrea.campi on 2007-12-03T14:36:58.000Z:

(I don't have a detailed description, but I'm still logging this to keep track of the conversation with
MarkM, who has a WIP patch that fixes the issue).

Caja.js unittests should fail on multiple evaluation

Original issue 13 created by mikesamuel on 2007-12-05T04:22:32.000Z:

Jeff Walden reports that
var o =
{
toString: function()
{
if (firstTime)
{
firstTime = false;
return "toString"; // guessing this is readable on functions
}
return "constructor";
}
};
triggered a bug in readPub__ causing it to return the constructor.

We should use a similar trick to define an object

function singleUseFunction(x) {
var called = false;
return function () {
if (called) { throw new Error('Called multiple times'); }
called = true;
return x;
};
}

var o = {
toString: singleUseFunction('x'),
valueOf: singleUseFunction('x')
};

and pass o as a key to readPub et al.

What steps will reproduce the problem?
1.
2.
3.

What is the expected output? What do you see instead?

Please use labels and text to provide additional information.

Parsing of '<' is problematic

Original issue 29 created by andrea.campi on 2008-01-14T18:04:20.000Z:

What steps will reproduce the problem?

Translate:

var Foo = function() {
var arr;
for (var i=0; i<arr.length; i++) {}
};

Or:

var Foo = function() {
if (a<b) {}
};

What is the expected output? What do you see instead?

Translation fails with: ERROR: Unexpected end of input in script%3E

Note that it doesn't fail is a space is inserted after the '<'

What version of the product are you using? On what operating system?

r359

Please provide any additional information below.

Code Review: test_fixes_and_testbed_extension_9_Jan_2008

Original issue 21 created by mikesamuel on 2008-01-09T10:24:53.000Z:

Mike, can you review the testbed stuff: env.js, TestUtil.java, console-stubs.js

Ihab, can you review all the Scope and Quasiliteral related stuff?

This fixes a number of currently failing bugs.
Specifically, all the ones that failed because
ExpressionSanitizerCaja was trying to cajole top-level catch
block's exception variable to an assignment now work.

I also extended the Rhino test environment by adding John
Resig's env.js which provides functioning Rhino implementations
of the window.location, the DOM, XMLHttpRequest, setTimeout,
and setInterval. The DOM implementation will only work on
valid XHTML, styles don't work, and script tags will not
be executed, but it's a lot better than what we have now.

Two tests still fail:

  • DefaultRewriterTest.clickMe
    "Method in non-method context: FunctionConstructor"
  • HtmlCompiledPluginTest.testVirtualGlobalThis
    "<script>x=this;</script>"
    fails to execute because we don't allow reference to
    this in the global scope refer to the global scope.
    We could add var t___ = _OUTERS_;
    to the closure passed to loadModule, but that is out
    of the scope of this change.

Fix scoping of try blocks, and rewriting of exception vars

Added isException(varName) method to Scope.

Modified Scope to introduce a pseudo-scope for catch blocks
exception variables and changed the scope visitor to add
messages about masked and redefined variables to a MessageQueue
instead of issuing RuntimeExceptions.

Modified AbstractRewriter and DefaultRewriter to recognize
scopes added by catch blocks.
MARK & IHAB: This required modifying one rule and adding
another rule.

Added ScopeTest to AllTests.

Replace browser-stubs.js with John Resig's env.js

Added env.js to third_party/js/... and deleted browser-stubs.js

Fixed bug in env.js.
Filed at http://code.google.com/p/jqueryjs/issues/detail?id=18

Since env.js requires setting window.location in order to create
a document, I added support for content: URLs to TestUtil. When
env.js detects a change to document.location it creates an
XMLHttpRequest handler which uses java.net.URL to load the
content. This prevents java.net.URL from fetching http(s) URLs
which would bork unittests, and adds a handler for content: URLS.

Moved the parts of browser-stubs.js that weren't DOM related
into console-stubs.js and fleshed them out. console-stubs.js
now contains a stub of the Firebug plugin which will allow us
to get logging and tracing from JS apps.

Adding a method is translated incorrectly

Original issue 12 created by andrea.campi on 2007-12-03T14:39:39.000Z:

Example:

function Point(x, y) {
this.x_ = x;
};
Point.prototype.toString = function() {
return "<" + this.getX() + "," + this.getY() + ">";
};

From MarkM:

the relevant rule from expand.emaker is

       match js`@fname.prototype.@p = @m` ?
             (fname.isFuncName() &amp;&amp;
              `$p` !~ `constructor`)       { def m2 :=

expandMember(fname, m, scope)

js___.setMember($fname, ${$p}, $m2)
}

As you see, for this case, you should be calling setMember by itself
rather than readPub+setPub. The full translation of Andrea's example,
ignoring the fast-path stuff for brevity, should be

var Point = ___.ctor(function(x,y) {
___.setProp(this,'_x',x);
});

_.setMember(Point,'toString',_.method(Point,function() {
return "<" + ___.callProp(this,'getX',[]) + ',' +
___.callProp(this,'getY',[]) + '>';
}));

caja.def unrecognized

Original issue 35 created by metaweta on 2008-01-17T00:01:16.000Z:

What steps will reproduce the problem?
1.
function F(x) { this.x_ = x; }
caja.def(F, Object, {});

What is the expected output? What do you see instead?

I expect the cajoler to recognize the special form caja.def(derived, base,
methods). Instead I get

Constructors are not first class: Rule "varBadCtorLeak", Reference
Identifier : F

MultiDeclarations don't cajole

Original issue 33 created by mikesamuel on 2008-01-15T05:41:04.000Z:

Both of the following statements fail to cajole
var a, b;
for (var i = 0, j = 10; i < j; ++i, --j);

with
Exception in thread "main" java.lang.RuntimeException:
Unrecognized node: MultiDeclaration
at ...AbstractRewriter.expand(AbstractRewriter.java:135)
...

Code Review : calendar-demo-rrules-22-Jan-2008

Original issue 44 created by mikesamuel on 2008-01-23T05:08:35.000Z:

The second part of the calendar demo app.

See package.html for a description of the overall purpose of the demo.

Most of this is a JS port of code.google.com/p/google-rfc-2445 which
is Apache licensed.

I made a few changes to RhinoTestBed to allow me to write my unittests
in an html file which can be executed in a browser, but also easily
executed in Rhino in the regular test engine.

Code Review html-sanitizer-fixes-18-Jan-2007

Original issue 42 created by mikesamuel on 2008-01-21T05:28:15.000Z:

*mikesamuel/html-sanitizer-fixes-18-Jan-2007@415 | mikesamuel | 2008-01-18
15:57:36 -0800 (Fri, 18 Jan 2008)

Description:

Fix bugs in html_sanitizer.js

  • opt_nmTokenXform was not useful because of a type
  • strip things that look like attributes in close tags.
  • escapeAttrib was not escaping > and was over-escaping ampersands

Added a JUnit wrapper for the JSUnit tests.

Added testcases for the nmtoken xforms, and for non-string inputs..

Affected Paths:
M //trunk/src/build.xml
M //trunk/src/java/com/google/caja/plugin/html-sanitizer.js
M //trunk/src/javatests/com/google/caja/AllTests.java
A //trunk/src/javatests/com/google/caja/plugin/HtmlSanitizerTest.java
M //trunk/src/javatests/com/google/caja/plugin/html-sanitizer-test.js

Index: build.xml
===================================================================
--- build.xml   (revision 411)
+++ build.xml   (working copy)
@@ -46,7 +46,6 @@
   &lt;property name=&quot;reports&quot;     location=&quot;ant-reports&quot;/&gt;  &lt;!-- emma reports --&gt;
   &lt;property name=&quot;instr&quot;       location=&quot;ant-instr&quot;/&gt;  &lt;!-- instrumented
src --&gt;
   &lt;property name=&quot;lib&quot;         location=&quot;ant-lib&quot;/&gt;
-  &lt;property name=&quot;testlib&quot;     location=&quot;ant-testlib&quot;/&gt;
   &lt;property name=&quot;docs&quot;        location=&quot;ant-docs&quot;/&gt;
   &lt;property name=&quot;jars&quot;        location=&quot;ant-jars&quot;/&gt;
   &lt;property name=&quot;www&quot;         location=&quot;ant-www&quot;/&gt;  &lt;!-- demo files dir --&gt;
@@ -106,7 +105,6 @@
     &lt;delete dir=&quot;${instr}&quot;/&gt;
     &lt;delete dir=&quot;${jars}&quot;/&gt;
     &lt;delete dir=&quot;${lib}&quot;/&gt;
-    &lt;delete dir=&quot;${testlib}&quot;/&gt;
     &lt;delete dir=&quot;${www}&quot;/&gt;
   &lt;/target&gt;

@@ -116,7 +114,6 @@
     &lt;mkdir dir=&quot;${instr}&quot;/&gt;
     &lt;mkdir dir=&quot;${jars}&quot;/&gt;
     &lt;mkdir dir=&quot;${lib}&quot;/&gt;
-    &lt;mkdir dir=&quot;${testlib}&quot;/&gt;
     &lt;mkdir dir=&quot;${www}&quot;/&gt;
   &lt;/target&gt;

@@ -141,7 +138,7 @@
       &lt;batchtest todir=&quot;${reports}&quot;&gt;
         &lt;fileset dir=&quot;${testsrc}&quot;&gt;
           &lt;include name=&quot;**/*Test.java&quot;/&gt;
-       &lt;/fileset&gt;
+        &lt;/fileset&gt;
       &lt;/batchtest&gt;
       &lt;sysproperty key=&quot;emma.coverage.out.file&quot;
value=&quot;${reports}/coverage.ec&quot;/&gt;
       &lt;sysproperty key=&quot;emma.coverage.out.merge&quot; value=&quot;false&quot;/&gt;
@@ -210,6 +207,7 @@
       &lt;include name=&quot;**/caja/plugin/GxpCompilerTest.java&quot;/&gt;
       &lt;include name=&quot;**/caja/plugin/GxpValidatorTest.java&quot;/&gt;
       &lt;include name=&quot;**/caja/plugin/HtmlCompiledPluginTest.java&quot;/&gt;
+      &lt;include name=&quot;**/caja/plugin/HtmlSanitizerTest.java&quot;/&gt;
       &lt;include name=&quot;**/caja/plugin/HtmlWhitelistTest.java&quot;/&gt;
       &lt;include name=&quot;**/caja/plugin/PluginCompilerTest.java&quot;/&gt;
       &lt;include name=&quot;**/caja/plugin/UrlUtilTest.java&quot;/&gt;
@@ -219,6 +217,9 @@
       &lt;!-- compilerarg line=&quot;-Xlint:unchecked&quot;/ --&gt;
     &lt;/javac&gt;
     &lt;copy todir=&quot;${lib}&quot;&gt;
+      &lt;fileset dir=&quot;${src}&quot;&gt;
+        &lt;include name=&quot;**/caja/plugin/html-sanitizer.js&quot;/&gt;
+      &lt;/fileset&gt;
       &lt;fileset dir=&quot;${testsrc}&quot;&gt;
         &lt;include name=&quot;**/caja/lexer/csslexergolden1.txt&quot;/&gt;
         &lt;include name=&quot;**/caja/lexer/csslexerinput1.css&quot;/&gt;
@@ -275,6 +276,7 @@
         &lt;include name=&quot;**/caja/plugin/gxpcompilerinput2.gxp&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/gxpcompilerinput3.gxp&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/gxpcompilerinput4.gxp&quot;/&gt;
+        &lt;include name=&quot;**/caja/plugin/html-sanitizer-test.js&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/plugintest-csstest.golden&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/plugintest-csstest.input&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/plugintest-helloworld.golden&quot;/&gt;
@@ -286,8 +288,6 @@
         &lt;include name=&quot;**/caja/plugin/sanitizerinput1.js&quot;/&gt;
         &lt;include name=&quot;**/caja/plugin/tmp-caja.js&quot;/&gt;
       &lt;/fileset&gt;
-    &lt;/copy&gt;
-    &lt;copy todir=&quot;${lib}&quot;&gt;
       &lt;fileset dir=&quot;${javascript}&quot;&gt;
         &lt;include name=&quot;**/caja/caja.js&quot;/&gt;
       &lt;/fileset&gt;
Index: java/com/google/caja/plugin/html-sanitizer.js
===================================================================
--- java/com/google/caja/plugin/html-sanitizer.js       (revision 411)
+++ java/com/google/caja/plugin/html-sanitizer.js       (working copy)
@@ -375,7 +375,7 @@
   }

   function escapeAttrib(s) {
-    return s.replace(/&amp;/g, '&amp;amp;').replace(/&lt;/g, '&amp;lt;').replace(/&amp;/g,
'&amp;gt;')
+    return s.replace(/&amp;/g, '&amp;amp;').replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g,
'&amp;gt;')
       .replace(/\&quot;/g, '&amp;quot;');
   }

@@ -385,28 +385,29 @@
     var out = [];

     var ignoring = false;
+    var open = false;
     for (var i = 0; i &lt; toks.length; ++i) {
       var tok = toks[i], type = toks[++i];
-      //alert('tok=' + tok + ', type=' + type + ', ignoring=' + ignoring);
       if (TOK_TAG_BEGIN === type) {
         var name = tok.replace(/^[&lt;\/]+/, '').toUpperCase();
         ignoring = !ELEMENTS.hasOwnProperty(name) || (ELEMENTS[name] &amp;
UNSAFE);
+        open = tok.charAt(1) !== '/';
       } else if (TOK_ATTRIB === type &amp;&amp; !ignoring) {
+        if (!open) { continue; }
         var name = tok.match(/\w+/)[0].toUpperCase();
         if (!ATTRIBS.hasOwnProperty(name)) { continue; }
         var flags = ATTRIBS[name];
         if (flags &amp; (SCRIPT_TYPE | STYLE_TYPE)) { continue; }
-        if (flags) {
+        if (flags || /[&lt;&gt;&amp;]/.test(tok)) {
           // apply transforms
           // unescape value, transform it.  skip if null, otherwise reescape.
           var value = unescapedValueForAttrib(tok);
           if (null == value) { continue; }
           if ((flags &amp; URI_TYPE) &amp;&amp; opt_urlXform) {
             value = opt_urlXform(value);
+          } else if ((flags &amp; NMTOKEN_TYPE) &amp;&amp; opt_nmTokenXform) {
+            value = opt_nmTokenXform(value);
           }
-          if ((flags &amp; NMTOKEN_TYPE) &amp;&amp; opt_nmTokenXform) {
-            value = opt_nmTokenXForm(value);
-          }
           if (null == value) { continue; }
           tok = name + '=&quot;' + escapeAttrib(value) + '&quot;';
         }
Index: javatests/com/google/caja/AllTests.java
===================================================================
--- javatests/com/google/caja/AllTests.java     (revision 411)
+++ javatests/com/google/caja/AllTests.java     (working copy)
@@ -42,6 +42,7 @@
 import com.google.caja.plugin.GxpCompilerTest;
 import com.google.caja.plugin.GxpValidatorTest;
 import com.google.caja.plugin.HtmlCompiledPluginTest;
+import com.google.caja.plugin.HtmlSanitizerTest;
 import com.google.caja.plugin.HtmlWhitelistTest;
 import com.google.caja.plugin.PluginCompilerTest;
 import com.google.caja.plugin.UrlUtilTest;
@@ -83,6 +84,7 @@
           GxpValidatorTest.class,
           HtmlCompiledPluginTest.class,
           HtmlLexerTest.class,
+          HtmlSanitizerTest.class,
           HtmlWhitelistTest.class,
           JoinTest.class,
           JsHtmlParserTest.class,
Index: javatests/com/google/caja/plugin/HtmlSanitizerTest.java
===================================================================
--- javatests/com/google/caja/plugin/HtmlSanitizerTest.java     (revision 0)
+++ javatests/com/google/caja/plugin/HtmlSanitizerTest.java     (revision 0)
@@ -0,0 +1,39 @@
+// Copyright (C) 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.caja.plugin;
+
+import com.google.caja.util.RhinoTestBed;
+import com.google.caja.util.TestUtil;
+import java.io.StringReader;
+import junit.framework.TestCase;
+
+/**
+ * JUnit wrapper for html-sanitizer JSUnit unittests.
+ *
+ * @author [email protected]
+ */
+public final class HtmlSanitizerTest extends TestCase {
+  public void testHtmlSanitizer() throws Exception {
+    RhinoTestBed.runJs(
+        null,
+        new RhinoTestBed.Input(getClass(), &quot;html-sanitizer.js&quot;),
+        new RhinoTestBed.Input(getClass(), &quot;asserts.js&quot;),
+        new RhinoTestBed.Input(getClass(), &quot;html-sanitizer-test.js&quot;),
+        new RhinoTestBed.Input(getClass(), &quot;console-stubs.js&quot;),
+        new RhinoTestBed.Input(getClass(), &quot;jsunit.js&quot;),
+        new RhinoTestBed.Input(new StringReader(&quot;jsunitRun()&quot;), getName())
+        );
+  }
+}
Index: javatests/com/google/caja/plugin/html-sanitizer-test.js
===================================================================
--- javatests/com/google/caja/plugin/html-sanitizer-test.js     (revision 411)
+++ javatests/com/google/caja/plugin/html-sanitizer-test.js     (working copy)
@@ -1,3 +1,22 @@
+function nmTokenPrefixer(prefix) {
+  return function (nmTokens) {
+        var names = nmTokens.split(/\s+/);
+        var validNames;
+        for (var i = names.length; --i &gt;= 0;) {
+          // See http://www.w3.org/TR/1998/REC-xml-19980210#NT-NameChar
+          // for the regex below.
+          if (names[i] &amp;&amp; !/[^\-\.0-9:A-Z_a-z]/.test(names[i])) {
+            names[i] = prefix + names[i];
+            validNames = true;
+          } else {
+            names[i] = '';
+          }
+        }
+        return validNames ? names.join(' ') : null;
+      };
+}
+
+
 function testEmpty() { assertEquals('', html_sanitize('')); }

 function testSimpleText() {
@@ -40,3 +59,33 @@
   assertEquals('&lt;b ID=&quot;foo&quot;  &gt;hello &lt;i&gt;world&amp;lt;&lt;/i&gt;&lt;/b&gt;',
                html_sanitize('&lt;b id=&quot;foo&quot; / --&gt;hello &lt;i&gt;world&lt;&lt;/i&gt;&lt;/b&gt;'));
 }
+
+function testIdsAndClassesPrefixed() {
+  assertEquals(
+      '&lt;b ID=&quot;p-foo&quot; CLASS=&quot;p-boo p-bar p-baz&quot;&gt;hello &lt;i&gt;world&amp;lt;&lt;/i&gt;&lt;/b&gt;',
+      html_sanitize(
+          '&lt;b id=&quot;foo&quot; class=&quot;boo bar baz&quot;&gt;hello &lt;i&gt;world&lt;&lt;/i&gt;&lt;/b&gt;',
+          undefined, nmTokenPrefixer('p-')));
+}
+
+function testInvalidIdsAndClassesRemoved() {
+  assertEquals(
+      '&lt;b  CLASS=&quot;p-boo  p-baz&quot;&gt;hello &lt;i &gt;world&amp;lt;&lt;/i&gt;&lt;/b&gt;',
+      html_sanitize(
+          ('&lt;b id=&quot;fo,o&quot; class=&quot;boo bar/bar baz&quot;&gt;'
+           + 'hello &lt;i class=&quot;i*j&quot;&gt;world&lt;&lt;/i&gt;&lt;/b&gt;'),
+          undefined, nmTokenPrefixer('p-')));
+}
+
+function testNonStringInput() {
+  var badHtml = '&lt;b whacky=foo&gt;&lt;script src=badness.js&gt;&lt;/script&gt;bar&lt;/b
id=foo&gt;';
+  assertEquals(
+      '&lt;b &gt;bar&lt;/b &gt;',
+      html_sanitize({ toString: function () { return badHtml; } }));
+}
+
+function testSpecialCharsInAttributes() {
+  assertEquals(
+      '&lt;b TITLE=&quot;a&amp;lt;b &amp;amp;&amp;amp; c&amp;gt;b&quot;&gt;bar&lt;/b&gt;',
+      html_sanitize('&lt;b title=&quot;a&lt;b &amp;&amp; c&gt;b&quot;&gt;bar&lt;/b&gt;'));
+}

Invoking 'new' on an expression causes ClassCastException

Original issue 37 created by ihab.awad on 2008-01-17T00:59:19.000Z:

As of rev 402. Cajoling the expression --

new foo.bar

causes "ClassCastException: Operation". This is because the rule that accepts the "new" operator
assumes the RHS to be a Reference, and bombs out when that's not the case. Should be rewritten to
two separate rules: one that handles "new [Reference]", and one that prints a meaningful error
message saying something like, "Cannot invoke new on the result of an arbitrary expression".

Code review: code-dashboard-initial-20-Jan-2008

Original issue 45 created by mikesamuel on 2008-01-23T22:31:29.000Z:

We'll be getting a continuous build server soon, and this should help us
put together a dashboard showing test and coverage stats, task comments
from code, documentation, and variables useful for profiling.

html_sanitize expects a string

Original issue 40 created by metaweta on 2008-01-18T01:29:13.000Z:

&lt;div id=&quot;output&quot;&gt;Hi&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

var o ={ match: function() {
return new Array(
{
length:0,
toString:function(){
return 'unsanitized control over innerHTML';
}
}
);
},
substring: function() { return ''; }
};
document.getElementById("output").innerHTML= o;
</script>

Error translating constructor invocation

Original issue 8 created by andrea.campi on 2007-12-03T14:27:54.000Z:

From mailing list thread: http://groups.google.com/group/google-caja-
discuss/browse_thread/thread/7bc023f1413f6384/

Translating the following:

function F(x) { this.x_ = x; }
F.make = function(x) {
return new F(x);
};

produces:

{
.loadModule(function (p) {
p.F = .ctor(function (x) {
var t
= this;
t
.x_ = x;
});
(function () {
var x___ = p.F;
return x___.make_canSet___ ? (x___.make = function (x) {
return ___.callNew(p.F, [x]);
}) : .setPub(x, 'make', function (x) {
return ___.callNew(p.F, [x]);
});
})();
return p;
});
}

___.callNew doesn't exist, the body of F.make should be:

      ___.setMember(plugin.F,'make',___.method(plugin.F,function(x) {
        return new (___.asCtor(plugin.F))(x);
      }));

Code Review: mikesamuel/misc_bug_fixes_7_Jan_2008

Original issue 19 created by mikesamuel on 2008-01-08T05:37:38.000Z:

gvn --project https://google-caja.googlecode.com/svn review
mikesamuel/misc_bug_fixes_7_Jan_2008

Fixed various bugs reported by Andrea:

  • HtmlPluginCompilerMain was not writing any output.
    This did not affect gadget rewriting since the problem
    was in the main method.
  • Fixed copyright comments in demo files that were causing
    parse errors.
  • Changed demo build target to use the PluginCompiler, not Ryan's
    HtmlPluginCompiler.
  • Added check to PluginMeta to make sure namespaceName is a valid javascript
    identifier.

Other cleanup:

  • Fixed ordering of arguments for empty output warning.
  • Added checkpointing to HtmlPluginCompilers pipeline.

Code Review use-right-element-stack-18-Jan-2008

Original issue 43 created by mikesamuel on 2008-01-21T05:30:27.000Z:

*mikesamuel/use-right-element-stack-18-Jan-2008@413 | mikesamuel |
2008-01-18 11:54:02 -0800 (Fri, 18 Jan 2008)

Description:

Make sure that all the places where we parse HTML & XML are using the proper
element stack implementation.

Affected Paths:
M //trunk/src/java/com/google/caja/parser/html/DomParser.java
M //trunk/src/java/com/google/caja/plugin/PluginCompiler.java
M //trunk/src/java/com/google/caja/plugin/PluginCompilerMain.java
M //trunk/src/javatests/com/google/caja/lexer/htmllexergolden1.txt
M //trunk/src/javatests/com/google/caja/lexer/htmllexerinput1.html
M //trunk/src/javatests/com/google/caja/parser/html/DomParserTest.java
M //trunk/src/javatests/com/google/caja/plugin/GxpCompilerTest.java
M //trunk/src/javatests/com/google/caja/plugin/GxpValidatorTest.java
M //trunk/src/javatests/com/google/caja/plugin/HtmlCompiledPluginTest.java

Index: java/com/google/caja/parser/html/DomParser.java
===================================================================
--- java/com/google/caja/parser/html/DomParser.java     (revision 411)
+++ java/com/google/caja/parser/html/DomParser.java     (working copy)
@@ -46,12 +46,6 @@
  * @author [email protected]
  */
 public final class DomParser {
-  public static DomTree parseDocument(TokenQueue&lt;HtmlTokenType&gt; tokens)
-      throws ParseException {
-    return parseDocument(
-        tokens, OpenElementStack.Factory.createXmlElementStack());
-  }
-
   public static DomTree parseDocument(
       TokenQueue&lt;HtmlTokenType&gt; tokens, OpenElementStack elementStack)
       throws ParseException {
@@ -80,15 +74,6 @@
   /**
    * Parses a snippet of markup.
    */
-  public static DomTree.Fragment parseFragment(TokenQueue&lt;HtmlTokenType&gt;
tokens)
-      throws ParseException {
-    return parseFragment(
-        tokens, OpenElementStack.Factory.createXmlElementStack());
-  }
-
-  /**
-   * Parses a snippet of markup.
-   */
   public static DomTree.Fragment parseFragment(
       TokenQueue&lt;HtmlTokenType&gt; tokens, OpenElementStack elementStack)
       throws ParseException {
Index: java/com/google/caja/plugin/PluginCompiler.java
===================================================================
--- java/com/google/caja/plugin/PluginCompiler.java     (revision 411)
+++ java/com/google/caja/plugin/PluginCompiler.java     (working copy)
@@ -22,6 +22,7 @@
 import com.google.caja.parser.css.CssTree;
 import com.google.caja.parser.html.DomParser;
 import com.google.caja.parser.html.DomTree;
+import com.google.caja.parser.html.OpenElementStack;
 import com.google.caja.parser.js.*;
 import com.google.caja.plugin.GxpCompiler.BadContentException;
 import com.google.caja.reporting.Message;
@@ -495,7 +496,8 @@
       TokenQueue&lt;HtmlTokenType&gt; tq = new TokenQueue&lt;HtmlTokenType&gt;(
           lexer, node.getFilePosition().source(),
           Criterion.Factory.&lt;Token&lt;HtmlTokenType&gt;&gt;optimist());
-      DomTree doc = DomParser.parseDocument(tq);
+      DomTree doc = DomParser.parseDocument(
+          tq, OpenElementStack.Factory.createXmlElementStack());
       tq.expectEmpty();
       if (!(doc instanceof DomTree.Tag)) {
         throw new ParseException(new Message(
Index: java/com/google/caja/plugin/PluginCompilerMain.java
===================================================================
--- java/com/google/caja/plugin/PluginCompilerMain.java (revision 411)
+++ java/com/google/caja/plugin/PluginCompilerMain.java (working copy)
@@ -32,6 +32,7 @@
 import com.google.caja.parser.css.CssParser;
 import com.google.caja.parser.css.CssTree;
 import com.google.caja.parser.html.DomParser;
+import com.google.caja.parser.html.OpenElementStack;
 import com.google.caja.parser.js.Parser;
 import com.google.caja.parser.js.Statement;
 import com.google.caja.reporting.Message;
@@ -241,7 +242,8 @@
       lexer.setTreatedAsXml(true);
       TokenQueue&lt;HtmlTokenType&gt; tq = new TokenQueue&lt;HtmlTokenType&gt;(
           lexer, is, Criterion.Factory.&lt;Token&lt;HtmlTokenType&gt;&gt;optimist());
-      input = DomParser.parseDocument(tq);
+      input = DomParser.parseDocument(
+          tq, OpenElementStack.Factory.createXmlElementStack());
       tq.expectEmpty();
     } else if (path.endsWith(&quot;.css&quot;)) {
       CssLexer lexer = new CssLexer(cp);
Index: javatests/com/google/caja/lexer/htmllexergolden1.txt
===================================================================
--- javatests/com/google/caja/lexer/htmllexergolden1.txt        (revision 411)
+++ javatests/com/google/caja/lexer/htmllexergolden1.txt        (working copy)
@@ -198,3 +198,9 @@
 TEXT       [\n\n]  :  htmllexerinput1.html:78+8@1834 - 80+1@1836
 DIRECTIVE  [&lt;![CDATA[ No such thing as a CDATA&gt;]  : 
htmllexerinput1.html:80+1@1836 - 36@1871
 TEXT       [ section in HTML ]]&gt;\n]  :  htmllexerinput1.html:80+36@1871 -
81+1@1892
+TAGBEGIN   [&lt;script]  :  htmllexerinput1.html:81+1@1892 - 8@1899
+TAGEND     [&gt;]  :  htmllexerinput1.html:81+8@1899 - 9@1900
+UNESCAPED  [a&lt;b]  :  htmllexerinput1.html:81+9@1900 - 12@1903
+TAGBEGIN   [&lt;/script]  :  htmllexerinput1.html:81+12@1903 - 20@1911
+TAGEND     [&gt;]  :  htmllexerinput1.html:81+20@1911 - 21@1912
+TEXT       [\n]  :  htmllexerinput1.html:81+21@1912 - 82+1@1913
Index: javatests/com/google/caja/lexer/htmllexerinput1.html
===================================================================
--- javatests/com/google/caja/lexer/htmllexerinput1.html        (revision 411)
+++ javatests/com/google/caja/lexer/htmllexerinput1.html        (working copy)
@@ -78,3 +78,4 @@
 &lt;/html&gt;

 &lt;![CDATA[ No such thing as a CDATA&gt; section in HTML ]]&gt;
+&lt;script&gt;a&lt;b&lt;/script&gt;
Index: javatests/com/google/caja/parser/html/DomParserTest.java
===================================================================
--- javatests/com/google/caja/parser/html/DomParserTest.java    (revision 411)
+++ javatests/com/google/caja/parser/html/DomParserTest.java    (working copy)
@@ -94,7 +94,8 @@

   public void testParseDom() throws Exception {
     TokenQueue&lt;HtmlTokenType&gt; tq = tokenizeTestInput(DOM1_XML, true);
-    DomTree t = DomParser.parseDocument(tq);
+    DomTree t = DomParser.parseDocument(
+        tq, OpenElementStack.Factory.createXmlElementStack());
     StringBuilder actual = new StringBuilder();
     t.format(new MessageContext(), actual);
     assertEquals(DOM1_GOLDEN, actual.toString());
Index: javatests/com/google/caja/plugin/GxpCompilerTest.java
===================================================================
--- javatests/com/google/caja/plugin/GxpCompilerTest.java       (revision 411)
+++ javatests/com/google/caja/plugin/GxpCompilerTest.java       (working copy)
@@ -26,6 +26,7 @@
 import com.google.caja.parser.ParseTreeNode;
 import com.google.caja.parser.html.DomParser;
 import com.google.caja.parser.html.DomTree;
+import com.google.caja.parser.html.OpenElementStack;
 import com.google.caja.parser.js.FunctionDeclaration;
 import com.google.caja.reporting.EchoingMessageQueue;
 import com.google.caja.reporting.Message;
@@ -72,7 +73,8 @@
         new PrintWriter(new OutputStreamWriter(System.out)), mc);
     TokenQueue&lt;HtmlTokenType&gt; tq = TestUtil.parseXml(
         getClass(), &quot;gxpcompilerinput1.gxp&quot;, mq);
-    DomTree.Tag domTree = (DomTree.Tag) DomParser.parseDocument(tq);
+    DomTree.Tag domTree = (DomTree.Tag) DomParser.parseDocument(
+        tq, OpenElementStack.Factory.createXmlElementStack());
     GxpCompiler gxpc = new GxpCompiler(mq, makeTestPluginMeta());
     GxpCompiler.TemplateSignature sig =
gxpc.compileTemplateSignature(domTree);
     ParseTreeNode compiled = gxpc.compileDocument(sig);
@@ -94,7 +96,8 @@
         new PrintWriter(new OutputStreamWriter(System.out)), mc);
     TokenQueue&lt;HtmlTokenType&gt; tq = TestUtil.parseXml(
         getClass(), &quot;gxpcompilerinput2.gxp&quot;, mq);
-    DomTree.Tag domTree = (DomTree.Tag) DomParser.parseDocument(tq);
+    DomTree.Tag domTree = (DomTree.Tag) DomParser.parseDocument(
+        tq, OpenElementStack.Factory.createXmlElementStack());
     GxpCompiler gxpc = new GxpCompiler(mq, makeTestPluginMeta());
     GxpCompiler.TemplateSignature sig =
gxpc.compileTemplateSignature(domTree);
     ParseTreeNode compiled = gxpc.compileDocument(sig);
@@ -132,9 +135,11 @@
         new PrintWriter(new OutputStreamWriter(System.out)), mc);

     DomTree.Tag gxp2 = (DomTree.Tag) DomParser.parseDocument(
-        TestUtil.parseXml(getClass(), &quot;gxpcompilerinput3.gxp&quot;, mq));
+        TestUtil.parseXml(getClass(), &quot;gxpcompilerinput3.gxp&quot;, mq),
+        OpenElementStack.Factory.createXmlElementStack());
     DomTree.Tag gxp3 = (DomTree.Tag) DomParser.parseDocument(
-        TestUtil.parseXml(getClass(), &quot;gxpcompilerinput4.gxp&quot;, mq));
+        TestUtil.parseXml(getClass(), &quot;gxpcompilerinput4.gxp&quot;, mq),
+        OpenElementStack.Factory.createXmlElementStack());
     GxpCompiler gxpc = new GxpCompiler(mq, makeTestPluginMeta());
     GxpCompiler.TemplateSignature sig2 = gxpc.compileTemplateSignature(gxp2),
                                   sig3 = gxpc.compileTemplateSignature(gxp3);
@@ -394,7 +399,8 @@
       lexer.setTreatedAsXml(true);
       TokenQueue&lt;HtmlTokenType&gt; tq = new TokenQueue&lt;HtmlTokenType&gt;(
           lexer, is, Criterion.Factory.&lt;Token&lt;HtmlTokenType&gt;&gt;optimist());
-      doms[i] = (DomTree.Tag) DomParser.parseDocument(tq);
+      doms[i] = (DomTree.Tag) DomParser.parseDocument(
+          tq, OpenElementStack.Factory.createXmlElementStack());
       tq.expectEmpty();
     }

@@ -474,7 +480,8 @@
       lexer.setTreatedAsXml(true);
       TokenQueue&lt;HtmlTokenType&gt; tq = new TokenQueue&lt;HtmlTokenType&gt;(
           lexer, is, Criterion.Factory.&lt;Token&lt;HtmlTokenType&gt;&gt;optimist());
-      doms[i] = (DomTree.Tag) DomParser.parseDocument(tq);
+      doms[i] = (DomTree.Tag) DomParser.parseDocument(
+          tq, OpenElementStack.Factory.createXmlElementStack());
       tq.expectEmpty();
     }

Index: javatests/com/google/caja/plugin/GxpValidatorTest.java
===================================================================
--- javatests/com/google/caja/plugin/GxpValidatorTest.java      (revision 411)
+++ javatests/com/google/caja/plugin/GxpValidatorTest.java      (working copy)
@@ -23,6 +23,7 @@
 import com.google.caja.parser.AncestorChain;
 import com.google.caja.parser.html.DomParser;
 import com.google.caja.parser.html.DomTree;
+import com.google.caja.parser.html.OpenElementStack;
 import com.google.caja.reporting.EchoingMessageQueue;
 import com.google.caja.reporting.MessageContext;
 import com.google.caja.reporting.MessageQueue;
@@ -77,7 +78,8 @@
     lexer.setTreatedAsXml(true);
     TokenQueue&lt;HtmlTokenType&gt; tq = new TokenQueue&lt;HtmlTokenType&gt;(
         lexer, is, Criterion.Factory.&lt;Token&lt;HtmlTokenType&gt;&gt;optimist());
-    DomTree t = DomParser.parseDocument(tq);
+    DomTree t = DomParser.parseDocument(
+        tq, OpenElementStack.Factory.createXmlElementStack());
     assertEquals(html, valid,
                  new GxpValidator(mq).validate(new
AncestorChain&lt;DomTree&gt;(t)));
   }
Index: javatests/com/google/caja/plugin/HtmlCompiledPluginTest.java
===================================================================
--- javatests/com/google/caja/plugin/HtmlCompiledPluginTest.java       
(revision 411)
+++ javatests/com/google/caja/plugin/HtmlCompiledPluginTest.java       
(working copy)
@@ -20,6 +20,7 @@
 import com.google.caja.parser.AncestorChain;
 import com.google.caja.parser.html.DomParser;
 import com.google.caja.parser.html.DomTree;
+import com.google.caja.parser.html.OpenElementStack;
 import com.google.caja.parser.js.Block;
 import com.google.caja.reporting.EchoingMessageQueue;
 import com.google.caja.reporting.MessageContext;
@@ -340,7 +341,7 @@
         PluginEnvironment.CLOSED_PLUGIN_ENVIRONMENT);
     HtmlPluginCompiler compiler = new HtmlPluginCompiler(mq, meta);
     compiler.setMessageContext(mc);
-    DomTree html = parseHtml(gadgetSpec);
+    DomTree html = parseHtml(gadgetSpec, mq);
     if (html != null) { compiler.addInput(new AncestorChain&lt;DomTree&gt;(html)); }

     boolean failed = !compiler.run();
@@ -378,12 +379,13 @@
     }
   }

-  DomTree parseHtml(String html) throws Exception {
+  DomTree parseHtml(String html, MessageQueue mq) throws Exception {
     InputSource is
         = new InputSource(new URI(&quot;content&quot;, null, &quot;/&quot; + html, null));
     StringReader in = new StringReader(html);
     TokenQueue&lt;HtmlTokenType&gt; tq = DomParser.makeTokenQueue(is, in, false);
     if (tq.isEmpty()) { return null; }
-    return DomParser.parseFragment(tq);
+    return DomParser.parseFragment(
+        tq, OpenElementStack.Factory.createHtml5ElementStack(mq));
   }
 }

Flash Attributes

Original issue 46 created by sshjason on 2008-01-25T22:20:27.000Z:

The following Flash Attributes need to be added:

allowScriptAccess
allowNetworking

Missing return in translation of member access

Original issue 22 created by andrea.campi on 2008-01-09T14:21:43.000Z:

What steps will reproduce the problem?

Traslate the following code:

var foo = bar.baz;

This will result in:

{
.loadModule(function (o) {
___OUTERS
.foo = (function () {
var x___ = _OUTERS.bar;
x
__.baz_canRead___ ? x___.baz : _.readPub(x_, 'baz');
})();
});
}

What is the expected output? What do you see instead?

Line 5 is missing a return; the expected output is:

{
.loadModule(function (o) {
___OUTERS
.foo = (function () {
var x___ = _OUTERS.bar;
return x
__.baz_canRead___ ? x___.baz : _.readPub(x_, 'baz');
})();
});
}

What version of the product are you using? On what operating system?

trunk as of January 9, r337.

'this' not allowed in methods declared inside caja.freeze

Original issue 30 created by andrea.campi on 2008-01-14T22:04:47.000Z:

What steps will reproduce the problem?

Translate:

function Foo() {
return caja.freeze({
getSelf: function() { return this; }
});
}

What is the expected output? What do you see instead?

FATAL_ERROR: Method in non-method context: Rule "funcBadMethod", FunctionConstructor
Identifier
Block
ReturnStmt
Reference
Identifier : this

This should be equivalent to:

function Foo() {
return caja.freeze({
});
}
Foo.prototype.getSelf = function() { return this; }

What version of the product are you using? On what operating system?

r359

Please provide any additional information below.

JSON arrays cause an error

Original issue 25 created by andrea.campi on 2008-01-10T14:55:44.000Z:

What steps will reproduce the problem?

Try translating either of these:

var foo = [];

var foo = {meta: []};

What is the expected output? What do you see instead?

All I get is:

java.lang.RuntimeException: Unrecognized node: ArrayConstructor

What version of the product are you using? On what operating system?

trunk r337

Code Review: mikesamuel/escaping-text-spans-2-Jan-2007

Original issue 20 created by mikesamuel on 2008-01-08T05:51:23.000Z:

*mikesamuel/escaping-text-spans-2-Jan-2007@317 | mikesamuel | 2008-01-02
15:58:30 -0800 (Wed, 02 Jan 2008)

Description:

Louis ran into a problem whereby a </script> tag in a javascript comment was
causing problems.

This was a valid problem, but the typical solution -- surrounding the script
in <!-- ... --> didn't work either.

This change makes HtmlLexer agree with section 8.1.2.6 of HTML 5
reproduced below. In brief, a CDATA or RCDATA section, except one in
an XMP tag, ends when a matching end tag is seen, unless the end tag
is inside an escaping text span which is delimited by <!-- ... -->.

This will conflict to some degree with changes
mikesamuel/malformed-html-20-DEc-2007 but the merge should be
straightforward, and this change should go in first.

8.1.2.6. Restrictions on the contents of CDATA and RCDATA elements

The text in CDATA and RCDATA elements must not contain any occurences
of the string "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS) followed by
characters that case-insensitively match the tag name of the element
followed by one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF),
U+000B LINE TABULATION, U+000C FORM FEED (FF), U+0020 SPACE, U+003E
GREATER-THAN SIGN (>), or U+002F SOLIDUS (/), unless that string is
part of an escaping text span.

An escaping text span is a span of text (in CDATA and RCDATA elements)
and character entity references (in RCDATA elements) that starts with
an escaping text span start that is not itself in an escaping text
span, and ends at the next escaping text span end.

An escaping text span start is a part of text that consists of the
four character sequence "<!--" (U+003C LESS-THAN SIGN, U+0021
EXCLAMATION MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS).

An escaping text span end is a part of text that consists of the three
character sequence "-->" (U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS,
U+003E GREATER-THAN SIGN) whose U+003E GREATER-THAN SIGN (>).

An escaping text span start may share its U+002D HYPHEN-MINUS
characters with its corresponding escaping text span end.

The text in CDATA and RCDATA elements must not have an escaping text
span start that is not followed by an escaping text span end

Code Review js-regex-lexer-18-Jan-2006

Original issue 41 created by mikesamuel on 2008-01-21T05:24:51.000Z:

*mikesamuel/js-regex-lexer-18-Jan-2006@414 | mikesamuel | 2008-01-18
13:21:18 -000 (Fri, 18 Jan 2008)

Description:

In JS, regular expression literals are not ended by backslashes inside
charactersets.

Affected Paths:
M //trunk/src/java/com/google/caja/lexer/InputElementSplitter.java
M //trunk/src/javatests/com/google/caja/lexer/JsLexerTest.java
M //trunk/src/javatests/com/google/caja/lexer/lexergolden1.txt
M //trunk/src/javatests/com/google/caja/lexer/lexertest1.js

Index: java/com/google/caja/lexer/InputElementSplitter.java
===================================================================
--- java/com/google/caja/lexer/InputElementSplitter.java        (revision 411)
+++ java/com/google/caja/lexer/InputElementSplitter.java        (working copy)
@@ -49,7 +49,8 @@
     this(p, punctuation, false);
   }

-  public InputElementSplitter(CharProducer p, PunctuationTrie punctuation,
boolean isQuasiliteral) {
+  public InputElementSplitter(
+      CharProducer p, PunctuationTrie punctuation, boolean isQuasiliteral) {
     this.p = new LineContinuingCharProducer(p);
     this.punctuation = punctuation;
     this.isQuasiliteral = isQuasiliteral;
@@ -148,21 +149,40 @@
                     || JsLexer.isRegexp(lastNonCommentToken.text)) {
                   boolean closed = false;
                   boolean escaped = false;
+                  boolean inCharSet = false;
+
+                  regex_body:
                   do {
                     text.append((char) ch2);
-                    if (ch2 == '/' &amp;&amp; !escaped) {
-                      closed = true;
+                    if (JsLexer.isJsLineSeparator((char) ch2)) {
+                      // will register as unterminated token below
                       break;
-                    } else if (JsLexer.isJsLineSeparator((char) ch2)) {
-                      break;  // will register as unterminated token below
+                    } else if (!escaped) {
+                      switch (ch2) {
+                        case '/':
+                          if (!inCharSet) {
+                            closed = true;
+                            break regex_body;
+                          }
+                          break;
+                        case '[':
+                          inCharSet = true;
+                          break;
+                        case ']':
+                          inCharSet = false;
+                          break;
+                        case '\\':
+                          escaped = true;
+                          break;
+                      }
+                    } else {
+                      escaped = false;
                     }
-                    escaped = !escaped &amp;&amp; ch2 == '\\';
                   } while ((ch2 = p.read()) &gt;= 0);
                   if (!closed) {
                     throw new ParseException(
                         new Message(MessageType.UNTERMINATED_STRING_TOKEN,
-                            FilePosition.span(
-                                start, p.getCurrentPosition())));
+                            FilePosition.span(start,
p.getCurrentPosition())));
                   }
                   // Pick up any modifiers at the end, e.g. /foo/g
                   // Firefox fails on &quot;/foo/instanceof RegExp&quot; with an
Index: javatests/com/google/caja/lexer/JsLexerTest.java
===================================================================
--- javatests/com/google/caja/lexer/JsLexerTest.java    (revision 411)
+++ javatests/com/google/caja/lexer/JsLexerTest.java    (working copy)
@@ -65,7 +65,6 @@
     }

     assertEquals(golden, output.toString());
-    //fail(golden + &quot;\n\n  !=\n\n&quot; + output);
   }

   public void testLexer2() throws Exception {
@@ -105,8 +104,6 @@
     }

     assertEquals(golden, output.toString());
-    //fail(golden + &quot;\n\n  !=\n\n&quot; + output);
-
   }

   public void testSimpleExpression() {
Index: javatests/com/google/caja/lexer/lexergolden1.txt
===================================================================
--- javatests/com/google/caja/lexer/lexergolden1.txt    (revision 411)
+++ javatests/com/google/caja/lexer/lexergolden1.txt    (working copy)
@@ -128,4 +128,14 @@
 STRI [&quot; */&quot;]: lexertest1.js:57+58@1193 - 58+2@1200
 WORD [also]: lexertest1.js:58+2@1200 - 6@1204
 COMM [/* &quot; /* */]: lexertest1.js:58+7@1205 - 17@1215
-COMM [// leave some whitespace at the end of this file  ]:
lexertest1.js:60+1@1217 - 51@1267
+COMM [// Backslashes in character sets do not end regexs.]:
lexertest1.js:60+1@1217 - 52@1268
+WORD [r]: lexertest1.js:61+1@1269 - 2@1270
+PUNC [=]: lexertest1.js:61+3@1271 - 4@1272
+REGE [/./]: lexertest1.js:61+5@1273 - 8@1276
+PUNC [,]: lexertest1.js:61+8@1276 - 9@1277
+REGE [/\//]: lexertest1.js:61+10@1278 - 14@1282
+PUNC [,]: lexertest1.js:61+14@1282 - 15@1283
+REGE [/[/]/]: lexertest1.js:61+16@1284 - 21@1289
+PUNC [,]: lexertest1.js:61+21@1289 - 22@1290
+REGE [/[\/]\//]: lexertest1.js:61+23@1291 - 31@1299
+COMM [// leave some whitespace at the end of this file  ]:
lexertest1.js:63+1@1301 - 51@1351
Index: javatests/com/google/caja/lexer/lexertest1.js
===================================================================
--- javatests/com/google/caja/lexer/lexertest1.js       (revision 411)
+++ javatests/com/google/caja/lexer/lexertest1.js       (working copy)
@@ -57,4 +57,7 @@
 /* and extending the example at line 30 &quot; interleaved */ &quot; */\
 &quot;also /* &quot; /* */

+// Backslashes in character sets do not end regexs.
+r = /./, /\//, /[/]/, /[\/]\//
+
 // leave some whitespace at the end of this file

Move whitelists out of java into configuration files

Original issue 50 created by mikesamuel on 2008-01-29T01:04:17.000Z:

Background
HtmlWhitelist.java and Css2.java include definitions of HTML tags, HTML
attributes, CSS properties, and CSS functions.

Goal
Allow clients to add items to whitelists. Some clients have prior
validation stages that guarantee that certain unsafe tags are really safe,
and want to allow some proprietary (-moz-*) CSS properties.

Examples:

<!-- Add <object> to the set of allowed HTML tags. -->
<whitelist id="urn://com/google/caja/html/tags">
<inherit class="urn:com.google.caja.plugin.HtmlWhitelist$Tags"/>
<allow item="object"/>
</whitelist>

<!-- Add allowScriptAccess to the set of allowed HTML attributes. -->
<whitelist id="urn://com/google/caja/html/attributes">
<inherit class="urn:com.google.caja.plugin.HtmlWhitelist$Attributes"/>
<allow item="allowscriptaccess"/>
</whitelist>

<!-- Add a definition of a CSS property. -->
<whitelist id="urn://com/google/caja/css/properties">
<inherit class="urn:com.google.caja.plugin.CssWhitelist$Properties"/>
<allow item="-moz-background-origin">
<![CDATA[ <background-origin> | inherit ]]>
</allow>
<define symbol="background-origin">
content | border | padding
</define>
</whitelist>

<!-- Replace the existing HTML whitelist that only allows
<b> and <p> tags. -->
<whitelist id="urn://com/google/caja/html/tags">
<!-- No <inherit>. -->
<allow item="b"/>
<allow item="p"/>
</whitelist>

Schema:
<!ELEMENT whitelist (inherit_, (allow|define)_)>
<!ATTLIST whitelist id %urn; #REQUIRED>

<!ELEMENT inherit NONE>
<!ATTLIST inherit id %urn; #REQUIRED>

<!ELEMENT allow (#PCDATA)>
<!ATTLIST allow item CDATA #REQUIRED>

<!ELEMENT define (#PCDATA)>
<!ATTLIST define symbol CDATA #REQUIRED>

doesn't handle null value in the defaultFilter

Original issue 1 created by sylvain.pointeau on 2007-10-19T13:41:54.000Z:

What steps will reproduce the problem?

  1. calling the serialize on an object with a null property

What is the expected output? What do you see instead?
one error in firebug

please find below a fix for the defaultFilter.

/* default filter */
function defaultFilter(baseObj, key) {
var result;

    if (typeof key === 'string') {
        if (!Object.prototype.hasOwnProperty.call(baseObj, key)) {
            return undefined;
        }
    } else if (typeof key === 'number') {
        if (!(baseObj instanceof Array)) {
            return undefined;
        }
    } else {
        return undefined;
    }
    result = baseObj[key];

    if(!result) { return undefined; }        

    if (typeof result.toJSON === 'function') {
        return result.toJSON();
    } else {
        return result;
    }
}

'instanceof' should not completely expand RHS

Original issue 31 created by ihab.awad on 2008-01-15T01:27:55.000Z:

If I have --

function foo() {}
... x instanceof foo ...

the current expansion will expand the RHS of the 2nd line completely, to --

... x instanceof .primFreeze(___OUTERS.foo)) ...

we need an expansion which re-scopes to _OUTERS_ but does not prematurely freeze.

Current Caja translator doesn't protect encapsulated state

Original issue 14 created by erights on 2007-12-05T18:34:15.000Z:

What steps will reproduce the problem?

  1. I fed the following text into Andrea's online translator page:

<script>x.foo_;
</script>

What is the expected output?

I expected to see a failure report. This text must be statically rejected
by the Caja translator, because it's accessing an internal property name
(one ending in "_") without using "this.".

What do you see instead?

{
.loadModule(function (___OUTERS) {
(function () {
var x___ = _OUTERS.x;
return x
__.foo__canRead___ ? x___.foo_ : _.readPub(x, 'foo');
})();
});
}

If x does have an internal "foo_" property for which the canRead fastpath
flag is already set, this translated code will innappropriately succeed,
resulting in a security breach.

Please use labels and text to provide additional information.

Reassigning "this" in global scope

Original issue 38 created by metaweta on 2008-01-17T01:28:17.000Z:

this=function(){}
this();

You can replace your global scope; I don't know if that causes problems,
but it's weird.

[PATCH] Null namespaceName should be disallowed

Original issue 7 created by andrea.campi on 2007-12-03T14:23:48.000Z:

Creating a new PluginMeta instance with a null (for instance, by passing a null nsName to HtmlPluginCompiler) causes bad generated code, so we may as well disallow it.

ClassCastException: com.google.caja.parser.js.FunctionConstructor

Original issue 28 created by andrea.campi on 2008-01-14T17:42:53.000Z:

What steps will reproduce the problem?

Translate:

var Singleton = new (function() {
})();

What is the expected output? What do you see instead?

java.lang.ClassCastException: com.google.caja.parser.js.FunctionConstructor

The expected behavior would be equivalent to:

var Singleton = (function() {
})();

which is translated to:

{
.loadModule(function (___OUTERS) {
_OUTERS.Singleton = **.asSimpleFunc(**.primFreeze(__.simpleFunc(function () {
})))();
});
}

What version of the product are you using? On what operating system?

r359

Please provide any additional information below.

Calling Javascript type-cast constructors as simple-functions must work cajoled, but doesn't

Original issue 26 created by erights on 2008-01-11T03:31:43.000Z:

What steps will reproduce the problem?

  1. Cajole "foo = String(bar);"
  2. Run the result
    3.

What is the expected output? What do you see instead?

This should work cajoled just as it does uncajoled.
However, the current translation and runtime spec correctly cause it fail,
complaining that String is a constructor, and so can't be called as a
simple-function. The current implementation correctly implements this
broken implication of the current spec.

Originally reported by Andrea Campi at
http://groups.google.com/group/google-caja-discuss/browse_thread/thread/4a9a5e2fbe18be39#

local__ is accepted

Original issue 15 created by andrea.campi on 2007-12-10T14:20:18.000Z:

What steps will reproduce the problem?

Translate the following (with the online translator, for instance):

<script>
var foo__ = "bar";
</script>

What is the expected output? What do you see instead?

I expect the above to be statically refused. Instead I get:

{
.loadModule(function (___OUTERS) {
var foo__ = "bar";
});
}

Increment and decrement on object fields produces bogus javascript

Original issue 34 created by mikesamuel on 2008-01-15T05:49:01.000Z:

The following
var o = { x: 0 };
o.x++;
cajoles to the following illegal javascript
{
_OUTERS.o = {
'x': 0
};
(function () {
var x
__ = _OUTERS.o;
return x
__.x_canRead___ ? x___.x : _.readPub(x_, 'x');
})()++;
}

Note the lack of a x_canSetPub___, and the ++ applied to a function call.

Bad reference to other functions in same module

Original issue 24 created by andrea.campi on 2008-01-10T13:49:19.000Z:

What steps will reproduce the problem?

Translate:

<script>
function Foo() {
return caja.freeze({
});
}

function Bar() {
var foo = new Foo();

return caja.freeze({
});
}
</script>

What is the expected output? What do you see instead?

{
.loadModule(function (___OUTERS) {
_OUTERS.Foo = **.simpleFunc(function () {
return (function () {
var x**_ = _OUTERS.caja;
var x0
__ = {
};
x___.freeze_canCall___ ? x___.freeze(x0___) : _.callPub(x, 'freeze', [x0__]);
})();
});
_OUTERS.Bar = **.simpleFunc(function () {
var foo = new (**.asCtor(Foo))();
return (function () {
var x
__ = _OUTERS.caja;
var x0
__ = {
};
x___.freeze_canCall___ ? x___.freeze(x0___) : _.callPub(x, 'freeze', [x0__]);
})();
});
});
}

Note how Foo is accessed unqualified. It needs to be accessed via _OUTERS_; or,
alternatively, we could use:

{
.loadModule(function (___OUTERS) {
var Foo = .simpleFunc(function () {
....
}
___OUTERS
.Foo = Foo;
}

which would make it OK to refer to Foo in subsequent code in the same module. Foo wouldn't
escaped the current module, but I'm not sure whether there could be a risk of other unintended
side effects.

What version of the product are you using? On what operating system?

trunk as of Jan 9, r337.

The caja rewriter fails on catch blocks

Original issue 16 created by mikesamuel on 2007-12-22T05:48:22.000Z:

Catch blocks have a parse tree like
TryStmt
Block
...
CatchStmt
Declaration
Identifier : ex
Block
...

The current rewrite rules rewrite the Declaration to an assignment but this
is incorrect.

Previously, aaja rewrite
catch (ex) { foo }
to
catch (tmp_1__) {
var ex = '' + tmp_1__;
foo;
}

where conversion to a string was used as a poor man's sanitization.

'int' values are serialized as 'null'

Original issue 3 created by erights on 2007-11-01T19:30:30.000Z:

Reported by Donovan Walker. Thanks!

What steps will reproduce the problem?
1.
2. JSON.serialize(3)
3.

What is the expected output? What do you see instead?

Should see

3

did see

null

Please use labels and text to provide additional information.

log-to-console.js causes error

Original issue 23 created by andrea.campi on 2008-01-09T14:55:52.000Z:

What steps will reproduce the problem?

After loading caja.js and log-to-console.js, call:

caja.log("test");

Then load the page with Firefox with Firebug.

What is the expected output? What do you see instead?

Instead of getting "test" in the log, you will see "uncaught exception:
Permission denied to get property Function.parent

I am not sure what is the reason for the message, but a simple fix is to
change log-to-console.js to:

___.setLogFunc(function(str) {
  global.console.log(str);
})

What version of the product are you using? On what operating system?

Jan 9 = r337

the first indice of an array is 0 not 1

Original issue 2 created by sylvain.pointeau on 2007-10-19T14:04:29.000Z:

in JSON.js
method serialize
for an array
the loop should begin at 0

        function serialize(value) {

....
for (i = 0; i < len; i += 1) { <---- here
v = filter(value, i);
if (v !== undefined) {
if (needComma) {
out.push(',');
} else {

Cheers,
Sylvain Pointeau

javascript urls aren't sanitized

Original issue 39 created by metaweta on 2008-01-18T00:42:08.000Z:

<div id="1"></div>
<script type="text/javascript">
document.getElementById("1").innerHTML="<a
href='javascript:alert(1)'>blah</a>";
</script>

warnings are fatal

Original issue 5 created by andrea.campi on 2007-12-03T14:18:49.000Z:

From mailing list thread: http://groups.google.com/group/google-caja-
discuss/browse_thread/thread/4d55528621d84b06

Warning messages (MessageLevel.WARNING) are fatal and abort the translation. The expected
behavior is for a warning to be emitted, but translation to proceed.

To reproduce the issue, try translating the following code:

var a = {
foo: "bar",
};

The attached diff fixes this by aborting only if the level is MessageLevel.CRITICAL_WARNING or
above; this is a somewhat arbitrary choice that can be changed.
Also, messages are emitted to System.err only if the error level is high enough to abort
translation; callers of this API should IMHO call getErrors() themselves to collect any warning, so
they can present them to the user in a better way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.