|
|
|
@ -8,13 +8,18 @@ |
|
|
|
|
#ifndef GOOGLE_PROTOBUF_PARSE_CONTEXT_H__ |
|
|
|
|
#define GOOGLE_PROTOBUF_PARSE_CONTEXT_H__ |
|
|
|
|
|
|
|
|
|
#include <algorithm> |
|
|
|
|
#include <climits> |
|
|
|
|
#include <cstddef> |
|
|
|
|
#include <cstdint> |
|
|
|
|
#include <cstring> |
|
|
|
|
#include <limits> |
|
|
|
|
#include <string> |
|
|
|
|
#include <type_traits> |
|
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
#include "absl/base/config.h" |
|
|
|
|
#include "absl/base/prefetch.h" |
|
|
|
|
#include "absl/log/absl_check.h" |
|
|
|
|
#include "absl/log/absl_log.h" |
|
|
|
|
#include "absl/strings/cord.h" |
|
|
|
@ -27,9 +32,11 @@ |
|
|
|
|
#include "google/protobuf/inlined_string_field.h" |
|
|
|
|
#include "google/protobuf/io/coded_stream.h" |
|
|
|
|
#include "google/protobuf/io/zero_copy_stream.h" |
|
|
|
|
#include "google/protobuf/message_lite.h" |
|
|
|
|
#include "google/protobuf/metadata_lite.h" |
|
|
|
|
#include "google/protobuf/port.h" |
|
|
|
|
#include "google/protobuf/repeated_field.h" |
|
|
|
|
#include "google/protobuf/repeated_ptr_field.h" |
|
|
|
|
#include "google/protobuf/wire_format_lite.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -103,7 +110,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
ABSL_DCHECK(ptr <= buffer_end_ + kSlopBytes); |
|
|
|
|
int count; |
|
|
|
|
if (next_chunk_ == patch_buffer_) { |
|
|
|
|
count = static_cast<int>(buffer_end_ + kSlopBytes - ptr); |
|
|
|
|
count = BytesAvailable(ptr); |
|
|
|
|
} else { |
|
|
|
|
count = size_ + static_cast<int>(buffer_end_ - ptr); |
|
|
|
|
} |
|
|
|
@ -170,14 +177,14 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PROTOBUF_NODISCARD const char* Skip(const char* ptr, int size) { |
|
|
|
|
if (size <= buffer_end_ + kSlopBytes - ptr) { |
|
|
|
|
if (size <= BytesAvailable(ptr)) { |
|
|
|
|
return ptr + size; |
|
|
|
|
} |
|
|
|
|
return SkipFallback(ptr, size); |
|
|
|
|
} |
|
|
|
|
PROTOBUF_NODISCARD const char* ReadString(const char* ptr, int size, |
|
|
|
|
std::string* s) { |
|
|
|
|
if (size <= buffer_end_ + kSlopBytes - ptr) { |
|
|
|
|
if (size <= BytesAvailable(ptr)) { |
|
|
|
|
// Fundamentally we just want to do assign to the string.
|
|
|
|
|
// However micro-benchmarks regress on string reading cases. So we copy
|
|
|
|
|
// the same logic from the old CodedInputStream ReadString. Note: as of
|
|
|
|
@ -191,7 +198,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
} |
|
|
|
|
PROTOBUF_NODISCARD const char* AppendString(const char* ptr, int size, |
|
|
|
|
std::string* s) { |
|
|
|
|
if (size <= buffer_end_ + kSlopBytes - ptr) { |
|
|
|
|
if (size <= BytesAvailable(ptr)) { |
|
|
|
|
s->append(ptr, size); |
|
|
|
|
return ptr + size; |
|
|
|
|
} |
|
|
|
@ -204,8 +211,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
|
|
|
|
|
PROTOBUF_NODISCARD const char* ReadCord(const char* ptr, int size, |
|
|
|
|
::absl::Cord* cord) { |
|
|
|
|
if (size <= std::min<int>(static_cast<int>(buffer_end_ + kSlopBytes - ptr), |
|
|
|
|
kMaxCordBytesToCopy)) { |
|
|
|
|
if (size <= std::min<int>(BytesAvailable(ptr), kMaxCordBytesToCopy)) { |
|
|
|
|
*cord = absl::string_view(ptr, size); |
|
|
|
|
return ptr + size; |
|
|
|
|
} |
|
|
|
@ -345,6 +351,14 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
// systems. TODO do we need to set this as build flag?
|
|
|
|
|
enum { kSafeStringSize = 50000000 }; |
|
|
|
|
|
|
|
|
|
int BytesAvailable(const char* ptr) const { |
|
|
|
|
ABSL_DCHECK_NE(ptr, nullptr); |
|
|
|
|
ptrdiff_t available = buffer_end_ + kSlopBytes - ptr; |
|
|
|
|
ABSL_DCHECK_GE(available, 0); |
|
|
|
|
ABSL_DCHECK_LE(available, INT_MAX); |
|
|
|
|
return static_cast<int>(available); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Advances to next buffer chunk returns a pointer to the same logical place
|
|
|
|
|
// in the stream as set by overrun. Overrun indicates the position in the slop
|
|
|
|
|
// region the parse was left (0 <= overrun <= kSlopBytes). Returns true if at
|
|
|
|
@ -382,7 +396,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
|
|
|
|
|
template <typename A> |
|
|
|
|
const char* AppendSize(const char* ptr, int size, const A& append) { |
|
|
|
|
int chunk_size = static_cast<int>(buffer_end_ + kSlopBytes - ptr); |
|
|
|
|
int chunk_size = BytesAvailable(ptr); |
|
|
|
|
do { |
|
|
|
|
ABSL_DCHECK(size > chunk_size); |
|
|
|
|
if (next_chunk_ == nullptr) return nullptr; |
|
|
|
@ -396,7 +410,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
ptr = Next(); |
|
|
|
|
if (ptr == nullptr) return nullptr; // passed the limit
|
|
|
|
|
ptr += kSlopBytes; |
|
|
|
|
chunk_size = static_cast<int>(buffer_end_ + kSlopBytes - ptr); |
|
|
|
|
chunk_size = BytesAvailable(ptr); |
|
|
|
|
} while (size > chunk_size); |
|
|
|
|
append(ptr, size); |
|
|
|
|
return ptr + size; |
|
|
|
@ -411,7 +425,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { |
|
|
|
|
const char* AppendUntilEnd(const char* ptr, const A& append) { |
|
|
|
|
if (ptr - buffer_end_ > limit_) return nullptr; |
|
|
|
|
while (limit_ > kSlopBytes) { |
|
|
|
|
size_t chunk_size = buffer_end_ + kSlopBytes - ptr; |
|
|
|
|
size_t chunk_size = BytesAvailable(ptr); |
|
|
|
|
append(ptr, chunk_size); |
|
|
|
|
ptr = Next(); |
|
|
|
|
if (ptr == nullptr) return limit_end_; |
|
|
|
@ -1163,7 +1177,7 @@ template <typename T> |
|
|
|
|
const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, |
|
|
|
|
RepeatedField<T>* out) { |
|
|
|
|
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
|
|
|
|
int nbytes = static_cast<int>(buffer_end_ + kSlopBytes - ptr); |
|
|
|
|
int nbytes = BytesAvailable(ptr); |
|
|
|
|
while (size > nbytes) { |
|
|
|
|
int num = nbytes / sizeof(T); |
|
|
|
|
int old_entries = out->size(); |
|
|
|
@ -1181,7 +1195,7 @@ const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, |
|
|
|
|
ptr = Next(); |
|
|
|
|
if (ptr == nullptr) return nullptr; |
|
|
|
|
ptr += kSlopBytes - (nbytes - block_size); |
|
|
|
|
nbytes = static_cast<int>(buffer_end_ + kSlopBytes - ptr); |
|
|
|
|
nbytes = BytesAvailable(ptr); |
|
|
|
|
} |
|
|
|
|
int num = size / sizeof(T); |
|
|
|
|
int block_size = num * sizeof(T); |
|
|
|
|