aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/io/coded_stream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/io/coded_stream.cc')
-rw-r--r--src/google/protobuf/io/coded_stream.cc90
1 files changed, 21 insertions, 69 deletions
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 3c2e0fbd..0851ff0c 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -76,10 +76,6 @@ CodedInputStream::~CodedInputStream() {
if (input_ != NULL) {
BackUpInputToCurrentPosition();
}
-
- if (total_bytes_warning_threshold_ == -2) {
- GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
- }
}
// Static.
@@ -123,21 +119,15 @@ CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
Limit old_limit = current_limit_;
// security: byte_limit is possibly evil, so check for negative values
- // and overflow.
- if (byte_limit >= 0 &&
- byte_limit <= INT_MAX - current_position) {
+ // and overflow. Also check that the new requested limit is before the
+ // previous limit; otherwise we continue to enforce the previous limit.
+ if (GOOGLE_PREDICT_TRUE(byte_limit >= 0 &&
+ byte_limit <= INT_MAX - current_position &&
+ byte_limit < current_limit_ - current_position)) {
current_limit_ = current_position + byte_limit;
- } else {
- // Negative or overflow.
- current_limit_ = INT_MAX;
+ RecomputeBufferLimits();
}
- // We need to enforce all limits, not just the new one, so if the previous
- // limit was before the new requested limit, we continue to enforce the
- // previous limit.
- current_limit_ = std::min(current_limit_, old_limit);
-
- RecomputeBufferLimits();
return old_limit;
}
@@ -183,18 +173,11 @@ int CodedInputStream::BytesUntilLimit() const {
return current_limit_ - current_position;
}
-void CodedInputStream::SetTotalBytesLimit(
- int total_bytes_limit, int warning_threshold) {
+void CodedInputStream::SetTotalBytesLimit(int total_bytes_limit) {
// Make sure the limit isn't already past, since this could confuse other
// code.
int current_position = CurrentPosition();
total_bytes_limit_ = std::max(current_position, total_bytes_limit);
- if (warning_threshold >= 0) {
- total_bytes_warning_threshold_ = warning_threshold;
- } else {
- // warning_threshold is negative
- total_bytes_warning_threshold_ = -1;
- }
RecomputeBufferLimits();
}
@@ -211,17 +194,7 @@ void CodedInputStream::PrintTotalBytesLimitError() {
"in google/protobuf/io/coded_stream.h.";
}
-bool CodedInputStream::Skip(int count) {
- if (count < 0) return false; // security: count is often user-supplied
-
- const int original_buffer_size = BufferSize();
-
- if (count <= original_buffer_size) {
- // Just skipping within the current buffer. Easy.
- Advance(count);
- return true;
- }
-
+bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
if (buffer_size_after_limit_ > 0) {
// We hit a limit inside this buffer. Advance to the limit and fail.
Advance(original_buffer_size);
@@ -244,8 +217,12 @@ bool CodedInputStream::Skip(int count) {
return false;
}
+ if (!input_->Skip(count)) {
+ total_bytes_read_ = input_->ByteCount();
+ return false;
+ }
total_bytes_read_ += count;
- return input_->Skip(count);
+ return true;
}
bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
@@ -339,7 +316,8 @@ namespace {
// The first part of the pair is true iff the read was successful. The second
// part is buffer + (number of bytes read). This function is always inlined,
// so returning a pair is costless.
-GOOGLE_ATTRIBUTE_ALWAYS_INLINE ::std::pair<bool, const uint8*> ReadVarint32FromArray(
+GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+::std::pair<bool, const uint8*> ReadVarint32FromArray(
uint32 first_byte, const uint8* buffer,
uint32* value);
inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
@@ -376,8 +354,8 @@ inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
return std::make_pair(true, ptr);
}
-GOOGLE_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*> ReadVarint64FromArray(
- const uint8* buffer, uint64* value);
+GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*>
+ReadVarint64FromArray(const uint8* buffer, uint64* value);
inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
const uint8* buffer, uint64* value) {
const uint8* ptr = buffer;
@@ -605,20 +583,6 @@ bool CodedInputStream::Refresh() {
return false;
}
- if (total_bytes_warning_threshold_ >= 0 &&
- total_bytes_read_ >= total_bytes_warning_threshold_) {
- GOOGLE_LOG(INFO) << "Reading dangerously large protocol message. If the "
- "message turns out to be larger than "
- << total_bytes_limit_ << " bytes, parsing will be halted "
- "for security reasons. To increase the limit (or to "
- "disable these warnings), see "
- "CodedInputStream::SetTotalBytesLimit() in "
- "google/protobuf/io/coded_stream.h.";
-
- // Don't warn again for this stream, and print total size at the end.
- total_bytes_warning_threshold_ = -2;
- }
-
const void* void_buffer;
int buffer_size;
if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
@@ -655,23 +619,11 @@ bool CodedInputStream::Refresh() {
// CodedOutputStream =================================================
-bool CodedOutputStream::default_serialization_deterministic_ = false;
+std::atomic<bool> CodedOutputStream::default_serialization_deterministic_{
+ false};
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
- : output_(output),
- buffer_(NULL),
- buffer_size_(0),
- total_bytes_(0),
- had_error_(false),
- aliasing_enabled_(false),
- serialization_deterministic_is_overridden_(false) {
- // Eagerly Refresh() so buffer space is immediately available.
- Refresh();
- // The Refresh() may have failed. If the client doesn't write any data,
- // though, don't consider this an error. If the client does write data, then
- // another Refresh() will be attempted and it will set the error once again.
- had_error_ = false;
-}
+ : CodedOutputStream(output, true) {}
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
bool do_eager_refresh)
@@ -681,7 +633,7 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
total_bytes_(0),
had_error_(false),
aliasing_enabled_(false),
- serialization_deterministic_is_overridden_(false) {
+ is_serialization_deterministic_(IsDefaultSerializationDeterministic()) {
if (do_eager_refresh) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();