Skip to content
This repository was archived by the owner on Dec 9, 2025. It is now read-only.

Commit 02cf7aa

Browse files
ericsalocopybara-github
authored andcommitted
upb_Array_Resize() now correctly clears new values
PiperOrigin-RevId: 496255949
1 parent 8797415 commit 02cf7aa

File tree

6 files changed

+94
-18
lines changed

6 files changed

+94
-18
lines changed

BUILD

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,16 @@ cc_test(
681681
],
682682
)
683683

684+
cc_test(
685+
name = "collections_test",
686+
srcs = ["upb/collections/test.cc"],
687+
deps = [
688+
":collections",
689+
":upb",
690+
"@com_google_googletest//:gtest_main",
691+
],
692+
)
693+
684694
cc_test(
685695
name = "message_test",
686696
srcs = ["upb/message/test.cc"],

upb/collections/array.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,16 @@ bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
7979

8080
void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx,
8181
size_t count) {
82+
const int lg2 = arr->data & 7;
8283
char* data = _upb_array_ptr(arr);
83-
int lg2 = arr->data & 7;
8484
memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2);
8585
}
8686

8787
bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
8888
upb_Arena* arena) {
8989
UPB_ASSERT(i <= arr->size);
9090
UPB_ASSERT(count + arr->size >= count);
91-
size_t oldsize = arr->size;
91+
const size_t oldsize = arr->size;
9292
if (!upb_Array_Resize(arr, arr->size + count, arena)) {
9393
return false;
9494
}
@@ -101,15 +101,25 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
101101
* |------------|XXXXXXXX|--------|
102102
*/
103103
void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) {
104-
size_t end = i + count;
104+
const size_t end = i + count;
105105
UPB_ASSERT(i <= end);
106106
UPB_ASSERT(end <= arr->size);
107107
upb_Array_Move(arr, i, end, arr->size - end);
108108
arr->size -= count;
109109
}
110110

111111
bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) {
112-
return _upb_Array_Resize(arr, size, arena);
112+
const size_t oldsize = arr->size;
113+
if (UPB_UNLIKELY(!_upb_Array_ResizeUninitialized(arr, size, arena))) {
114+
return false;
115+
}
116+
const size_t newsize = arr->size;
117+
if (newsize > oldsize) {
118+
const int lg2 = arr->data & 7;
119+
char* data = _upb_array_ptr(arr);
120+
memset(data + (oldsize << lg2), 0, (newsize - oldsize) << lg2);
121+
}
122+
return true;
113123
}
114124

115125
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
@@ -126,10 +136,7 @@ bool _upb_array_realloc(upb_Array* arr, size_t min_capacity, upb_Arena* arena) {
126136

127137
new_bytes = new_capacity << elem_size_lg2;
128138
ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
129-
130-
if (!ptr) {
131-
return false;
132-
}
139+
if (!ptr) return false;
133140

134141
arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
135142
arr->capacity = new_capacity;
@@ -150,8 +157,9 @@ static upb_Array* getorcreate_array(upb_Array** arr_ptr, int elem_size_lg2,
150157
void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
151158
int elem_size_lg2, upb_Arena* arena) {
152159
upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
153-
return arr && _upb_Array_Resize(arr, size, arena) ? _upb_array_ptr(arr)
154-
: NULL;
160+
return arr && _upb_Array_ResizeUninitialized(arr, size, arena)
161+
? _upb_array_ptr(arr)
162+
: NULL;
155163
}
156164

157165
bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
@@ -160,10 +168,7 @@ bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
160168
if (!arr) return false;
161169

162170
size_t elems = arr->size;
163-
164-
if (!_upb_Array_Resize(arr, elems + 1, arena)) {
165-
return false;
166-
}
171+
if (!_upb_Array_ResizeUninitialized(arr, elems + 1, arena)) return false;
167172

168173
char* data = _upb_array_ptr(arr);
169174
memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);

upb/collections/array.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ UPB_API bool upb_Array_Insert(upb_Array* array, size_t i, size_t count,
7272
// REQUIRES: `i + count <= upb_Array_Size(arr)`
7373
UPB_API void upb_Array_Delete(upb_Array* array, size_t i, size_t count);
7474

75-
// Changes the size of a vector. New elements are initialized to empty/0.
75+
// Changes the size of a vector. New elements are initialized to NULL/0.
7676
// Returns false on allocation failure.
7777
UPB_API bool upb_Array_Resize(upb_Array* array, size_t size, upb_Arena* arena);
7878

upb/collections/array_internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size,
9595
return true;
9696
}
9797

98-
UPB_INLINE bool _upb_Array_Resize(upb_Array* arr, size_t size,
99-
upb_Arena* arena) {
98+
// Resize without initializing new elements.
99+
UPB_INLINE bool _upb_Array_ResizeUninitialized(upb_Array* arr, size_t size,
100+
upb_Arena* arena) {
100101
if (!_upb_array_reserve(arr, size, arena)) return false;
101102
arr->size = size;
102103
return true;

upb/collections/test.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2009-2021, Google LLC
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of Google LLC nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
#include "gtest/gtest.h"
29+
#include "upb/base/descriptor_constants.h"
30+
#include "upb/collections/array.h"
31+
#include "upb/upb.hpp"
32+
33+
TEST(CollectionsTest, Arrays) {
34+
upb::Arena arena;
35+
upb::Status status;
36+
37+
upb_Array* array = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
38+
EXPECT_TRUE(array);
39+
40+
for (int i = 0; i < 10; i++) {
41+
upb_MessageValue mv = {.int32_val = 3 * i};
42+
upb_Array_Append(array, mv, arena.ptr());
43+
EXPECT_EQ(upb_Array_Size(array), i + 1);
44+
EXPECT_EQ(upb_Array_Get(array, i).int32_val, 3 * i);
45+
}
46+
47+
upb_Array_Resize(array, 12, arena.ptr());
48+
EXPECT_EQ(upb_Array_Get(array, 10).int32_val, 0);
49+
EXPECT_EQ(upb_Array_Get(array, 11).int32_val, 0);
50+
51+
upb_Array_Resize(array, 4, arena.ptr());
52+
EXPECT_EQ(upb_Array_Size(array), 4);
53+
54+
upb_Array_Resize(array, 6, arena.ptr());
55+
EXPECT_EQ(upb_Array_Size(array), 6);
56+
57+
EXPECT_EQ(upb_Array_Get(array, 3).int32_val, 9);
58+
EXPECT_EQ(upb_Array_Get(array, 4).int32_val, 0);
59+
EXPECT_EQ(upb_Array_Get(array, 5).int32_val, 0);
60+
}

upb/wire/decode_fast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ TAGBYTES(p)
563563
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
564564
} \
565565
} else { \
566-
_upb_Array_Resize(arr, elems, &d->arena); \
566+
_upb_Array_ResizeUninitialized(arr, elems, &d->arena); \
567567
} \
568568
\
569569
char* dst = _upb_array_ptr(arr); \

0 commit comments

Comments
 (0)