1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <google/protobuf/wire_format_lite_inl.h> 36 37#include <stack> 38#include <string> 39#include <vector> 40#include <google/protobuf/stubs/logging.h> 41#include <google/protobuf/stubs/common.h> 42#include <google/protobuf/stubs/stringprintf.h> 43#include <google/protobuf/io/coded_stream_inl.h> 44#include <google/protobuf/io/zero_copy_stream.h> 45#include <google/protobuf/io/zero_copy_stream_impl_lite.h> 46 47 48namespace google { 49namespace protobuf { 50namespace internal { 51 52 53#if !defined(_MSC_VER) || _MSC_VER >= 1900 54// Old version of MSVC doesn't like definitions of inline constants, GCC 55// requires them. 56const int WireFormatLite::kMessageSetItemStartTag; 57const int WireFormatLite::kMessageSetItemEndTag; 58const int WireFormatLite::kMessageSetTypeIdTag; 59const int WireFormatLite::kMessageSetMessageTag; 60 61#endif 62 63// IBM xlC requires prefixing constants with WireFormatLite:: 64const int WireFormatLite::kMessageSetItemTagsSize = 65 io::CodedOutputStream::StaticVarintSize32< 66 WireFormatLite::kMessageSetItemStartTag>::value + 67 io::CodedOutputStream::StaticVarintSize32< 68 WireFormatLite::kMessageSetItemEndTag>::value + 69 io::CodedOutputStream::StaticVarintSize32< 70 WireFormatLite::kMessageSetTypeIdTag>::value + 71 io::CodedOutputStream::StaticVarintSize32< 72 WireFormatLite::kMessageSetMessageTag>::value; 73 74const WireFormatLite::CppType 75WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { 76 static_cast<CppType>(0), // 0 is reserved for errors 77 78 CPPTYPE_DOUBLE, // TYPE_DOUBLE 79 CPPTYPE_FLOAT, // TYPE_FLOAT 80 CPPTYPE_INT64, // TYPE_INT64 81 CPPTYPE_UINT64, // TYPE_UINT64 82 CPPTYPE_INT32, // TYPE_INT32 83 CPPTYPE_UINT64, // TYPE_FIXED64 84 CPPTYPE_UINT32, // TYPE_FIXED32 85 CPPTYPE_BOOL, // TYPE_BOOL 86 CPPTYPE_STRING, // TYPE_STRING 87 CPPTYPE_MESSAGE, // TYPE_GROUP 88 CPPTYPE_MESSAGE, // TYPE_MESSAGE 89 CPPTYPE_STRING, // TYPE_BYTES 90 CPPTYPE_UINT32, // TYPE_UINT32 91 CPPTYPE_ENUM, // TYPE_ENUM 92 CPPTYPE_INT32, // TYPE_SFIXED32 93 CPPTYPE_INT64, // TYPE_SFIXED64 94 CPPTYPE_INT32, // TYPE_SINT32 95 CPPTYPE_INT64, // TYPE_SINT64 96}; 97 98const WireFormatLite::WireType 99WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { 100 static_cast<WireFormatLite::WireType>(-1), // invalid 101 WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE 102 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT 103 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 104 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 105 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 106 WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 107 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 108 WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL 109 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING 110 WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP 111 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE 112 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES 113 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 114 WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM 115 WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 116 WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 117 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 118 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 119}; 120 121bool WireFormatLite::SkipField( 122 io::CodedInputStream* input, uint32 tag) { 123 switch (WireFormatLite::GetTagWireType(tag)) { 124 case WireFormatLite::WIRETYPE_VARINT: { 125 uint64 value; 126 if (!input->ReadVarint64(&value)) return false; 127 return true; 128 } 129 case WireFormatLite::WIRETYPE_FIXED64: { 130 uint64 value; 131 if (!input->ReadLittleEndian64(&value)) return false; 132 return true; 133 } 134 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { 135 uint32 length; 136 if (!input->ReadVarint32(&length)) return false; 137 if (!input->Skip(length)) return false; 138 return true; 139 } 140 case WireFormatLite::WIRETYPE_START_GROUP: { 141 if (!input->IncrementRecursionDepth()) return false; 142 if (!SkipMessage(input)) return false; 143 input->DecrementRecursionDepth(); 144 // Check that the ending tag matched the starting tag. 145 if (!input->LastTagWas(WireFormatLite::MakeTag( 146 WireFormatLite::GetTagFieldNumber(tag), 147 WireFormatLite::WIRETYPE_END_GROUP))) { 148 return false; 149 } 150 return true; 151 } 152 case WireFormatLite::WIRETYPE_END_GROUP: { 153 return false; 154 } 155 case WireFormatLite::WIRETYPE_FIXED32: { 156 uint32 value; 157 if (!input->ReadLittleEndian32(&value)) return false; 158 return true; 159 } 160 default: { 161 return false; 162 } 163 } 164} 165 166bool WireFormatLite::SkipField( 167 io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) { 168 switch (WireFormatLite::GetTagWireType(tag)) { 169 case WireFormatLite::WIRETYPE_VARINT: { 170 uint64 value; 171 if (!input->ReadVarint64(&value)) return false; 172 output->WriteVarint32(tag); 173 output->WriteVarint64(value); 174 return true; 175 } 176 case WireFormatLite::WIRETYPE_FIXED64: { 177 uint64 value; 178 if (!input->ReadLittleEndian64(&value)) return false; 179 output->WriteVarint32(tag); 180 output->WriteLittleEndian64(value); 181 return true; 182 } 183 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { 184 uint32 length; 185 if (!input->ReadVarint32(&length)) return false; 186 output->WriteVarint32(tag); 187 output->WriteVarint32(length); 188 // TODO(mkilavuz): Provide API to prevent extra string copying. 189 string temp; 190 if (!input->ReadString(&temp, length)) return false; 191 output->WriteString(temp); 192 return true; 193 } 194 case WireFormatLite::WIRETYPE_START_GROUP: { 195 output->WriteVarint32(tag); 196 if (!input->IncrementRecursionDepth()) return false; 197 if (!SkipMessage(input, output)) return false; 198 input->DecrementRecursionDepth(); 199 // Check that the ending tag matched the starting tag. 200 if (!input->LastTagWas(WireFormatLite::MakeTag( 201 WireFormatLite::GetTagFieldNumber(tag), 202 WireFormatLite::WIRETYPE_END_GROUP))) { 203 return false; 204 } 205 return true; 206 } 207 case WireFormatLite::WIRETYPE_END_GROUP: { 208 return false; 209 } 210 case WireFormatLite::WIRETYPE_FIXED32: { 211 uint32 value; 212 if (!input->ReadLittleEndian32(&value)) return false; 213 output->WriteVarint32(tag); 214 output->WriteLittleEndian32(value); 215 return true; 216 } 217 default: { 218 return false; 219 } 220 } 221} 222 223bool WireFormatLite::SkipMessage(io::CodedInputStream* input) { 224 while (true) { 225 uint32 tag = input->ReadTag(); 226 if (tag == 0) { 227 // End of input. This is a valid place to end, so return true. 228 return true; 229 } 230 231 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); 232 233 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { 234 // Must be the end of the message. 235 return true; 236 } 237 238 if (!SkipField(input, tag)) return false; 239 } 240} 241 242bool WireFormatLite::SkipMessage(io::CodedInputStream* input, 243 io::CodedOutputStream* output) { 244 while (true) { 245 uint32 tag = input->ReadTag(); 246 if (tag == 0) { 247 // End of input. This is a valid place to end, so return true. 248 return true; 249 } 250 251 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); 252 253 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { 254 output->WriteVarint32(tag); 255 // Must be the end of the message. 256 return true; 257 } 258 259 if (!SkipField(input, tag, output)) return false; 260 } 261} 262 263bool FieldSkipper::SkipField( 264 io::CodedInputStream* input, uint32 tag) { 265 return WireFormatLite::SkipField(input, tag); 266} 267 268bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 269 return WireFormatLite::SkipMessage(input); 270} 271 272void FieldSkipper::SkipUnknownEnum( 273 int /* field_number */, int /* value */) { 274 // Nothing. 275} 276 277bool CodedOutputStreamFieldSkipper::SkipField( 278 io::CodedInputStream* input, uint32 tag) { 279 return WireFormatLite::SkipField(input, tag, unknown_fields_); 280} 281 282bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) { 283 return WireFormatLite::SkipMessage(input, unknown_fields_); 284} 285 286void CodedOutputStreamFieldSkipper::SkipUnknownEnum( 287 int field_number, int value) { 288 unknown_fields_->WriteVarint32(field_number); 289 unknown_fields_->WriteVarint64(value); 290} 291 292bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input, 293 bool (*is_valid)(int), 294 RepeatedField<int>* values) { 295 uint32 length; 296 if (!input->ReadVarint32(&length)) return false; 297 io::CodedInputStream::Limit limit = input->PushLimit(length); 298 while (input->BytesUntilLimit() > 0) { 299 int value; 300 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< 301 int, WireFormatLite::TYPE_ENUM>(input, &value)) { 302 return false; 303 } 304 if (is_valid == NULL || is_valid(value)) { 305 values->Add(value); 306 } 307 } 308 input->PopLimit(limit); 309 return true; 310} 311 312bool WireFormatLite::ReadPackedEnumPreserveUnknowns( 313 io::CodedInputStream* input, 314 int field_number, 315 bool (*is_valid)(int), 316 io::CodedOutputStream* unknown_fields_stream, 317 RepeatedField<int>* values) { 318 uint32 length; 319 if (!input->ReadVarint32(&length)) return false; 320 io::CodedInputStream::Limit limit = input->PushLimit(length); 321 while (input->BytesUntilLimit() > 0) { 322 int value; 323 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< 324 int, WireFormatLite::TYPE_ENUM>(input, &value)) { 325 return false; 326 } 327 if (is_valid == NULL || is_valid(value)) { 328 values->Add(value); 329 } else { 330 uint32 tag = WireFormatLite::MakeTag(field_number, 331 WireFormatLite::WIRETYPE_VARINT); 332 unknown_fields_stream->WriteVarint32(tag); 333 unknown_fields_stream->WriteVarint32(value); 334 } 335 } 336 input->PopLimit(limit); 337 return true; 338} 339 340void WireFormatLite::WriteInt32(int field_number, int32 value, 341 io::CodedOutputStream* output) { 342 WriteTag(field_number, WIRETYPE_VARINT, output); 343 WriteInt32NoTag(value, output); 344} 345void WireFormatLite::WriteInt64(int field_number, int64 value, 346 io::CodedOutputStream* output) { 347 WriteTag(field_number, WIRETYPE_VARINT, output); 348 WriteInt64NoTag(value, output); 349} 350void WireFormatLite::WriteUInt32(int field_number, uint32 value, 351 io::CodedOutputStream* output) { 352 WriteTag(field_number, WIRETYPE_VARINT, output); 353 WriteUInt32NoTag(value, output); 354} 355void WireFormatLite::WriteUInt64(int field_number, uint64 value, 356 io::CodedOutputStream* output) { 357 WriteTag(field_number, WIRETYPE_VARINT, output); 358 WriteUInt64NoTag(value, output); 359} 360void WireFormatLite::WriteSInt32(int field_number, int32 value, 361 io::CodedOutputStream* output) { 362 WriteTag(field_number, WIRETYPE_VARINT, output); 363 WriteSInt32NoTag(value, output); 364} 365void WireFormatLite::WriteSInt64(int field_number, int64 value, 366 io::CodedOutputStream* output) { 367 WriteTag(field_number, WIRETYPE_VARINT, output); 368 WriteSInt64NoTag(value, output); 369} 370void WireFormatLite::WriteFixed32(int field_number, uint32 value, 371 io::CodedOutputStream* output) { 372 WriteTag(field_number, WIRETYPE_FIXED32, output); 373 WriteFixed32NoTag(value, output); 374} 375void WireFormatLite::WriteFixed64(int field_number, uint64 value, 376 io::CodedOutputStream* output) { 377 WriteTag(field_number, WIRETYPE_FIXED64, output); 378 WriteFixed64NoTag(value, output); 379} 380void WireFormatLite::WriteSFixed32(int field_number, int32 value, 381 io::CodedOutputStream* output) { 382 WriteTag(field_number, WIRETYPE_FIXED32, output); 383 WriteSFixed32NoTag(value, output); 384} 385void WireFormatLite::WriteSFixed64(int field_number, int64 value, 386 io::CodedOutputStream* output) { 387 WriteTag(field_number, WIRETYPE_FIXED64, output); 388 WriteSFixed64NoTag(value, output); 389} 390void WireFormatLite::WriteFloat(int field_number, float value, 391 io::CodedOutputStream* output) { 392 WriteTag(field_number, WIRETYPE_FIXED32, output); 393 WriteFloatNoTag(value, output); 394} 395void WireFormatLite::WriteDouble(int field_number, double value, 396 io::CodedOutputStream* output) { 397 WriteTag(field_number, WIRETYPE_FIXED64, output); 398 WriteDoubleNoTag(value, output); 399} 400void WireFormatLite::WriteBool(int field_number, bool value, 401 io::CodedOutputStream* output) { 402 WriteTag(field_number, WIRETYPE_VARINT, output); 403 WriteBoolNoTag(value, output); 404} 405void WireFormatLite::WriteEnum(int field_number, int value, 406 io::CodedOutputStream* output) { 407 WriteTag(field_number, WIRETYPE_VARINT, output); 408 WriteEnumNoTag(value, output); 409} 410 411void WireFormatLite::WriteString(int field_number, const string& value, 412 io::CodedOutputStream* output) { 413 // String is for UTF-8 text only 414 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 415 GOOGLE_CHECK_LE(value.size(), kint32max); 416 output->WriteVarint32(value.size()); 417 output->WriteString(value); 418} 419void WireFormatLite::WriteStringMaybeAliased( 420 int field_number, const string& value, 421 io::CodedOutputStream* output) { 422 // String is for UTF-8 text only 423 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 424 GOOGLE_CHECK_LE(value.size(), kint32max); 425 output->WriteVarint32(value.size()); 426 output->WriteRawMaybeAliased(value.data(), value.size()); 427} 428void WireFormatLite::WriteBytes(int field_number, const string& value, 429 io::CodedOutputStream* output) { 430 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 431 GOOGLE_CHECK_LE(value.size(), kint32max); 432 output->WriteVarint32(value.size()); 433 output->WriteString(value); 434} 435void WireFormatLite::WriteBytesMaybeAliased( 436 int field_number, const string& value, 437 io::CodedOutputStream* output) { 438 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 439 GOOGLE_CHECK_LE(value.size(), kint32max); 440 output->WriteVarint32(value.size()); 441 output->WriteRawMaybeAliased(value.data(), value.size()); 442} 443 444 445void WireFormatLite::WriteGroup(int field_number, 446 const MessageLite& value, 447 io::CodedOutputStream* output) { 448 WriteTag(field_number, WIRETYPE_START_GROUP, output); 449 value.SerializeWithCachedSizes(output); 450 WriteTag(field_number, WIRETYPE_END_GROUP, output); 451} 452 453void WireFormatLite::WriteMessage(int field_number, 454 const MessageLite& value, 455 io::CodedOutputStream* output) { 456 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 457 const int size = value.GetCachedSize(); 458 output->WriteVarint32(size); 459 value.SerializeWithCachedSizes(output); 460} 461 462void WireFormatLite::WriteGroupMaybeToArray(int field_number, 463 const MessageLite& value, 464 io::CodedOutputStream* output) { 465 WriteTag(field_number, WIRETYPE_START_GROUP, output); 466 const int size = value.GetCachedSize(); 467 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); 468 if (target != NULL) { 469 uint8* end = value.SerializeWithCachedSizesToArray(target); 470 GOOGLE_DCHECK_EQ(end - target, size); 471 } else { 472 value.SerializeWithCachedSizes(output); 473 } 474 WriteTag(field_number, WIRETYPE_END_GROUP, output); 475} 476 477void WireFormatLite::WriteMessageMaybeToArray(int field_number, 478 const MessageLite& value, 479 io::CodedOutputStream* output) { 480 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 481 const int size = value.GetCachedSize(); 482 output->WriteVarint32(size); 483 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); 484 if (target != NULL) { 485 uint8* end = value.SerializeWithCachedSizesToArray(target); 486 GOOGLE_DCHECK_EQ(end - target, size); 487 } else { 488 value.SerializeWithCachedSizes(output); 489 } 490} 491 492GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadBytesToString( 493 io::CodedInputStream* input, string* value); 494inline static bool ReadBytesToString(io::CodedInputStream* input, 495 string* value) { 496 uint32 length; 497 return input->ReadVarint32(&length) && 498 input->InternalReadStringInline(value, length); 499} 500 501bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string* value) { 502 return ReadBytesToString(input, value); 503} 504 505bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string** p) { 506 if (*p == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { 507 *p = new ::std::string(); 508 } 509 return ReadBytesToString(input, *p); 510} 511 512bool WireFormatLite::VerifyUtf8String(const char* data, 513 int size, 514 Operation op, 515 const char* field_name) { 516 if (!IsStructurallyValidUTF8(data, size)) { 517 const char* operation_str = NULL; 518 switch (op) { 519 case PARSE: 520 operation_str = "parsing"; 521 break; 522 case SERIALIZE: 523 operation_str = "serializing"; 524 break; 525 // no default case: have the compiler warn if a case is not covered. 526 } 527 string quoted_field_name = ""; 528 if (field_name != NULL) { 529 quoted_field_name = StringPrintf(" '%s'", field_name); 530 } 531 // no space below to avoid double space when the field name is missing. 532 GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid " 533 << "UTF-8 data when " << operation_str << " a protocol " 534 << "buffer. Use the 'bytes' type if you intend to send raw " 535 << "bytes. "; 536 return false; 537 } 538 return true; 539} 540 541} // namespace internal 542} // namespace protobuf 543} // namespace google 544