| Index: third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
|
| diff --git a/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h b/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
|
| index 641cc92f65bf0ea88b23cd6b84db56220ef27706..b1c477d1a9e493d13faf34c979456e759146299a 100644
|
| --- a/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
|
| +++ b/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
|
| @@ -1,6 +1,6 @@
|
| // Protocol Buffers - Google's data interchange format
|
| // Copyright 2008 Google Inc. All rights reserved.
|
| -// http://code.google.com/p/protobuf/
|
| +// https://developers.google.com/protocol-buffers/
|
| //
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| @@ -36,12 +36,19 @@
|
| #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
|
| #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
|
|
|
| +#ifdef _MSC_VER
|
| +// This is required for min/max on VS2013 only.
|
| +#include <algorithm>
|
| +#endif
|
| +
|
| #include <string>
|
| #include <google/protobuf/stubs/common.h>
|
| +#include <google/protobuf/stubs/logging.h>
|
| #include <google/protobuf/message_lite.h>
|
| #include <google/protobuf/repeated_field.h>
|
| #include <google/protobuf/wire_format_lite.h>
|
| #include <google/protobuf/io/coded_stream.h>
|
| +#include <google/protobuf/arenastring.h>
|
|
|
|
|
| namespace google {
|
| @@ -150,8 +157,8 @@ template <>
|
| inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
|
| io::CodedInputStream* input,
|
| bool* value) {
|
| - uint32 temp;
|
| - if (!input->ReadVarint32(&temp)) return false;
|
| + uint64 temp;
|
| + if (!input->ReadVarint64(&temp)) return false;
|
| *value = temp != 0;
|
| return true;
|
| }
|
| @@ -221,10 +228,11 @@ inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
|
| }
|
|
|
| template <typename CType, enum WireFormatLite::FieldType DeclaredType>
|
| -inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
|
| - uint32 tag,
|
| - io::CodedInputStream* input,
|
| - RepeatedField<CType>* values) {
|
| +inline bool WireFormatLite::ReadRepeatedPrimitive(
|
| + int, // tag_size, unused.
|
| + uint32 tag,
|
| + io::CodedInputStream* input,
|
| + RepeatedField<CType>* values) {
|
| CType value;
|
| if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
|
| values->Add(value);
|
| @@ -284,7 +292,7 @@ inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
|
| return true;
|
| }
|
|
|
| -// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
|
| +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
|
| // the optimized code path.
|
| #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
|
| template <> \
|
| @@ -334,12 +342,93 @@ inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
|
| }
|
|
|
| template <typename CType, enum WireFormatLite::FieldType DeclaredType>
|
| +inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
|
| + io::CodedInputStream* input, RepeatedField<CType>* values) {
|
| + uint32 length;
|
| + if (!input->ReadVarint32(&length)) return false;
|
| + const uint32 old_entries = values->size();
|
| + const uint32 new_entries = length / sizeof(CType);
|
| + const uint32 new_bytes = new_entries * sizeof(CType);
|
| + if (new_bytes != length) return false;
|
| + // We would *like* to pre-allocate the buffer to write into (for
|
| + // speed), but *must* avoid performing a very large allocation due
|
| + // to a malicious user-supplied "length" above. So we have a fast
|
| + // path that pre-allocates when the "length" is less than a bound.
|
| + // We determine the bound by calling BytesUntilTotalBytesLimit() and
|
| + // BytesUntilLimit(). These return -1 to mean "no limit set".
|
| + // There are four cases:
|
| + // TotalBytesLimit Limit
|
| + // -1 -1 Use slow path.
|
| + // -1 >= 0 Use fast path if length <= Limit.
|
| + // >= 0 -1 Use slow path.
|
| + // >= 0 >= 0 Use fast path if length <= min(both limits).
|
| + int64 bytes_limit = input->BytesUntilTotalBytesLimit();
|
| + if (bytes_limit == -1) {
|
| + bytes_limit = input->BytesUntilLimit();
|
| + } else {
|
| + bytes_limit =
|
| + min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
|
| + }
|
| + if (bytes_limit >= new_bytes) {
|
| + // Fast-path that pre-allocates *values to the final size.
|
| +#if defined(PROTOBUF_LITTLE_ENDIAN)
|
| + values->Resize(old_entries + new_entries, 0);
|
| + // values->mutable_data() may change after Resize(), so do this after:
|
| + void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
|
| + if (!input->ReadRaw(dest, new_bytes)) {
|
| + values->Truncate(old_entries);
|
| + return false;
|
| + }
|
| +#else
|
| + values->Reserve(old_entries + new_entries);
|
| + CType value;
|
| + for (uint32 i = 0; i < new_entries; ++i) {
|
| + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
|
| + values->AddAlreadyReserved(value);
|
| + }
|
| +#endif
|
| + } else {
|
| + // This is the slow-path case where "length" may be too large to
|
| + // safely allocate. We read as much as we can into *values
|
| + // without pre-allocating "length" bytes.
|
| + CType value;
|
| + for (uint32 i = 0; i < new_entries; ++i) {
|
| + if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
|
| + values->Add(value);
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// Specializations of ReadPackedPrimitive for the fixed size types, which use
|
| +// an optimized code path.
|
| +#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
|
| +template <> \
|
| +inline bool WireFormatLite::ReadPackedPrimitive< \
|
| + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
|
| + io::CodedInputStream* input, \
|
| + RepeatedField<CPPTYPE>* values) { \
|
| + return ReadPackedFixedSizePrimitive< \
|
| + CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \
|
| +}
|
| +
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
|
| +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
|
| +
|
| +#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
|
| +
|
| +template <typename CType, enum WireFormatLite::FieldType DeclaredType>
|
| bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
|
| RepeatedField<CType>* values) {
|
| return ReadPackedPrimitive<CType, DeclaredType>(input, values);
|
| }
|
|
|
|
|
| +
|
| inline bool WireFormatLite::ReadGroup(int field_number,
|
| io::CodedInputStream* input,
|
| MessageLite* value) {
|
| @@ -356,15 +445,12 @@ inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
|
| MessageLite* value) {
|
| uint32 length;
|
| if (!input->ReadVarint32(&length)) return false;
|
| - if (!input->IncrementRecursionDepth()) return false;
|
| - io::CodedInputStream::Limit limit = input->PushLimit(length);
|
| - if (!value->MergePartialFromCodedStream(input)) return false;
|
| + std::pair<io::CodedInputStream::Limit, int> p =
|
| + input->IncrementRecursionDepthAndPushLimit(length);
|
| + if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
|
| // Make sure that parsing stopped when the limit was hit, not at an endgroup
|
| // tag.
|
| - if (!input->ConsumedEntireMessage()) return false;
|
| - input->PopLimit(limit);
|
| - input->DecrementRecursionDepth();
|
| - return true;
|
| + return input->DecrementRecursionDepthAndPopLimit(p.first);
|
| }
|
|
|
| // We name the template parameter something long and extremely unlikely to occur
|
| @@ -385,7 +471,7 @@ inline bool WireFormatLite::ReadGroupNoVirtual(
|
| if (!value->
|
| MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
|
| return false;
|
| - input->DecrementRecursionDepth();
|
| + input->UnsafeDecrementRecursionDepth();
|
| // Make sure the last thing read was an end tag for this group.
|
| if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
|
| return false;
|
| @@ -393,21 +479,37 @@ inline bool WireFormatLite::ReadGroupNoVirtual(
|
| return true;
|
| }
|
| template<typename MessageType_WorkAroundCppLookupDefect>
|
| +inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth(
|
| + int field_number, io::CodedInputStream* input,
|
| + MessageType_WorkAroundCppLookupDefect* value) {
|
| + return value->MessageType_WorkAroundCppLookupDefect::
|
| + MergePartialFromCodedStream(input) &&
|
| + input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP));
|
| +}
|
| +template<typename MessageType_WorkAroundCppLookupDefect>
|
| inline bool WireFormatLite::ReadMessageNoVirtual(
|
| io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
|
| uint32 length;
|
| if (!input->ReadVarint32(&length)) return false;
|
| - if (!input->IncrementRecursionDepth()) return false;
|
| - io::CodedInputStream::Limit limit = input->PushLimit(length);
|
| + std::pair<io::CodedInputStream::Limit, int> p =
|
| + input->IncrementRecursionDepthAndPushLimit(length);
|
| + if (p.second < 0 || !value->
|
| + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
|
| + return false;
|
| + // Make sure that parsing stopped when the limit was hit, not at an endgroup
|
| + // tag.
|
| + return input->DecrementRecursionDepthAndPopLimit(p.first);
|
| +}
|
| +template<typename MessageType_WorkAroundCppLookupDefect>
|
| +inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
|
| + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
|
| + io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit();
|
| if (!value->
|
| MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
|
| return false;
|
| // Make sure that parsing stopped when the limit was hit, not at an endgroup
|
| // tag.
|
| - if (!input->ConsumedEntireMessage()) return false;
|
| - input->PopLimit(limit);
|
| - input->DecrementRecursionDepth();
|
| - return true;
|
| + return input->CheckEntireMessageConsumedAndPopLimit(old_limit);
|
| }
|
|
|
| // ===================================================================
|
| @@ -660,15 +762,13 @@ inline uint8* WireFormatLite::WriteStringToArray(int field_number,
|
| // WriteString() to avoid code duplication. If the implementations become
|
| // different, you will need to update that usage.
|
| target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
|
| - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
|
| - return io::CodedOutputStream::WriteStringToArray(value, target);
|
| + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
|
| }
|
| inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
|
| const string& value,
|
| uint8* target) {
|
| target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
|
| - target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
|
| - return io::CodedOutputStream::WriteStringToArray(value, target);
|
| + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
|
| }
|
|
|
|
|
| @@ -735,12 +835,14 @@ inline int WireFormatLite::EnumSize(int value) {
|
| }
|
|
|
| inline int WireFormatLite::StringSize(const string& value) {
|
| - return io::CodedOutputStream::VarintSize32(value.size()) +
|
| - value.size();
|
| + return static_cast<int>(
|
| + io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) +
|
| + value.size());
|
| }
|
| inline int WireFormatLite::BytesSize(const string& value) {
|
| - return io::CodedOutputStream::VarintSize32(value.size()) +
|
| - value.size();
|
| + return static_cast<int>(
|
| + io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) +
|
| + value.size());
|
| }
|
|
|
|
|
|
|