HTTPHeaderMap's operator== is not fully correct
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 23 Nov 2019 00:04:05 +0000 (00:04 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 23 Nov 2019 00:04:05 +0000 (00:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204361

Reviewed by Alex Christensen.

Source/WebCore:

If headers are added in a different order, HTTPHeaderMap's operator==() would wrongly
return false because it is using a Vector internally to store the headers. Also, it
would incorrectly return false if the case of the headers did not match.

* platform/network/HTTPHeaderMap.cpp:
(WebCore::HTTPHeaderMap::get const):
(WebCore::HTTPHeaderMap::getUncommonHeader const):
* platform/network/HTTPHeaderMap.h:
(WebCore::HTTPHeaderMap::operator==):

Tools:

Add API test coverage.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/HTTPHeaderMap.cpp: Added.
(TestWebKitAPI::TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/network/HTTPHeaderMap.cpp
Source/WebCore/platform/network/HTTPHeaderMap.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderMap.cpp [new file with mode: 0644]

index 0f0c05f..ddf0dea 100644 (file)
@@ -1,3 +1,20 @@
+2019-11-22  Chris Dumez  <cdumez@apple.com>
+
+        HTTPHeaderMap's operator== is not fully correct
+        https://bugs.webkit.org/show_bug.cgi?id=204361
+
+        Reviewed by Alex Christensen.
+
+        If headers are added in a different order, HTTPHeaderMap's operator==() would wrongly
+        return false because it is using a Vector internally to store the headers. Also, it
+        would incorrectly return false if the case of the headers did not match.
+
+        * platform/network/HTTPHeaderMap.cpp:
+        (WebCore::HTTPHeaderMap::get const):
+        (WebCore::HTTPHeaderMap::getUncommonHeader const):
+        * platform/network/HTTPHeaderMap.h:
+        (WebCore::HTTPHeaderMap::operator==):
+
 2019-11-22  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Merge "insert inline runs" and "setup display runs" loops in InlineFormattingContext::setDisplayBoxesForLine
index 1e979f8..39cb560 100644 (file)
@@ -55,6 +55,11 @@ String HTTPHeaderMap::get(const String& name) const
     if (findHTTPHeaderName(name, headerName))
         return get(headerName);
 
+    return getUncommonHeader(name);
+}
+
+String HTTPHeaderMap::getUncommonHeader(const String& name) const
+{
     auto index = m_uncommonHeaders.findMatching([&](auto& header) {
         return equalIgnoringASCIICase(header.key, name);
     });
index 0bd0429..6000745 100644 (file)
@@ -158,7 +158,7 @@ public:
     WEBCORE_EXPORT void add(const String& name, const String& value);
     WEBCORE_EXPORT void append(const String& name, const String& value);
     WEBCORE_EXPORT bool contains(const String&) const;
-    bool remove(const String&);
+    WEBCORE_EXPORT bool remove(const String&);
 
 #if USE(CF)
     void set(CFStringRef name, const String& value);
@@ -190,7 +190,17 @@ public:
 
     friend bool operator==(const HTTPHeaderMap& a, const HTTPHeaderMap& b)
     {
-        return a.m_commonHeaders == b.m_commonHeaders && a.m_uncommonHeaders == b.m_uncommonHeaders;
+        if (a.m_commonHeaders.size() != b.m_commonHeaders.size() || a.m_uncommonHeaders.size() != b.m_uncommonHeaders.size())
+            return false;
+        for (auto& commonHeader : a.m_commonHeaders) {
+            if (b.get(commonHeader.key) != commonHeader.value)
+                return false;
+        }
+        for (auto& uncommonHeader : a.m_uncommonHeaders) {
+            if (b.getUncommonHeader(uncommonHeader.key) != uncommonHeader.value)
+                return false;
+        }
+        return true;
     }
 
     friend bool operator!=(const HTTPHeaderMap& a, const HTTPHeaderMap& b)
@@ -203,6 +213,7 @@ public:
 
 private:
     void setUncommonHeader(const String& name, const String& value);
+    WEBCORE_EXPORT String getUncommonHeader(const String& name) const;
 
     CommonHeadersVector m_commonHeaders;
     UncommonHeadersVector m_uncommonHeaders;
index 325da6d..4547e65 100644 (file)
@@ -1,3 +1,16 @@
+2019-11-22  Chris Dumez  <cdumez@apple.com>
+
+        HTTPHeaderMap's operator== is not fully correct
+        https://bugs.webkit.org/show_bug.cgi?id=204361
+
+        Reviewed by Alex Christensen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/HTTPHeaderMap.cpp: Added.
+        (TestWebKitAPI::TEST):
+
 2019-11-22  Sihui Liu  <sihui_liu@apple.com>
 
         Cross-thread version StorageQuotaManager
index b3ba9a2..8252f98 100644 (file)
                46E66A901F0D75590026D83C /* WKWebViewDiagnosticLogging.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46E66A8F1F0D75590026D83C /* WKWebViewDiagnosticLogging.mm */; };
                46E816F81E79E29C00375ADC /* RestoreStateAfterTermination.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46E816F71E79E29100375ADC /* RestoreStateAfterTermination.mm */; };
                46EBD8472372320F00223A6E /* RestoreScrollPosition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46EBD846237231E600223A6E /* RestoreScrollPosition.mm */; };
+               46FA2FEE23846CA5000CCB0C /* HTTPHeaderMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46FA2FED23846C9A000CCB0C /* HTTPHeaderMap.cpp */; };
                4909EE3A2D09480C88982D56 /* Markable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC79F168BE454E579E417B05 /* Markable.cpp */; };
                4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */; };
                510477721D298DDD009747EB /* IDBDeleteRecovery.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5104776F1D298D85009747EB /* IDBDeleteRecovery.sqlite3 */; };
                46E66A8F1F0D75590026D83C /* WKWebViewDiagnosticLogging.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewDiagnosticLogging.mm; sourceTree = "<group>"; };
                46E816F71E79E29100375ADC /* RestoreStateAfterTermination.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RestoreStateAfterTermination.mm; sourceTree = "<group>"; };
                46EBD846237231E600223A6E /* RestoreScrollPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RestoreScrollPosition.mm; sourceTree = "<group>"; };
+               46FA2FED23846C9A000CCB0C /* HTTPHeaderMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPHeaderMap.cpp; sourceTree = "<group>"; };
                4A410F4B19AF7BD6002EBAB5 /* UserMedia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMedia.cpp; sourceTree = "<group>"; };
                4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = getUserMedia.html; sourceTree = "<group>"; };
                4A410F4D19AF7BEF002EBAB6 /* ondevicechange.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ondevicechange.html; sourceTree = "<group>"; };
                                8E4A85361E1D1AA100F53B0F /* GridPosition.cpp */,
                                83B88A331C80056D00BB2418 /* HTMLParserIdioms.cpp */,
                                5CA1DEC71F71F40700E71BD3 /* HTTPHeaderField.cpp */,
+                               46FA2FED23846C9A000CCB0C /* HTTPHeaderMap.cpp */,
                                6B9ABE112086952F00D75DE6 /* HTTPParsers.cpp */,
                                7A909A731D877475007E10F8 /* IntPoint.cpp */,
                                7A909A741D877475007E10F8 /* IntRect.cpp */,
                                7CCE7EC21A411A7E00447C4C /* HTMLFormCollectionNamedItem.mm in Sources */,
                                7C83E0501D0A641800FEBCF3 /* HTMLParserIdioms.cpp in Sources */,
                                5CA1DEC81F71F70100E71BD3 /* HTTPHeaderField.cpp in Sources */,
+                               46FA2FEE23846CA5000CCB0C /* HTTPHeaderMap.cpp in Sources */,
                                6B9ABE122086952F00D75DE6 /* HTTPParsers.cpp in Sources */,
                                5C7C24FC237C975400599C91 /* HTTPServer.mm in Sources */,
                                51AF23DF1EF1A3730072F281 /* IconLoadingDelegate.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderMap.cpp b/Tools/TestWebKitAPI/Tests/WebCore/HTTPHeaderMap.cpp
new file mode 100644 (file)
index 0000000..2f6d84d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "Test.h"
+#include <WebCore/HTTPHeaderMap.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+TEST(HTTPHeaderMap, ComparisonOperator)
+{
+    HTTPHeaderMap map1;
+    HTTPHeaderMap map2;
+
+    map1.add("Cache-Control"_str, "max-age:0"_str);
+    map1.add("ETag"_str, "foo"_str);
+    map1.add("Not-Common1"_str, "bar"_str);
+    map1.add("Not-Common2"_str, "bar"_str);
+
+    map2.add("ETag"_str, "foo"_str);
+    map2.add("Cache-Control"_str, "max-age:0"_str);
+    map2.add("Not-Common2"_str, "bar"_str);
+    map2.add("Not-Common1"_str, "bar"_str);
+
+    EXPECT_TRUE(map1 == map2);
+    EXPECT_FALSE(map1 != map2);
+
+    map1.add("Last-Modified"_str, "123455"_str);
+    map2.add("Last-Modified"_str, "123456"_str);
+    EXPECT_FALSE(map1 == map2);
+    EXPECT_TRUE(map1 != map2);
+
+    map1.remove("Last-Modified"_str);
+    map2.remove("Last-Modified"_str);
+    EXPECT_TRUE(map1 == map2);
+    EXPECT_FALSE(map1 != map2);
+
+    map1.add("Not-Common3"_str, "bar"_str);
+    map1.add("Not-Common3"_str, "baz"_str);
+    EXPECT_FALSE(map1 == map2);
+    EXPECT_TRUE(map1 != map2);
+
+    map1.remove("Not-Common3"_str);
+    map2.remove("Not-Common3"_str);
+    EXPECT_TRUE(map1 == map2);
+    EXPECT_FALSE(map1 != map2);
+
+    map1.add("NOT-COMMON4"_str, "foo");
+    map2.add("Not-Common4"_str, "foo");
+    EXPECT_TRUE(map1 == map2);
+    EXPECT_FALSE(map1 != map2);
+}
+
+}