Switch CPDF_Dictionary::Remove() to take a ByteStringView.

- Add a comparator to the std::map CPDF_Dictionary uses.
- Change Remove() and adjust callers.
- Add the necessary ByteStringView less than operators.

Change-Id: Ic8e7bc132d783acbb350d74b62dae11033a70e71
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/91611
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_cross_ref_table.cpp b/core/fpdfapi/parser/cpdf_cross_ref_table.cpp
index 6400208..5d8c4b4 100644
--- a/core/fpdfapi/parser/cpdf_cross_ref_table.cpp
+++ b/core/fpdfapi/parser/cpdf_cross_ref_table.cpp
@@ -156,5 +156,5 @@
   new_trailer->SetFor("Prev", trailer_->RemoveFor("Prev"));
 
   for (const auto& key : new_trailer->GetKeys())
-    trailer_->SetFor(key, new_trailer->RemoveFor(key));
+    trailer_->SetFor(key, new_trailer->RemoveFor(key.AsStringView()));
 }
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index fc671e7..4e36946 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -234,7 +234,7 @@
   it->second = pObj->MakeReference(pHolder);
 }
 
-RetainPtr<CPDF_Object> CPDF_Dictionary::RemoveFor(const ByteString& key) {
+RetainPtr<CPDF_Object> CPDF_Dictionary::RemoveFor(ByteStringView key) {
   CHECK(!IsLocked());
   RetainPtr<CPDF_Object> result;
   auto it = m_Map.find(key);
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index 653b48c..f0a452e 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FPDFAPI_PARSER_CPDF_DICTIONARY_H_
 #define CORE_FPDFAPI_PARSER_CPDF_DICTIONARY_H_
 
+#include <functional>
 #include <map>
 #include <set>
 #include <utility>
@@ -26,7 +27,7 @@
 // will return nullptr to indicate non-existent keys.
 class CPDF_Dictionary final : public CPDF_Object {
  public:
-  using DictMap = std::map<ByteString, RetainPtr<CPDF_Object>>;
+  using DictMap = std::map<ByteString, RetainPtr<CPDF_Object>, std::less<>>;
   using const_iterator = DictMap::const_iterator;
 
   CONSTRUCT_VIA_MAKE_RETAIN;
@@ -111,7 +112,7 @@
                                   CPDF_IndirectObjectHolder* pHolder);
 
   // Invalidates iterators for the element with the key |key|.
-  RetainPtr<CPDF_Object> RemoveFor(const ByteString& key);
+  RetainPtr<CPDF_Object> RemoveFor(ByteStringView key);
 
   // Invalidates iterators for the element with the key |oldkey|.
   void ReplaceKey(const ByteString& oldkey, const ByteString& newkey);
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index c8161db..eb33510 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -239,6 +239,12 @@
 inline bool operator<(const char* lhs, const ByteString& rhs) {
   return rhs.Compare(lhs) > 0;
 }
+inline bool operator<(const ByteStringView& lhs, const ByteString& rhs) {
+  return rhs.Compare(lhs) > 0;
+}
+inline bool operator<(const ByteStringView& lhs, const char* rhs) {
+  return lhs < ByteStringView(rhs);
+}
 
 inline ByteString operator+(ByteStringView str1, ByteStringView str2) {
   return ByteString(str1, str2);
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp
index 8056b6f..f50e304 100644
--- a/core/fxcrt/bytestring_unittest.cpp
+++ b/core/fxcrt/bytestring_unittest.cpp
@@ -7,7 +7,9 @@
 #include <limits.h>
 
 #include <algorithm>
+#include <functional>
 #include <iterator>
+#include <set>
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
@@ -229,6 +231,19 @@
   EXPECT_FALSE(def < c_abc);
   EXPECT_TRUE(abc < v_def);
   EXPECT_FALSE(def < v_abc);
+
+  EXPECT_TRUE(v_empty < a);
+  EXPECT_TRUE(v_empty < c_a);
+
+  std::set<ByteString, std::less<>> str_set;
+  bool inserted = str_set.insert(ByteString("hello")).second;
+  ASSERT_TRUE(inserted);
+  EXPECT_TRUE(pdfium::Contains(str_set, ByteString("hello")));
+  EXPECT_TRUE(pdfium::Contains(str_set, ByteStringView("hello")));
+  EXPECT_TRUE(pdfium::Contains(str_set, "hello"));
+  EXPECT_FALSE(pdfium::Contains(str_set, ByteString("goodbye")));
+  EXPECT_FALSE(pdfium::Contains(str_set, ByteStringView("goodbye")));
+  EXPECT_FALSE(pdfium::Contains(str_set, "goodbye"));
 }
 
 TEST(ByteString, OperatorEQ) {
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp
index 017eeaf..88979e5 100644
--- a/fpdfsdk/cpdfsdk_appstream.cpp
+++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -1890,7 +1890,7 @@
   pStream->SetDataAndRemoveFilter(sContents.raw_span());
 }
 
-void CPDFSDK_AppStream::Remove(const ByteString& sAPType) {
+void CPDFSDK_AppStream::Remove(ByteStringView sAPType) {
   dict_->RemoveFor(sAPType);
 }
 
diff --git a/fpdfsdk/cpdfsdk_appstream.h b/fpdfsdk/cpdfsdk_appstream.h
index 5709ba3..89d91dd 100644
--- a/fpdfsdk/cpdfsdk_appstream.h
+++ b/fpdfsdk/cpdfsdk_appstream.h
@@ -33,7 +33,7 @@
   void Write(const ByteString& sAPType,
              const ByteString& sContents,
              const ByteString& sAPState);
-  void Remove(const ByteString& sAPType);
+  void Remove(ByteStringView sAPType);
 
   ByteString GetBackgroundAppStream() const;
   ByteString GetBorderAppStream() const;
diff --git a/fpdfsdk/fpdf_ppo.cpp b/fpdfsdk/fpdf_ppo.cpp
index b307cac..b42d1dc 100644
--- a/fpdfsdk/fpdf_ppo.cpp
+++ b/fpdfsdk/fpdf_ppo.cpp
@@ -310,7 +310,7 @@
         }
       }
       for (const auto& key : bad_keys)
-        pDict->RemoveFor(key);
+        pDict->RemoveFor(key.AsStringView());
       return true;
     }
     case CPDF_Object::kArray: {