@@ -66,6 +66,11 @@ inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* unknown);
6666inline void WriteLengthDelimited (uint32_t num, absl::string_view val,
6767 UnknownFieldSet* unknown);
6868
69+ // Counts the number of varints in the array, assuming that end - ptr >= 8.
70+ // If varints are valid only up to some point, then returns at least the number
71+ // of valid varints.
72+ int CountVarintsAssumingLargeArray (const char * ptr, const char * end);
73+
6974
7075// The basic abstraction the parser is designed for is a slight modification
7176// of the ZeroCopyInputStream (ZCIS) abstraction. A ZCIS presents a serialized
@@ -1389,13 +1394,13 @@ const char* EpsCopyInputStream::ReadPackedVarintArrayWithField(
13891394 // field, than parsing, so count the number of ints first and preallocate.
13901395 // Assume that varint are valid and just count the number of bytes with
13911396 // continuation bit not set. In a valid varint there is only 1 such byte.
1392- if (( end - ptr) >= 16 && ( out.Capacity () - out.size () < end - ptr) ) {
1397+ if (end - ptr >= 16 && out.Capacity () - out.size () < end - ptr) {
13931398 int old_size = out.size ();
13941399 int count = out.Capacity () - out.size ();
13951400 // We are not guaranteed to have enough space for worst possible case,
13961401 // do an actual count and reserve.
13971402 if (count < end - ptr) {
1398- count = std::count_if (ptr, end, []( char c) { return (c & 0x80 ) == 0 ; } );
1403+ count = CountVarintsAssumingLargeArray (ptr, end);
13991404 // We can overread, so if the last byte has a continuation bit set,
14001405 // we need to account for that.
14011406 if (end[-1 ] & 0x80 ) count++;
@@ -1408,8 +1413,8 @@ const char* EpsCopyInputStream::ReadPackedVarintArrayWithField(
14081413 });
14091414 int new_size = x - out.data ();
14101415 ABSL_DCHECK_LE (new_size, old_size + count);
1411- // We may have overreserved if there was enough capacitiy .
1412- // Or encountered malformed data, so set the actaul size to
1416+ // We may have overreserved if there was enough capacity .
1417+ // Or encountered malformed data, so set the actual size to
14131418 // avoid exposing uninitialized memory.
14141419 out.Truncate (new_size);
14151420 return ptr;
0 commit comments