K. Moon | 832a694 | 2022-10-31 20:11:31 +0000 | [diff] [blame] | 1 | // Copyright 2015 The PDFium Authors |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Tom Sepez | a9deea9 | 2017-04-25 10:37:47 -0700 | [diff] [blame] | 5 | #include "core/fxcrt/fx_memory.h" |
| 6 | |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 7 | #include <limits> |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 8 | #include <memory> |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 9 | |
Lei Zhang | bc10648 | 2019-05-30 23:55:19 +0000 | [diff] [blame] | 10 | #include "build/build_config.h" |
Tom Sepez | 2786390 | 2024-03-28 21:53:49 +0000 | [diff] [blame] | 11 | #include "core/fxcrt/compiler_specific.h" |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 12 | #include "testing/gtest/include/gtest/gtest.h" |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 13 | |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 14 | #if defined(PDF_USE_PARTITION_ALLOC) |
Arthur Sonzogni | 3476811 | 2023-10-06 16:53:00 +0000 | [diff] [blame] | 15 | #include "partition_alloc/partition_address_space.h" |
Arthur Sonzogni | 159bccb | 2023-08-29 08:59:38 +0000 | [diff] [blame] | 16 | #endif |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 17 | |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 18 | namespace { |
| 19 | |
Lei Zhang | d6f9fe0 | 2022-11-03 17:41:01 +0000 | [diff] [blame] | 20 | constexpr size_t kMaxByteAlloc = std::numeric_limits<size_t>::max(); |
| 21 | constexpr size_t kMaxIntAlloc = kMaxByteAlloc / sizeof(int); |
| 22 | constexpr size_t kOverflowIntAlloc = kMaxIntAlloc + 100; |
| 23 | constexpr size_t kWidth = 640; |
| 24 | constexpr size_t kOverflowIntAlloc2D = kMaxIntAlloc / kWidth + 10; |
| 25 | constexpr size_t kCloseToMaxIntAlloc = kMaxIntAlloc - 100; |
| 26 | constexpr size_t kCloseToMaxByteAlloc = kMaxByteAlloc - 100; |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 27 | |
| 28 | } // namespace |
| 29 | |
Tom Sepez | 57eea9a | 2019-11-19 21:37:47 +0000 | [diff] [blame] | 30 | TEST(fxcrt, FX_AllocZero) { |
| 31 | uint8_t* ptr = FX_Alloc(uint8_t, 0); |
Tom Sepez | af35239 | 2019-11-21 18:48:08 +0000 | [diff] [blame] | 32 | uint8_t* ptr2 = FX_Alloc(uint8_t, 0); |
Lei Zhang | 144da5d | 2019-12-13 17:39:08 +0000 | [diff] [blame] | 33 | EXPECT_TRUE(ptr); // Malloc(0) is distinguishable from OOM. |
Tom Sepez | af35239 | 2019-11-21 18:48:08 +0000 | [diff] [blame] | 34 | EXPECT_NE(ptr, ptr2); // Each malloc(0) is distinguishable. |
| 35 | FX_Free(ptr2); |
Tom Sepez | 57eea9a | 2019-11-19 21:37:47 +0000 | [diff] [blame] | 36 | FX_Free(ptr); |
| 37 | } |
| 38 | |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 39 | TEST(fxcrt, FXAllocOOM) { |
| 40 | EXPECT_DEATH_IF_SUPPORTED((void)FX_Alloc(int, kCloseToMaxIntAlloc), ""); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 41 | |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 42 | int* ptr = FX_Alloc(int, 1); |
| 43 | EXPECT_TRUE(ptr); |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 44 | EXPECT_DEATH_IF_SUPPORTED((void)FX_Realloc(int, ptr, kCloseToMaxIntAlloc), |
| 45 | ""); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 46 | FX_Free(ptr); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | TEST(fxcrt, FX_AllocOverflow) { |
weili | 14f5aeb | 2016-04-22 19:18:31 -0700 | [diff] [blame] | 50 | // |ptr| needs to be defined and used to avoid Clang optimizes away the |
| 51 | // FX_Alloc() statement overzealously for optimized builds. |
| 52 | int* ptr = nullptr; |
| 53 | EXPECT_DEATH_IF_SUPPORTED(ptr = FX_Alloc(int, kOverflowIntAlloc), "") << ptr; |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 54 | |
weili | 14f5aeb | 2016-04-22 19:18:31 -0700 | [diff] [blame] | 55 | ptr = FX_Alloc(int, 1); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 56 | EXPECT_TRUE(ptr); |
Ryan Harrison | 6cec70a | 2018-06-05 14:06:10 +0000 | [diff] [blame] | 57 | EXPECT_DEATH_IF_SUPPORTED((void)FX_Realloc(int, ptr, kOverflowIntAlloc), ""); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 58 | FX_Free(ptr); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 59 | } |
| 60 | |
Tom Sepez | 038cd08 | 2015-05-18 14:29:22 -0700 | [diff] [blame] | 61 | TEST(fxcrt, FX_AllocOverflow2D) { |
weili | 14f5aeb | 2016-04-22 19:18:31 -0700 | [diff] [blame] | 62 | // |ptr| needs to be defined and used to avoid Clang optimizes away the |
| 63 | // FX_Alloc() statement overzealously for optimized builds. |
| 64 | int* ptr = nullptr; |
| 65 | EXPECT_DEATH_IF_SUPPORTED(ptr = FX_Alloc2D(int, kWidth, kOverflowIntAlloc2D), |
| 66 | "") |
| 67 | << ptr; |
Tom Sepez | 038cd08 | 2015-05-18 14:29:22 -0700 | [diff] [blame] | 68 | } |
| 69 | |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 70 | TEST(fxcrt, FXTryAllocOOM) { |
| 71 | EXPECT_FALSE(FX_TryAlloc(int, kCloseToMaxIntAlloc)); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 72 | |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 73 | int* ptr = FX_Alloc(int, 1); |
| 74 | EXPECT_TRUE(ptr); |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 75 | EXPECT_FALSE(FX_TryRealloc(int, ptr, kCloseToMaxIntAlloc)); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 76 | FX_Free(ptr); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 77 | } |
| 78 | |
Lei Zhang | bc10648 | 2019-05-30 23:55:19 +0000 | [diff] [blame] | 79 | #if !defined(COMPILER_GCC) |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 80 | TEST(fxcrt, FX_TryAllocOverflow) { |
weili | 14f5aeb | 2016-04-22 19:18:31 -0700 | [diff] [blame] | 81 | // |ptr| needs to be defined and used to avoid Clang optimizes away the |
| 82 | // calloc() statement overzealously for optimized builds. |
| 83 | int* ptr = (int*)calloc(sizeof(int), kOverflowIntAlloc); |
| 84 | EXPECT_FALSE(ptr) << ptr; |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 85 | |
weili | 14f5aeb | 2016-04-22 19:18:31 -0700 | [diff] [blame] | 86 | ptr = FX_Alloc(int, 1); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 87 | EXPECT_TRUE(ptr); |
Tom Sepez | 26b2867 | 2018-09-13 18:18:44 +0000 | [diff] [blame] | 88 | *ptr = 1492; // Arbitrary sentinel. |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 89 | EXPECT_FALSE(FX_TryRealloc(int, ptr, kOverflowIntAlloc)); |
Tom Sepez | 26b2867 | 2018-09-13 18:18:44 +0000 | [diff] [blame] | 90 | EXPECT_EQ(1492, *ptr); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 91 | FX_Free(ptr); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 92 | } |
Lei Zhang | a41801e | 2018-08-23 21:59:33 +0000 | [diff] [blame] | 93 | #endif |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 94 | |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 95 | TEST(fxcrt, FXMEMDefaultOOM) { |
| 96 | EXPECT_FALSE(FXMEM_DefaultAlloc(kCloseToMaxByteAlloc)); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 97 | |
Lei Zhang | b810da2 | 2017-11-03 22:18:18 +0000 | [diff] [blame] | 98 | void* ptr = FXMEM_DefaultAlloc(1); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 99 | EXPECT_TRUE(ptr); |
Lei Zhang | 204d96e | 2022-11-02 21:39:24 +0000 | [diff] [blame] | 100 | EXPECT_FALSE(FXMEM_DefaultRealloc(ptr, kCloseToMaxByteAlloc)); |
Lei Zhang | b810da2 | 2017-11-03 22:18:18 +0000 | [diff] [blame] | 101 | FXMEM_DefaultFree(ptr); |
Tom Sepez | ed099be | 2015-05-15 16:30:52 -0700 | [diff] [blame] | 102 | } |
Tom Sepez | 30dc6aa | 2018-09-25 20:06:50 +0000 | [diff] [blame] | 103 | |
Lei Zhang | a7430c1 | 2020-04-01 20:57:14 +0000 | [diff] [blame] | 104 | TEST(fxcrt, AllocZeroesMemory) { |
| 105 | uint8_t* ptr = FX_Alloc(uint8_t, 32); |
| 106 | ASSERT_TRUE(ptr); |
Tom Sepez | 2786390 | 2024-03-28 21:53:49 +0000 | [diff] [blame] | 107 | for (size_t i = 0; i < 32; ++i) { |
Tom Sepez | 2224550 | 2024-06-13 00:28:00 +0000 | [diff] [blame] | 108 | // SAFETY: required for testing, length and loop bounds 32. |
| 109 | EXPECT_EQ(0, UNSAFE_BUFFERS(ptr[i])); |
Tom Sepez | 2786390 | 2024-03-28 21:53:49 +0000 | [diff] [blame] | 110 | } |
Lei Zhang | a7430c1 | 2020-04-01 20:57:14 +0000 | [diff] [blame] | 111 | FX_Free(ptr); |
| 112 | } |
| 113 | |
Tom Sepez | 30dc6aa | 2018-09-25 20:06:50 +0000 | [diff] [blame] | 114 | TEST(fxcrt, FXAlign) { |
| 115 | static_assert(std::numeric_limits<size_t>::max() % 2 == 1, |
| 116 | "numeric limit must be odd for this test"); |
| 117 | |
| 118 | size_t s0 = 0; |
| 119 | size_t s1 = 1; |
| 120 | size_t s2 = 2; |
| 121 | size_t sbig = std::numeric_limits<size_t>::max() - 2; |
| 122 | EXPECT_EQ(0u, FxAlignToBoundary<2>(s0)); |
| 123 | EXPECT_EQ(2u, FxAlignToBoundary<2>(s1)); |
| 124 | EXPECT_EQ(2u, FxAlignToBoundary<2>(s2)); |
| 125 | EXPECT_EQ(std::numeric_limits<size_t>::max() - 1, FxAlignToBoundary<2>(sbig)); |
| 126 | |
| 127 | int i0 = 0; |
| 128 | int i511 = 511; |
| 129 | int i512 = 512; |
| 130 | int ineg = -513; |
| 131 | EXPECT_EQ(0, FxAlignToBoundary<512>(i0)); |
| 132 | EXPECT_EQ(512, FxAlignToBoundary<512>(i511)); |
| 133 | EXPECT_EQ(512, FxAlignToBoundary<512>(i512)); |
| 134 | EXPECT_EQ(-512, FxAlignToBoundary<512>(ineg)); |
| 135 | } |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 136 | |
| 137 | #if defined(PDF_USE_PARTITION_ALLOC) |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 138 | #if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && \ |
| 139 | PA_BUILDFLAG(HAS_64_BIT_POINTERS) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 140 | TEST(FxMemory, NewOperatorResultIsPA) { |
| 141 | auto obj = std::make_unique<double>(4.0); |
| 142 | EXPECT_TRUE(partition_alloc::IsManagedByPartitionAlloc( |
| 143 | reinterpret_cast<uintptr_t>(obj.get()))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 144 | #if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 145 | EXPECT_TRUE(partition_alloc::IsManagedByPartitionAllocBRPPool( |
| 146 | reinterpret_cast<uintptr_t>(obj.get()))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 147 | #endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 148 | } |
| 149 | |
| 150 | TEST(FxMemory, MallocResultIsPA) { |
| 151 | void* obj = malloc(16); |
| 152 | EXPECT_TRUE(partition_alloc::IsManagedByPartitionAlloc( |
| 153 | reinterpret_cast<uintptr_t>(obj))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 154 | #if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 155 | EXPECT_TRUE(partition_alloc::IsManagedByPartitionAllocBRPPool( |
| 156 | reinterpret_cast<uintptr_t>(obj))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 157 | #endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 158 | free(obj); |
| 159 | } |
| 160 | |
| 161 | TEST(FxMemory, StackObjectIsNotPA) { |
| 162 | int x = 3; |
| 163 | EXPECT_FALSE(partition_alloc::IsManagedByPartitionAlloc( |
| 164 | reinterpret_cast<uintptr_t>(&x))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 165 | #if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 166 | EXPECT_FALSE(partition_alloc::IsManagedByPartitionAllocBRPPool( |
| 167 | reinterpret_cast<uintptr_t>(&x))); |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 168 | #endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 169 | } |
Arthur Sonzogni | 151ec02 | 2024-05-23 16:32:24 +0000 | [diff] [blame] | 170 | #endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && |
| 171 | // PA_BUILDFLAG(HAS_64_BIT_POINTERS) |
Tom Sepez | 45e5d5e | 2023-08-01 01:48:40 +0000 | [diff] [blame] | 172 | #endif // defined(PDF_USE_PARTITION_ALLOC) |