2009-09-24 Carol Szabo <carol.szabo@nokia.com>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Sep 2009 23:44:17 +0000 (23:44 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Sep 2009 23:44:17 +0000 (23:44 +0000)
        Reviewed by Alexey Proskuryakov.

        WebKit returns "" instead of null when getting
        inexistent, forbidden or invalidly named headers.
        https://bugs.webkit.org/show_bug.cgi?id=29140

        * http/tests/xmlhttprequest/get-dangerous-headers.html:
          Updated to test for null instead of ""
        * http/tests/xmlhttprequest/getResponseHeader-expected.txt:
        * http/tests/xmlhttprequest/getResponseHeader.html:
          Extended to also test for headers that should return null.
        * http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html: Removed.
          getResponseHeader.html now covers this case as well.
2009-09-24  Carol Szabo  <carol.szabo@nokia.com>

        Reviewed by Alexey Proskuryakov.

        WebKit returns "" instead of null when getting
        inexistent, forbidden or invalidly named headers.
        https://bugs.webkit.org/show_bug.cgi?id=29140

        * xml/XMLHttpRequest.cpp:
        (WebCore::XMLHttpRequest::getResponseHeader):
        Changed to return null as it should according to the spec.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48739 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/xmlhttprequest/get-dangerous-headers.html
LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt
LayoutTests/http/tests/xmlhttprequest/getResponseHeader.html
LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader-expected.txt [deleted file]
LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html [deleted file]
WebCore/ChangeLog
WebCore/xml/XMLHttpRequest.cpp

index 6d89d12..a0023a9 100644 (file)
@@ -1,3 +1,19 @@
+2009-09-24  Carol Szabo  <carol.szabo@nokia.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        WebKit returns "" instead of null when getting
+        inexistent, forbidden or invalidly named headers.
+        https://bugs.webkit.org/show_bug.cgi?id=29140
+
+        * http/tests/xmlhttprequest/get-dangerous-headers.html:
+          Updated to test for null instead of ""
+        * http/tests/xmlhttprequest/getResponseHeader-expected.txt:
+        * http/tests/xmlhttprequest/getResponseHeader.html:
+          Extended to also test for headers that should return null.
+        * http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html: Removed.
+          getResponseHeader.html now covers this case as well.
+
 2009-09-24  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
 
         Reviewed by Oliver Hunt.
index e030aca..7970bb2 100644 (file)
 
     var result = "PASS";
 
-    if (req.getResponseHeader("Set-Cookie") != "" && result == "PASS")
+    if (req.getResponseHeader("Set-Cookie") != null && result == "PASS")
         result = "FAIL: Saw a Set-Cookie header with getResponseHeader.";
-    if (req.getResponseHeader("set-cookie") != "" && result == "PASS")
+    if (req.getResponseHeader("set-cookie") != null && result == "PASS")
         result = "FAIL: Saw a set-cookie header with getResponseHeader.";
-    if (req.getResponseHeader("Set-Cookie2") != "" && result == "PASS")
+    if (req.getResponseHeader("Set-Cookie2") != null && result == "PASS")
         result = "FAIL: Saw a Set-Cookie2 header with getResponseHeader.";
-    if (req.getResponseHeader("set-cookie2") != "" && result == "PASS")
+    if (req.getResponseHeader("set-cookie2") != null && result == "PASS")
         result = "FAIL: Saw a set-cookie2 header with getResponseHeader.";
 
     if (req.getAllResponseHeaders().match(/Set-Cookie/) && result == "PASS")
index a9fe045..567a335 100644 (file)
@@ -1,10 +1,38 @@
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "SeT-COoKie"
+CONSOLE MESSAGE: line 1: Refused to get unsafe header "sEt-coOkIE2"
 Test page for bug 15356 and bug 29121
 
-Assertion: Invoking getResponseHeader method when readyState >= 2 (HEADERS_RECEIVED) should return a header value if the header exists.
+Assertion: Invoking the getResponseHeader method when readyState >= 2 (HEADERS_RECEIVED) returns a header value if the header exists.
 
-PASSED 0
-PASSED 1
-PASSED 2: getResponseHeader(Content-Type) returned a value.
-PASSED 3
-PASSED 4
+Assertion: Invoking the getResponseHeader method with the parameter satisfying the following conditions causes getResponseHeader to return null:
+
+1a. The parameter case-insensitively matches Set-Cookie;
+1b. The parameter case-insensitively matches Set-Cookie2;
+2. The parameter does not match any header in the response;
+3a. The parameter is null (it is not a valid header name);
+3b. The parameter is "Content-Type:" (it is not a valid header name).
+PASSED 0 Content-Type: exception thrown.
+PASSED 1 Content-Type: exception thrown
+PASSED 2 Content-Type: ResponseHeader(Content-Type) returned a value.
+PASSED 2 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
+PASSED 2 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
+PASSED 2 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
+PASSED 2 null: getResponseHeader(null) returned null.
+PASSED 2 Content-Type:: getResponseHeader(Content-Type:) returned null.
+PASSED 3 Content-Type: Content-Type
+PASSED 3 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
+PASSED 3 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
+PASSED 3 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
+PASSED 3 null: getResponseHeader(null) returned null.
+PASSED 3 Content-Type:: getResponseHeader(Content-Type:) returned null.
+PASSED 4 Content-Type: Content-Type
+PASSED 4 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
+PASSED 4 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
+PASSED 4 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
+PASSED 4 null: getResponseHeader(null) returned null.
+PASSED 4 Content-Type:: getResponseHeader(Content-Type:) returned null.
 
index fa1a9e3..c1cd1e8 100644 (file)
@@ -3,13 +3,24 @@
     <title>Check exception thrown by getReponseHeader </title>
 <script type="text/javascript">
 
+var savedHeader = null;
+var headerName="Content-Type";
+var nullTests =  new Array("SeT-COoKie", "sEt-coOkIE2", 
+    "xxx-mytest-headerabc", null, "Content-Type:");
+
 function log (msg) {
     var paragraph = document.createElement("li");
     paragraph.innerHTML=msg.replace(/\n/gm,"<br>");
     document.getElementById("console").appendChild(paragraph);
 }
 
-var xhr;
+function log4(status, rState, subState, msg) {
+    log(status + " " + rState + " " + subState + ": " + msg);
+}
+
+function log3(status, rState, msg) {
+    log4(status, rState, headerName, msg);
+}
 
 if (window.XMLHttpRequest) {
     xhr = new XMLHttpRequest();
@@ -21,8 +32,6 @@ if (window.XMLHttpRequest) {
     }
 }
 
-var savedHeader = null;
-var headerName="Content-Type";
 xhr.onreadystatechange = function() {
     var rState = this.readyState;
     // We expect an INVALID_STATE_ERR exception for readyState < 2
@@ -30,36 +39,47 @@ xhr.onreadystatechange = function() {
     try {
         var header = this.getResponseHeader(headerName);
         if (rState != this.readyState)
-            log("UNCERTAIN " + rState + ": readyState changed while getting the header.");
+            log3("UNCERTAIN", rState, "readyState changed while getting the header.");
         if (rState < 2) {
-            log("FAILED " + rState + ": " + headerName + "=" + header);
-        } else if (header)
+            log3("FAILED", rState, headerName + "=" + header);
+        } else if (header) {
             if (savedHeader)
                 if (savedHeader != header) {
-                    log("FAILED " + rState +
-": Content-Type changed after it was first returned. Previous " + headerName
-+ "=" + savedHeader + "; New " + headerName + "=" + header + ".");
+                    log3("FAILED", rState,headerName + " changed after it was first returned. Previous " + headerName
+                        + "=" + savedHeader + "; New " + headerName + "=" + header + ".");
                 savedHeader = header;
                 } 
                 else //savedHeader == header here; no need to reprint header
-                    log("PASSED " + rState);
+                    log3("PASSED", rState, headerName);
             else {//first header value retrieved
                 if (window.layoutTestController)
 //do not print the header's value for automated tests to avoid false failures.
-                    log("PASSED " + rState +
-": getResponseHeader(" + headerName + ") returned a value.");
+                    log3("PASSED", rState, "ResponseHeader(" + headerName + ") returned a value.");
                 else
-                    log("PASSED " + rState +
-": getResponseHeader(" + headerName + ") returned: " + header + ".");
+                    log3("PASSED", rState, "getResponseHeader(" + headerName + ") returned: " + header + ".");
                 savedHeader = header;
             }
+            for (var i=0;i<nullTests.length;++i) {
+                try {
+                    var str = this.getResponseHeader(nullTests[i]);
+                    if (str == null)
+                        log4("PASSED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] +
+                            ") returned null.");
+                    else
+                        log4("FAILED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] +
+                            ") returned \"" + str + "\"");
+                } catch(e) {
+                    log4("FAILED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] + ") threw exception:" + e);
+                }
+            }
+        }
         else //header is null
-            log("FAILED " + rState + ": null " + headerName + " returned.");
+            log3("FAILED", rState, "null " + headerName + " returned.");
     } catch (e) {
         if (rState < 2)
-            log("PASSED " + rState);
+            log3("PASSED", rState, "exception thrown");
         else
-            log("FAILED " + rState + ": EXCEPTION THROWN: " + e.message + ".");
+            log3("FAILED", rState, "exception thrown: " + e.message + ".");
     }
     if ((rState == 4) && (window.layoutTestController))
             layoutTestController.notifyDone();
@@ -74,15 +94,15 @@ function test() {
     // Test for readyState = 0
     try {
         var header = xhr.getResponseHeader(headerName);
-        log("FAILED " + xhr.readyState + ": " + headerName + "=" + header + ".");
+        log3("FAILED", xhr.readyState, headerName + "=" + header + ".");
     } catch (e) {
-        log("PASSED " + xhr.readyState);
+        log3("PASSED", xhr.readyState, "exception thrown.");
     }
     try {
         xhr.open("GET","resources/1251.html", true);
         xhr.send(null);
     } catch(e) {
-        log("FAILED open/send: EXCEPTION THROWN: " + e.message +".");
+        log3("FAILED", "open/send", "exception thrown: " + e.message +".");
         if (window.layoutTestController)
             layoutTestController.notifyDone();
     }
@@ -94,15 +114,25 @@ function test() {
 <p>Test page for <a href="http://bugs.webkit.org/show_bug.cgi?id=15356">bug
 15356</a>
 and <a href="http://bugs.webkit.org/show_bug.cgi?id=29121">bug 29121</a></p>
-<p>Assertion: Invoking getResponseHeader method when readyState >= 2
-(HEADERS_RECEIVED) should return a header value if the header exists.</p>
+<p>Assertion: Invoking the getResponseHeader method when readyState >= 2
+(HEADERS_RECEIVED) returns a header value if the header exists.</p>
+<p>Assertion: Invoking the getResponseHeader method with the parameter
+    satisfying the following conditions causes getResponseHeader
+    to return null:
+<li>1a. The parameter case-insensitively matches Set-Cookie;</li>
+<li>1b. The parameter case-insensitively matches Set-Cookie2;</li>
+<li>2.  The parameter does not match any header in the response;</li>
+<li>3a. The parameter is null (it is not a valid header name);</li>
+<li>3b. The parameter is "Content-Type:" (it is not a valid header name).</li>
+
 <script>
     if (!window.layoutTestController)
         document.write("<p>If the test passes one should see \
-below the ruler the text \"passed\" in all capital letters, 5 times, \
-followed each time by a space and the readyState number.</p>\n\
-<p>ReadyStatenumbers should be in ascending order 0 to 4.</p>\n\
-<p>The value of the " + headerName + " header should also be printed.</p>");
+below the ruler the text \"passed\" in all capital letters, once for every ready state &lt; 2, \
+followed each time by a space and the readyState number and 6 times for every ready state >= 2.</p>\n\
+<p>ReadyState numbers should be in ascending order 0 to 4.</p>\n\
+<p>ReadyState numbers should be followed by a blank, the name of the header tested, colon a space and a message.</p>\
+<p>The value of the " + headerName + " header should  be printed for ready state 2.</p>");
 </script>
  <hr>
  <p><ol id=console></ol></p>
diff --git a/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader-expected.txt b/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader-expected.txt
deleted file mode 100644 (file)
index b876bcd..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Test page for the bug 15356 : getResponseHeader and getAllResponseHeaders do not throw exceptions
-
-PASSED 3
-PASSED 4
-
diff --git a/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html b/LayoutTests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html
deleted file mode 100644 (file)
index b376cb1..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<head>
-    <title>Check behaviour when requestiong an invalid header in  getReponseHeader </title>
-</head>
-<body>
-
-<p>Test page for the <a href="http://bugs.webkit.org/show_bug.cgi?id=15356">bug 15356</a> : getResponseHeader and getAllResponseHeaders do not throw exceptions</p>
-
-<script type="text/javascript">
-
-if (window.layoutTestController)
-        layoutTestController.dumpAsText();
-
-function log (msg) {
-    document.body.appendChild(document.createTextNode(msg));
-    document.body.appendChild(document.createElement("br"));
-}
-
-var xhr;
-
-if (window.XMLHttpRequest) {
-    xhr = new XMLHttpRequest();
-} else {
-    try {
-        xhr = new ActiveXObject("Msxml2.XMLHTTP");
-    } catch (ex) {
-        xhr = new ActiveXObject("Microsoft.XMLHTTP");
-    }
-}
-
-xhr.onreadystatechange = function() {
-    var rState = this.readyState;
-    if (rState > 2) {
-        // We expect an empty string or null
-        var header = this.getResponseHeader("(<>@)");
-        if (header == "") {
-            log("PASSED " + rState);
-        } else {
-            log("FAILED " + rState);
-        }
-    }
-}
-xhr.open("GET","resources/1251.html", true);
-xhr.send(null);
-</script>
-</body>
-</html>
index f35b821..904d5fb 100644 (file)
@@ -1,3 +1,15 @@
+2009-09-24  Carol Szabo  <carol.szabo@nokia.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        WebKit returns "" instead of null when getting
+        inexistent, forbidden or invalidly named headers.
+        https://bugs.webkit.org/show_bug.cgi?id=29140
+
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::getResponseHeader):
+        Changed to return null as it should according to the spec.
+
 2009-09-24  Jeremy Orlow  <jorlow@chromium.org>
 
         Reviewed by Dimitri Glazkov.
index 798ae00..ca48d8d 100644 (file)
@@ -709,23 +709,19 @@ String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionCode
 {
     if (m_state < HEADERS_RECEIVED) {
         ec = INVALID_STATE_ERR;
-        return "";
+        return String();
     }
 
-    if (!isValidToken(name))
-        return "";
-
     // See comment in getAllResponseHeaders above.
     if (isSetCookieHeader(name) && !scriptExecutionContext()->securityOrigin()->canLoadLocalResources()) {
         reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
-        return "";
+        return String();
     }
 
     if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)) {
         reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
-        return "";
+        return String();
     }
-
     return m_response.httpHeaderField(name);
 }