Bug 845057 - Part 3: Use the parsed attribute in ParseSandboxAttributeToFlags; r=bz
authorDeian Stefan <deian@cs.stanford.edu>
Thu, 19 Dec 2013 13:35:25 -0800
changeset 177792 2e5d20af43eb5bab3b79ebf90717a6b3939b4de5
parent 177791 1e7b84ab87c4f6c00eae481f4fac0bc49c9463ad
child 177793 9664a697fd18a148e1da63e32c1b18ce91dd126a
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs845057
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 845057 - Part 3: Use the parsed attribute in ParseSandboxAttributeToFlags; r=bz
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsGkAtomList.h
content/html/content/src/HTMLIFrameElement.cpp
content/html/content/test/test_iframe_sandbox_general.html
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -91,16 +91,17 @@ class nsNodeInfoManager;
 class nsPIDOMWindow;
 class nsPresContext;
 class nsScriptObjectTracer;
 class nsStringBuffer;
 class nsStringHashKey;
 class nsTextFragment;
 class nsViewportInfo;
 class nsWrapperCache;
+class nsAttrValue;
 
 struct JSPropertyDescriptor;
 struct JSRuntime;
 struct nsIntMargin;
 
 template<class E> class nsCOMArray;
 template<class E> class nsTArray;
 template<class K, class V> class nsDataHashtable;
@@ -827,20 +828,20 @@ public:
   static nsresult GetLocalizedString(PropertiesFile aFile,
                                      const char* aKey,
                                      nsXPIDLString& aResult);
 
   /**
    * A helper function that parses a sandbox attribute (of an <iframe> or
    * a CSP directive) and converts it to the set of flags used internally.
    *
-   * @param aAttribute 	the value of the sandbox attribute
-   * @return 			the set of flags
+   * @param sandboxAttr   the sandbox attribute
+   * @return              the set of flags (0 if sandboxAttr is null)
    */
-  static uint32_t ParseSandboxAttributeToFlags(const nsAString& aSandboxAttr);
+  static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr);
 
 
   /**
    * Fill (with the parameters given) the localized string named |aKey| in
    * properties file |aFile|.
    */
 private:
   static nsresult FormatLocalizedString(PropertiesFile aFile,
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -924,63 +924,50 @@ nsContentUtils::GetParserService()
 
   return sParserService;
 }
 
 /**
  * A helper function that parses a sandbox attribute (of an <iframe> or
  * a CSP directive) and converts it to the set of flags used internally.
  *
- * @param aAttribute    the value of the sandbox attribute
- * @return              the set of flags
+ * @param sandboxAttr   the sandbox attribute
+ * @return              the set of flags (0 if sandboxAttr is null)
  */
 uint32_t
-nsContentUtils::ParseSandboxAttributeToFlags(const nsAString& aSandboxAttrValue)
-{
-  // If there's a sandbox attribute at all (and there is if this is being
-  // called), start off by setting all the restriction flags.
-  uint32_t out = SANDBOXED_NAVIGATION |
-                 SANDBOXED_AUXILIARY_NAVIGATION |
-                 SANDBOXED_TOPLEVEL_NAVIGATION |
-                 SANDBOXED_PLUGINS |
-                 SANDBOXED_ORIGIN |
-                 SANDBOXED_FORMS |
-                 SANDBOXED_SCRIPTS |
-                 SANDBOXED_AUTOMATIC_FEATURES |
-                 SANDBOXED_POINTER_LOCK |
-                 SANDBOXED_DOMAIN;
-
-  if (!aSandboxAttrValue.IsEmpty()) {
-    // The separator optional flag is used because the HTML5 spec says any
-    // whitespace is ok as a separator, which is what this does.
-    HTMLSplitOnSpacesTokenizer tokenizer(aSandboxAttrValue, ' ',
-      nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>::SEPARATOR_OPTIONAL);
-
-    while (tokenizer.hasMoreTokens()) {
-      nsDependentSubstring token = tokenizer.nextToken();
-      if (token.LowerCaseEqualsLiteral("allow-same-origin")) {
-        out &= ~SANDBOXED_ORIGIN;
-      } else if (token.LowerCaseEqualsLiteral("allow-forms")) {
-        out &= ~SANDBOXED_FORMS;
-      } else if (token.LowerCaseEqualsLiteral("allow-scripts")) {
-        // allow-scripts removes both SANDBOXED_SCRIPTS and
-        // SANDBOXED_AUTOMATIC_FEATURES.
-        out &= ~SANDBOXED_SCRIPTS;
-        out &= ~SANDBOXED_AUTOMATIC_FEATURES;
-      } else if (token.LowerCaseEqualsLiteral("allow-top-navigation")) {
-        out &= ~SANDBOXED_TOPLEVEL_NAVIGATION;
-      } else if (token.LowerCaseEqualsLiteral("allow-pointer-lock")) {
-        out &= ~SANDBOXED_POINTER_LOCK;
-      } else if (token.LowerCaseEqualsLiteral("allow-popups")) {
-        out &= ~SANDBOXED_AUXILIARY_NAVIGATION;
-      }
-    }
-  }
+nsContentUtils::ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr)
+{
+  // No sandbox attribute, no sandbox flags.
+  if (!sandboxAttr) { return 0; }
+
+  //  Start off by setting all the restriction flags.
+  uint32_t out = SANDBOXED_NAVIGATION
+               | SANDBOXED_AUXILIARY_NAVIGATION
+               | SANDBOXED_TOPLEVEL_NAVIGATION
+               | SANDBOXED_PLUGINS
+               | SANDBOXED_ORIGIN
+               | SANDBOXED_FORMS
+               | SANDBOXED_SCRIPTS
+               | SANDBOXED_AUTOMATIC_FEATURES
+               | SANDBOXED_POINTER_LOCK
+               | SANDBOXED_DOMAIN;
+
+// Macro for updating the flag according to the keywords
+#define IF_KEYWORD(atom, flags) \
+  if (sandboxAttr->Contains(nsGkAtoms::atom, eIgnoreCase)) { out &= ~(flags); }
+
+  IF_KEYWORD(allowsameorigin, SANDBOXED_ORIGIN)
+  IF_KEYWORD(allowforms,  SANDBOXED_FORMS)
+  IF_KEYWORD(allowscripts, SANDBOXED_SCRIPTS | SANDBOXED_AUTOMATIC_FEATURES)
+  IF_KEYWORD(allowtopnavigation, SANDBOXED_TOPLEVEL_NAVIGATION)
+  IF_KEYWORD(allowpointerlock, SANDBOXED_POINTER_LOCK)
+  IF_KEYWORD(allowpopups, SANDBOXED_AUXILIARY_NAVIGATION)
 
   return out;
+#undef IF_KEYWORD
 }
 
 #ifdef IBMBIDI
 nsIBidiKeyboard*
 nsContentUtils::GetBidiKeyboard()
 {
   if (!sBidiKeyboard) {
     nsresult rv = CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -68,17 +68,23 @@ GK_ATOM(address, "address")
 GK_ATOM(after, "after")
 GK_ATOM(after_end, "after_end")
 GK_ATOM(after_start, "after_start")
 GK_ATOM(align, "align")
 GK_ATOM(alink, "alink")
 GK_ATOM(all, "all")
 GK_ATOM(allowevents, "allowevents")
 GK_ATOM(allownegativeassertions, "allownegativeassertions")
+GK_ATOM(allowforms,"allow-forms")
 GK_ATOM(allowfullscreen, "allowfullscreen")
+GK_ATOM(allowpointerlock,"allow-pointer-lock")
+GK_ATOM(allowpopups,"allow-popups")
+GK_ATOM(allowsameorigin,"allow-same-origin")
+GK_ATOM(allowscripts,"allow-scripts")
+GK_ATOM(allowtopnavigation,"allow-top-navigation")
 GK_ATOM(allowuntrusted, "allowuntrusted")
 GK_ATOM(alt, "alt")
 GK_ATOM(alternate, "alternate")
 GK_ATOM(always, "always")
 GK_ATOM(ancestor, "ancestor")
 GK_ATOM(ancestorOrSelf, "ancestor-or-self")
 GK_ATOM(_and, "and")
 GK_ATOM(any, "any")
--- a/content/html/content/src/HTMLIFrameElement.cpp
+++ b/content/html/content/src/HTMLIFrameElement.cpp
@@ -239,24 +239,18 @@ HTMLIFrameElement::UnsetAttr(int32_t aNa
   }
 
   return NS_OK;
 }
 
 uint32_t
 HTMLIFrameElement::GetSandboxFlags()
 {
-  nsAutoString sandboxAttr;
-
-  if (GetAttr(kNameSpaceID_None, nsGkAtoms::sandbox, sandboxAttr)) {
-    return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
-  }
-
-  // No sandbox attribute, no sandbox flags.
-  return 0;
+  const nsAttrValue* sandboxAttr = GetParsedAttr(nsGkAtoms::sandbox);
+  return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
 }
 
 JSObject*
 HTMLIFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return HTMLIFrameElementBinding::Wrap(aCx, aScope, this);
 }
 
--- a/content/html/content/test/test_iframe_sandbox_general.html
+++ b/content/html/content/test/test_iframe_sandbox_general.html
@@ -35,36 +35,36 @@ function ok_wrapper(result, desc) {
   ok(result, desc);
 
   completedTests++;
 
   if (result) {
     passedTests++;
   }
 
-  if (completedTests == 23) {
+  if (completedTests == 27) {
     is(passedTests, completedTests, "There are " + completedTests + " general tests that should pass");
     SimpleTest.finish();
   }
 }
 
 function doTest() {
-  // passes if good
+  // passes twice if good
   // 1) test that inline scripts (<script>) can run in an iframe sandboxed with "allow-scripts"
   // (done in file_iframe_sandbox_c_if1.html which has 'allow-scripts')
 
-  // passes if good
+  // passes twice if good
   // 2) test that <script src=...> can run in an iframe sandboxed with "allow-scripts"
   // (done in file_iframe_sandbox_c_if1.html which has 'allow-scripts')
 
-  // passes if good
+  // passes twice if good
   // 3) test that script in an event listener (body onload) can run in an iframe sandboxed with "allow-scripts"
   // (done in file_iframe_sandbox_c_if1.html which has 'allow-scripts')
 
-  // passes if good
+  // passes twice if good
   // 4) test that script in an javascript:url can run in an iframe sandboxed with "allow-scripts"
   // (done in file_iframe_sandbox_c_if1.html which has 'allow-scripts')
 
   // fails if bad
   // 5) test that inline scripts cannot run in an iframe sandboxed without "allow-scripts"
   // (done in file_iframe_sandbox_c_if2.html which has sandbox='')
 
   // fails if bad
@@ -212,16 +212,17 @@ function do_if_10() {
   if_10.src = 'javascript:"<html><script>window.parent.ok_wrapper(true, \'an iframe sandboxed with allow-scripts should execute script in a javascript URL in a newly set src attribute\');<\/script><\/html>"';
 }
 </script>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
 <p id="display"></p>
 <div id="content">
 <iframe sandbox="allow-same-origin allow-scripts" id="if_1" src="file_iframe_sandbox_c_if1.html" height="10" width="10"></iframe>
+<iframe sandbox="aLlOw-SAME-oRiGin ALLOW-sCrIpTs" id="if_1_case_insensitive" src="file_iframe_sandbox_c_if1.html" height="10" width="10"></iframe>
 <iframe sandbox="" id="if_2" src="file_iframe_sandbox_c_if2.html" height="10" width="10"></iframe>
 <iframe sandbox="allow-forms allow-scripts" id="if_3" src="file_iframe_sandbox_c_if3.html" height="10" width="10"></iframe>
 <iframe sandbox="allow-same-origin allow-scripts" id="if_4" src="file_iframe_sandbox_c_if4.html" height="10" width="10"></iframe>
 <iframe sandbox="allow-same-origin" id="if_5" src="file_iframe_sandbox_c_if5.html" height="10" width="10"></iframe>
 <iframe sandbox="  allow-same-origin  allow-scripts  " id="if_6_a" src="file_iframe_sandbox_c_if6.html" height="10" width="10"></iframe>
 <iframe sandbox="&#x09;allow-same-origin&#x09;allow-scripts&#x09;" id="if_6_b" src="file_iframe_sandbox_c_if6.html" height="10" width="10"></iframe>
 <iframe sandbox="&#x0a;allow-same-origin&#x0a;allow-scripts&#x0a;" id="if_6_c" src="file_iframe_sandbox_c_if6.html" height="10" width="10"></iframe>
 <iframe sandbox="&#x0c;allow-same-origin&#x0c;allow-scripts&#x0c;" id="if_6_d" src="file_iframe_sandbox_c_if6.html" height="10" width="10"></iframe>