Move ScopedSetInsertion to core/fxcrt/scoped_set_insertion.h.
Move it out of third_party/base/stl_util.h since it does not exist in
Chromium's base/stl_util.h. Along the way:
- Add a unit test.
- Disallow copy, assign, and heap allocations.
Change-Id: Ie04cb53059805117da6b9906063f34d96d0629e7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/80350
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 8da89a6..13061b5 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -33,6 +33,7 @@
#include "core/fxcodec/icc/iccmodule.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/maybe_owned.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
#include "third_party/base/notreached.h"
@@ -500,7 +501,7 @@
if (pdfium::Contains(*pVisited, pObj))
return nullptr;
- pdfium::ScopedSetInsertion<const CPDF_Object*> insertion(pVisited, pObj);
+ ScopedSetInsertion<const CPDF_Object*> insertion(pVisited, pObj);
if (pObj->IsName())
return ColorspaceFromName(pObj->GetString());
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 38c41ac..921a3c8 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -32,6 +32,7 @@
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_substfont.h"
@@ -262,8 +263,7 @@
if (pdfium::Contains(*pVisitedInternal, pCSObj))
return nullptr;
- pdfium::ScopedSetInsertion<const CPDF_Object*> insertion(pVisitedInternal,
- pCSObj);
+ ScopedSetInsertion<const CPDF_Object*> insertion(pVisitedInternal, pCSObj);
if (pCSObj->IsName()) {
ByteString name = pCSObj->GetString();
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index ae0b8fb..ed2283b 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "third_party/base/stl_util.h"
namespace {
@@ -51,7 +52,7 @@
if (pdfium::Contains(*pVisited, pFuncObj))
return nullptr;
- pdfium::ScopedSetInsertion<const CPDF_Object*> insertion(pVisited, pFuncObj);
+ ScopedSetInsertion<const CPDF_Object*> insertion(pVisited, pFuncObj);
int iType = -1;
if (const CPDF_Stream* pStream = pFuncObj->AsStream())
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 9435f40..e9422a0 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -36,6 +36,7 @@
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxcrt/autonuller.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "third_party/base/check.h"
#include "third_party/base/no_destructor.h"
@@ -1498,8 +1499,8 @@
m_StreamStartOffsets = stream_start_offsets;
- pdfium::ScopedSetInsertion<const uint8_t*> scopedInsert(m_ParsedSet.Get(),
- pDataStart);
+ ScopedSetInsertion<const uint8_t*> scopedInsert(m_ParsedSet.Get(),
+ pDataStart);
uint32_t init_obj_count = m_pObjectHolder->GetPageObjectCount();
AutoNuller<std::unique_ptr<CPDF_StreamParser>> auto_clearer(&m_pSyntax);
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index b80043f..4a403fe 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -16,6 +16,7 @@
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fxcodec/jbig2/JBig2_DocumentContext.h"
#include "core/fxcrt/fx_codepage.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "third_party/base/check.h"
#include "third_party/base/stl_util.h"
@@ -38,8 +39,7 @@
continue;
if (pKid->KeyExist("Kids")) {
// Use |visited_pages| to help detect circular references of pages.
- pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages,
- pKid);
+ ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, pKid);
count += CountPages(pKid, visited_pages);
} else {
// This page is a leaf node.
@@ -424,7 +424,7 @@
if (pdfium::Contains(*pVisited, pKid))
return false;
- pdfium::ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid);
+ ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid);
if (!InsertDeletePDFPage(pKid, nPagesToGo, pPageDict, bInsert, pVisited))
return false;
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index b269776..f131121 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -28,6 +28,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/scoped_set_insertion.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
#include "third_party/base/notreached.h"
@@ -865,7 +866,7 @@
if (pdfium::Contains(m_ParsingObjNums, objnum))
return nullptr;
- pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
+ ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
if (GetObjectType(objnum) == ObjectType::kNotCompressed) {
FX_FILESIZE pos = GetObjectPositionOrZero(objnum);
if (pos <= 0)
@@ -888,8 +889,7 @@
if (pdfium::Contains(m_ParsingObjNums, object_number))
return nullptr;
- pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums,
- object_number);
+ ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, object_number);
auto it = m_ObjectStreamMap.find(object_number);
if (it != m_ObjectStreamMap.end())
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index a9ba304..c3220b7 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -62,6 +62,7 @@
"pauseindicator_iface.h",
"retain_ptr.h",
"retained_tree_node.h",
+ "scoped_set_insertion.h",
"shared_copy_on_write.h",
"string_data_template.cpp",
"string_data_template.h",
@@ -155,6 +156,7 @@
"pdfium_span_unittest.cpp",
"retain_ptr_unittest.cpp",
"retained_tree_node_unittest.cpp",
+ "scoped_set_insertion_unittest.cpp",
"shared_copy_on_write_unittest.cpp",
"string_pool_template_unittest.cpp",
"tree_node_unittest.cpp",
diff --git a/core/fxcrt/scoped_set_insertion.h b/core/fxcrt/scoped_set_insertion.h
new file mode 100644
index 0000000..890e75f
--- /dev/null
+++ b/core/fxcrt/scoped_set_insertion.h
@@ -0,0 +1,41 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXCRT_SCOPED_SET_INSERTION_H_
+#define CORE_FXCRT_SCOPED_SET_INSERTION_H_
+
+#include <set>
+#include <utility>
+
+#include "third_party/base/check.h"
+
+namespace fxcrt {
+
+// Track the addition of an object to a set, removing it automatically when
+// the ScopedSetInsertion goes out of scope.
+template <typename T>
+class ScopedSetInsertion {
+ public:
+ ScopedSetInsertion(std::set<T>* org_set, const T& elem)
+ : set_(org_set), insert_results_(set_->insert(elem)) {
+ CHECK(insert_results_.second);
+ }
+ ScopedSetInsertion(const ScopedSetInsertion&) = delete;
+ ScopedSetInsertion& operator=(const ScopedSetInsertion&) = delete;
+ ~ScopedSetInsertion() { set_->erase(insert_results_.first); }
+
+ // Stack allocated only.
+ void* operator new(size_t) = delete;
+ void* operator new(size_t, void*) = delete;
+
+ private:
+ std::set<T>* const set_;
+ const std::pair<typename std::set<T>::iterator, bool> insert_results_;
+};
+
+} // namespace fxcrt
+
+using fxcrt::ScopedSetInsertion;
+
+#endif // CORE_FXCRT_SCOPED_SET_INSERTION_H_
diff --git a/core/fxcrt/scoped_set_insertion_unittest.cpp b/core/fxcrt/scoped_set_insertion_unittest.cpp
new file mode 100644
index 0000000..ad7e232
--- /dev/null
+++ b/core/fxcrt/scoped_set_insertion_unittest.cpp
@@ -0,0 +1,24 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcrt/scoped_set_insertion.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(fxcrt, ScopedSetInsertion) {
+ std::set<int> container;
+ {
+ ScopedSetInsertion<int> insertion(&container, 5);
+ EXPECT_THAT(container, testing::UnorderedElementsAreArray({5}));
+
+ {
+ ScopedSetInsertion<int> insertion2(&container, 6);
+ EXPECT_THAT(container, testing::UnorderedElementsAreArray({5, 6}));
+ }
+
+ EXPECT_THAT(container, testing::UnorderedElementsAreArray({5}));
+ }
+ EXPECT_TRUE(container.empty());
+}
diff --git a/third_party/base/stl_util.h b/third_party/base/stl_util.h
index 17fdcd8..40ae622 100644
--- a/third_party/base/stl_util.h
+++ b/third_party/base/stl_util.h
@@ -8,12 +8,9 @@
#include <algorithm>
#include <iterator>
#include <memory>
-#include <set>
#include <type_traits>
-#include <utility>
#include <vector>
-#include "third_party/base/check.h"
#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/numerics/safe_math.h"
#include "third_party/base/template_util.h"
@@ -136,22 +133,6 @@
return index >= 0 && index < CollectionSize<IndexType>(collection);
}
-// Track the addition of an object to a set, removing it automatically when
-// the ScopedSetInsertion goes out of scope.
-template <typename T>
-class ScopedSetInsertion {
- public:
- ScopedSetInsertion(std::set<T>* org_set, const T& elem)
- : set_(org_set), insert_results_(set_->insert(elem)) {
- CHECK(insert_results_.second);
- }
- ~ScopedSetInsertion() { set_->erase(insert_results_.first); }
-
- private:
- std::set<T>* const set_;
- const std::pair<typename std::set<T>::iterator, bool> insert_results_;
-};
-
// std::clamp(), some day.
template <class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {