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 (at) 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 48 namespace google { 49 namespace protobuf { 50 namespace 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. 56 const int WireFormatLite::kMessageSetItemStartTag; 57 const int WireFormatLite::kMessageSetItemEndTag; 58 const int WireFormatLite::kMessageSetTypeIdTag; 59 const int WireFormatLite::kMessageSetMessageTag; 60 61 #endif 62 63 // IBM xlC requires prefixing constants with WireFormatLite:: 64 const 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 74 const WireFormatLite::CppType 75 WireFormatLite::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 98 const WireFormatLite::WireType 99 WireFormatLite::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 121 bool 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 166 bool 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 223 bool 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 242 bool 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 263 bool FieldSkipper::SkipField( 264 io::CodedInputStream* input, uint32 tag) { 265 return WireFormatLite::SkipField(input, tag); 266 } 267 268 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 269 return WireFormatLite::SkipMessage(input); 270 } 271 272 void FieldSkipper::SkipUnknownEnum( 273 int /* field_number */, int /* value */) { 274 // Nothing. 275 } 276 277 bool CodedOutputStreamFieldSkipper::SkipField( 278 io::CodedInputStream* input, uint32 tag) { 279 return WireFormatLite::SkipField(input, tag, unknown_fields_); 280 } 281 282 bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) { 283 return WireFormatLite::SkipMessage(input, unknown_fields_); 284 } 285 286 void CodedOutputStreamFieldSkipper::SkipUnknownEnum( 287 int field_number, int value) { 288 unknown_fields_->WriteVarint32(field_number); 289 unknown_fields_->WriteVarint64(value); 290 } 291 292 bool 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 312 bool 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 340 void WireFormatLite::WriteInt32(int field_number, int32 value, 341 io::CodedOutputStream* output) { 342 WriteTag(field_number, WIRETYPE_VARINT, output); 343 WriteInt32NoTag(value, output); 344 } 345 void WireFormatLite::WriteInt64(int field_number, int64 value, 346 io::CodedOutputStream* output) { 347 WriteTag(field_number, WIRETYPE_VARINT, output); 348 WriteInt64NoTag(value, output); 349 } 350 void WireFormatLite::WriteUInt32(int field_number, uint32 value, 351 io::CodedOutputStream* output) { 352 WriteTag(field_number, WIRETYPE_VARINT, output); 353 WriteUInt32NoTag(value, output); 354 } 355 void WireFormatLite::WriteUInt64(int field_number, uint64 value, 356 io::CodedOutputStream* output) { 357 WriteTag(field_number, WIRETYPE_VARINT, output); 358 WriteUInt64NoTag(value, output); 359 } 360 void WireFormatLite::WriteSInt32(int field_number, int32 value, 361 io::CodedOutputStream* output) { 362 WriteTag(field_number, WIRETYPE_VARINT, output); 363 WriteSInt32NoTag(value, output); 364 } 365 void WireFormatLite::WriteSInt64(int field_number, int64 value, 366 io::CodedOutputStream* output) { 367 WriteTag(field_number, WIRETYPE_VARINT, output); 368 WriteSInt64NoTag(value, output); 369 } 370 void WireFormatLite::WriteFixed32(int field_number, uint32 value, 371 io::CodedOutputStream* output) { 372 WriteTag(field_number, WIRETYPE_FIXED32, output); 373 WriteFixed32NoTag(value, output); 374 } 375 void WireFormatLite::WriteFixed64(int field_number, uint64 value, 376 io::CodedOutputStream* output) { 377 WriteTag(field_number, WIRETYPE_FIXED64, output); 378 WriteFixed64NoTag(value, output); 379 } 380 void WireFormatLite::WriteSFixed32(int field_number, int32 value, 381 io::CodedOutputStream* output) { 382 WriteTag(field_number, WIRETYPE_FIXED32, output); 383 WriteSFixed32NoTag(value, output); 384 } 385 void WireFormatLite::WriteSFixed64(int field_number, int64 value, 386 io::CodedOutputStream* output) { 387 WriteTag(field_number, WIRETYPE_FIXED64, output); 388 WriteSFixed64NoTag(value, output); 389 } 390 void WireFormatLite::WriteFloat(int field_number, float value, 391 io::CodedOutputStream* output) { 392 WriteTag(field_number, WIRETYPE_FIXED32, output); 393 WriteFloatNoTag(value, output); 394 } 395 void WireFormatLite::WriteDouble(int field_number, double value, 396 io::CodedOutputStream* output) { 397 WriteTag(field_number, WIRETYPE_FIXED64, output); 398 WriteDoubleNoTag(value, output); 399 } 400 void WireFormatLite::WriteBool(int field_number, bool value, 401 io::CodedOutputStream* output) { 402 WriteTag(field_number, WIRETYPE_VARINT, output); 403 WriteBoolNoTag(value, output); 404 } 405 void WireFormatLite::WriteEnum(int field_number, int value, 406 io::CodedOutputStream* output) { 407 WriteTag(field_number, WIRETYPE_VARINT, output); 408 WriteEnumNoTag(value, output); 409 } 410 411 void 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 } 419 void 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 } 428 void 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 } 435 void 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 445 void 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 453 void 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 462 void 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 477 void 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 492 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadBytesToString( 493 io::CodedInputStream* input, string* value); 494 inline static bool ReadBytesToString(io::CodedInputStream* input, 495 string* value) { 496 uint32 length; 497 return input->ReadVarint32(&length) && 498 input->InternalReadStringInline(value, length); 499 } 500 501 bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string* value) { 502 return ReadBytesToString(input, value); 503 } 504 505 bool 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 512 bool 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