Skip to content

Commit 0675221

Browse files
sbenzaquencopybara-github
authored andcommitted
Cast the other side of the expression to unsigned.
This way it can still handle blocks larger than 2G in 32-bit mode. PiperOrigin-RevId: 952790896
1 parent 4bd1598 commit 0675221

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

src/google/protobuf/arena_unittest.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstdint>
1717
#include <cstdlib>
1818
#include <cstring>
19+
#include <limits>
1920
#include <memory>
2021
#include <new> // IWYU pragma: keep for operator new
2122
#include <string>
@@ -72,6 +73,7 @@ using proto2_unittest::TestRepeatedString;
7273
using ::testing::AnyOf;
7374
using ::testing::ElementsAre;
7475
using ::testing::ElementsAreArray;
76+
using ::testing::Gt;
7577
using ::testing::HasSubstr;
7678
using ::testing::Optional;
7779
using ::testing::Pointee;
@@ -1786,6 +1788,34 @@ TEST(ArenaTest, StartingBlockSize) {
17861788
EXPECT_EQ(custom_arena.SpaceAllocated(), options.start_block_size);
17871789
}
17881790

1791+
TEST(ArenaTest, VeryLargeAllocIn32BitMode) {
1792+
if (sizeof(size_t) != 4) {
1793+
GTEST_SKIP() << "Only care about 32-bit mode.";
1794+
}
1795+
1796+
static absl::optional<size_t> large_allocation_size;
1797+
1798+
// Make sure we don't have bugs allocating buffers greater that ptrdiff_t max.
1799+
// It will likely fail, but it should fail in the allocator.
1800+
1801+
ArenaOptions options;
1802+
options.block_alloc = [](size_t n) {
1803+
if (n > size_t{std::numeric_limits<ptrdiff_t>::max()}) {
1804+
large_allocation_size = n;
1805+
// Just fake it. Doesn't matter.
1806+
n = 1000000;
1807+
}
1808+
return ::operator new(n);
1809+
};
1810+
options.block_dealloc = [](void* ptr, size_t) { ::operator delete(ptr); };
1811+
1812+
Arena arena(options);
1813+
void* ptr = arena.AllocateAligned(size_t{1} << 31);
1814+
EXPECT_NE(ptr, nullptr);
1815+
EXPECT_THAT(large_allocation_size,
1816+
Optional(Gt(size_t{std::numeric_limits<ptrdiff_t>::max()})));
1817+
}
1818+
17891819
TEST(ArenaTest, BlockSizeDoubling) {
17901820
Arena arena;
17911821
EXPECT_EQ(0, arena.SpaceUsed());

src/google/protobuf/serial_arena.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ class PROTOBUF_EXPORT SerialArena {
203203
ABSL_DCHECK_GE(limit_, ptr());
204204
char* ret = ptr();
205205
if (ABSL_PREDICT_FALSE(limit_ - ret < static_cast<ptrdiff_t>(n))) {
206+
// if (ABSL_PREDICT_FALSE(static_cast<size_t>(limit_ - ret) < n)) {
206207
return false;
207208
}
208209
internal::UnpoisonMemoryRegion(ret, n);

0 commit comments

Comments
 (0)