Provide an escape hatch for structs in Data Partition
As encountered in
https://pdfium-review.googlesource.com/c/pdfium/+/98291
Change-Id: Ic427364f7d1f17241e39df429bd8cf2f4db1d915
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98310
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/fx_memory_wrappers.h b/core/fxcrt/fx_memory_wrappers.h
index 23a5b47..de8042c 100644
--- a/core/fxcrt/fx_memory_wrappers.h
+++ b/core/fxcrt/fx_memory_wrappers.h
@@ -16,6 +16,17 @@
inline void operator()(void* ptr) const { FX_Free(ptr); }
};
+// Escape hatch mechanism to allow non_arithmetic types into data partition.
+template <typename T>
+struct IsFXDataPartitionException : std::false_type {};
+
+// Use with caution. No further checks are made to see if `T` is appropriate
+// for the Data Partition (e.g. no pointers, strings, vtables, etc.). This
+// declaration must occur in the top-level namespace.
+#define FX_DATA_PARTITION_EXCEPTION(T) \
+ template <> \
+ struct IsFXDataPartitionException<T> : std::true_type {}
+
// Allocators for mapping STL containers onto Partition Alloc.
// Otherwise, replacing e.g. the FX_AllocUninit/FX_Free pairs with STL may
// undo some of the nice segregation that we get from PartitionAlloc.
@@ -23,7 +34,8 @@
struct FxPartitionAllocAllocator {
public:
#if !defined(COMPILER_MSVC) || defined(NDEBUG)
- static_assert(std::is_arithmetic<T>::value,
+ static_assert(std::is_arithmetic<T>::value ||
+ IsFXDataPartitionException<T>::value,
"Only numeric types allowed in this partition");
#endif
@@ -77,7 +89,8 @@
// Used to put backing store for std::vector<> and such into the
// general partition, ensuring they contain data only.
template <typename T,
- typename = std::enable_if_t<std::is_arithmetic<T>::value, T>>
+ typename = std::enable_if_t<std::is_arithmetic<T>::value ||
+ IsFXDataPartitionException<T>::value>>
using FxAllocAllocator =
FxPartitionAllocAllocator<T, pdfium::internal::AllocOrDie>;
diff --git a/core/fxcrt/fx_memory_wrappers_unittest.cpp b/core/fxcrt/fx_memory_wrappers_unittest.cpp
index f9bee32..5476125 100644
--- a/core/fxcrt/fx_memory_wrappers_unittest.cpp
+++ b/core/fxcrt/fx_memory_wrappers_unittest.cpp
@@ -12,6 +12,17 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace {
+
+struct OnlyNumbers {
+ int x;
+ int y;
+};
+
+} // namespace
+
+FX_DATA_PARTITION_EXCEPTION(OnlyNumbers);
+
TEST(fxcrt, FxFreeDeleter) {
std::unique_ptr<int, FxFreeDeleter> empty(nullptr);
std::unique_ptr<int, FxFreeDeleter> thing(FX_Alloc(int, 1));
@@ -46,3 +57,10 @@
str << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
str << 42.0f;
}
+
+TEST(fxcrt, FxAllocAllocatorStructException) {
+ std::vector<OnlyNumbers, FxAllocAllocator<OnlyNumbers>> vec;
+ vec.push_back({42, 73});
+ EXPECT_EQ(vec.back().x, 42);
+ EXPECT_EQ(vec.back().y, 73);
+}