OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // http://code.google.com/p/protobuf/ | 3 // http://code.google.com/p/protobuf/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // this constructor. | 163 // this constructor. |
164 explicit CodedInputStream(const uint8* buffer, int size); | 164 explicit CodedInputStream(const uint8* buffer, int size); |
165 | 165 |
166 // Destroy the CodedInputStream and position the underlying | 166 // Destroy the CodedInputStream and position the underlying |
167 // ZeroCopyInputStream at the first unread byte. If an error occurred while | 167 // ZeroCopyInputStream at the first unread byte. If an error occurred while |
168 // reading (causing a method to return false), then the exact position of | 168 // reading (causing a method to return false), then the exact position of |
169 // the input stream may be anywhere between the last value that was read | 169 // the input stream may be anywhere between the last value that was read |
170 // successfully and the stream's byte limit. | 170 // successfully and the stream's byte limit. |
171 ~CodedInputStream(); | 171 ~CodedInputStream(); |
172 | 172 |
| 173 // Return true if this CodedInputStream reads from a flat array instead of |
| 174 // a ZeroCopyInputStream. |
| 175 inline bool IsFlat() const; |
173 | 176 |
174 // Skips a number of bytes. Returns false if an underlying read error | 177 // Skips a number of bytes. Returns false if an underlying read error |
175 // occurs. | 178 // occurs. |
176 bool Skip(int count); | 179 bool Skip(int count); |
177 | 180 |
178 // Sets *data to point directly at the unread part of the CodedInputStream's | 181 // Sets *data to point directly at the unread part of the CodedInputStream's |
179 // underlying buffer, and *size to the size of that buffer, but does not | 182 // underlying buffer, and *size to the size of that buffer, but does not |
180 // advance the stream's current position. This will always either produce | 183 // advance the stream's current position. This will always either produce |
181 // a non-empty buffer or return false. If the caller consumes any of | 184 // a non-empty buffer or return false. If the caller consumes any of |
182 // this data, it should then call Skip() to skip over the consumed bytes. | 185 // this data, it should then call Skip() to skip over the consumed bytes. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 // The value returned by PushLimit() is opaque to the caller, and must | 307 // The value returned by PushLimit() is opaque to the caller, and must |
305 // be passed unchanged to the corresponding call to PopLimit(). | 308 // be passed unchanged to the corresponding call to PopLimit(). |
306 Limit PushLimit(int byte_limit); | 309 Limit PushLimit(int byte_limit); |
307 | 310 |
308 // Pops the last limit pushed by PushLimit(). The input must be the value | 311 // Pops the last limit pushed by PushLimit(). The input must be the value |
309 // returned by that call to PushLimit(). | 312 // returned by that call to PushLimit(). |
310 void PopLimit(Limit limit); | 313 void PopLimit(Limit limit); |
311 | 314 |
312 // Returns the number of bytes left until the nearest limit on the | 315 // Returns the number of bytes left until the nearest limit on the |
313 // stack is hit, or -1 if no limits are in place. | 316 // stack is hit, or -1 if no limits are in place. |
314 int BytesUntilLimit(); | 317 int BytesUntilLimit() const; |
| 318 |
| 319 // Returns current position relative to the beginning of the input stream. |
| 320 int CurrentPosition() const; |
315 | 321 |
316 // Total Bytes Limit ----------------------------------------------- | 322 // Total Bytes Limit ----------------------------------------------- |
317 // To prevent malicious users from sending excessively large messages | 323 // To prevent malicious users from sending excessively large messages |
318 // and causing integer overflows or memory exhaustion, CodedInputStream | 324 // and causing integer overflows or memory exhaustion, CodedInputStream |
319 // imposes a hard limit on the total number of bytes it will read. | 325 // imposes a hard limit on the total number of bytes it will read. |
320 | 326 |
321 // Sets the maximum number of bytes that this CodedInputStream will read | 327 // Sets the maximum number of bytes that this CodedInputStream will read |
322 // before refusing to continue. To prevent integer overflows in the | 328 // before refusing to continue. To prevent integer overflows in the |
323 // protocol buffers implementation, as well as to prevent servers from | 329 // protocol buffers implementation, as well as to prevent servers from |
324 // allocating enormous amounts of memory to hold parsed messages, the | 330 // allocating enormous amounts of memory to hold parsed messages, the |
325 // maximum message length should be limited to the shortest length that | 331 // maximum message length should be limited to the shortest length that |
326 // will not harm usability. The theoretical shortest message that could | 332 // will not harm usability. The theoretical shortest message that could |
327 // cause integer overflows is 512MB. The default limit is 64MB. Apps | 333 // cause integer overflows is 512MB. The default limit is 64MB. Apps |
328 // should set shorter limits if possible. If warning_threshold is not -1, | 334 // should set shorter limits if possible. If warning_threshold is not -1, |
329 // a warning will be printed to stderr after warning_threshold bytes are | 335 // a warning will be printed to stderr after warning_threshold bytes are |
330 // read. An error will always be printed to stderr if the limit is | 336 // read. For backwards compatibility all negative values get squached to -1, |
331 // reached. | 337 // as other negative values might have special internal meanings. |
| 338 // An error will always be printed to stderr if the limit is reached. |
332 // | 339 // |
333 // This is unrelated to PushLimit()/PopLimit(). | 340 // This is unrelated to PushLimit()/PopLimit(). |
334 // | 341 // |
335 // Hint: If you are reading this because your program is printing a | 342 // Hint: If you are reading this because your program is printing a |
336 // warning about dangerously large protocol messages, you may be | 343 // warning about dangerously large protocol messages, you may be |
337 // confused about what to do next. The best option is to change your | 344 // confused about what to do next. The best option is to change your |
338 // design such that excessively large messages are not necessary. | 345 // design such that excessively large messages are not necessary. |
339 // For example, try to design file formats to consist of many small | 346 // For example, try to design file formats to consist of many small |
340 // messages rather than a single large one. If this is infeasible, | 347 // messages rather than a single large one. If this is infeasible, |
341 // you will need to increase the limit. Chances are, though, that | 348 // you will need to increase the limit. Chances are, though, that |
342 // your code never constructs a CodedInputStream on which the limit | 349 // your code never constructs a CodedInputStream on which the limit |
343 // can be set. You probably parse messages by calling things like | 350 // can be set. You probably parse messages by calling things like |
344 // Message::ParseFromString(). In this case, you will need to change | 351 // Message::ParseFromString(). In this case, you will need to change |
345 // your code to instead construct some sort of ZeroCopyInputStream | 352 // your code to instead construct some sort of ZeroCopyInputStream |
346 // (e.g. an ArrayInputStream), construct a CodedInputStream around | 353 // (e.g. an ArrayInputStream), construct a CodedInputStream around |
347 // that, then call Message::ParseFromCodedStream() instead. Then | 354 // that, then call Message::ParseFromCodedStream() instead. Then |
348 // you can adjust the limit. Yes, it's more work, but you're doing | 355 // you can adjust the limit. Yes, it's more work, but you're doing |
349 // something unusual. | 356 // something unusual. |
350 void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); | 357 void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); |
351 | 358 |
352 // Recursion Limit ------------------------------------------------- | 359 // Recursion Limit ------------------------------------------------- |
353 // To prevent corrupt or malicious messages from causing stack overflows, | 360 // To prevent corrupt or malicious messages from causing stack overflows, |
354 // we must keep track of the depth of recursion when parsing embedded | 361 // we must keep track of the depth of recursion when parsing embedded |
355 // messages and groups. CodedInputStream keeps track of this because it | 362 // messages and groups. CodedInputStream keeps track of this because it |
356 // is the only object that is passed down the stack during parsing. | 363 // is the only object that is passed down the stack during parsing. |
357 | 364 |
358 // Sets the maximum recursion depth. The default is 64. | 365 // Sets the maximum recursion depth. The default is 100. |
359 void SetRecursionLimit(int limit); | 366 void SetRecursionLimit(int limit); |
360 | 367 |
| 368 |
361 // Increments the current recursion depth. Returns true if the depth is | 369 // Increments the current recursion depth. Returns true if the depth is |
362 // under the limit, false if it has gone over. | 370 // under the limit, false if it has gone over. |
363 bool IncrementRecursionDepth(); | 371 bool IncrementRecursionDepth(); |
364 | 372 |
365 // Decrements the recursion depth. | 373 // Decrements the recursion depth. |
366 void DecrementRecursionDepth(); | 374 void DecrementRecursionDepth(); |
367 | 375 |
368 // Extension Registry ---------------------------------------------- | 376 // Extension Registry ---------------------------------------------- |
369 // ADVANCED USAGE: 99.9% of people can ignore this section. | 377 // ADVANCED USAGE: 99.9% of people can ignore this section. |
370 // | 378 // |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 // if these objects are represented using DynamicMessage. | 434 // if these objects are represented using DynamicMessage. |
427 // | 435 // |
428 // Using DynamicMessageFactory on which you have called | 436 // Using DynamicMessageFactory on which you have called |
429 // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the | 437 // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the |
430 // above requirement. | 438 // above requirement. |
431 // | 439 // |
432 // If either pool or factory is NULL, both must be NULL. | 440 // If either pool or factory is NULL, both must be NULL. |
433 // | 441 // |
434 // Note that this feature is ignored when parsing "lite" messages as they do | 442 // Note that this feature is ignored when parsing "lite" messages as they do |
435 // not have descriptors. | 443 // not have descriptors. |
436 void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory); | 444 void SetExtensionRegistry(const DescriptorPool* pool, |
| 445 MessageFactory* factory); |
437 | 446 |
438 // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool | 447 // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool |
439 // has been provided. | 448 // has been provided. |
440 const DescriptorPool* GetExtensionPool(); | 449 const DescriptorPool* GetExtensionPool(); |
441 | 450 |
442 // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no | 451 // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no |
443 // factory has been provided. | 452 // factory has been provided. |
444 MessageFactory* GetExtensionFactory(); | 453 MessageFactory* GetExtensionFactory(); |
445 | 454 |
446 private: | 455 private: |
(...skipping 28 matching lines...) Expand all Loading... |
475 // only tracks the number of bytes before that limit. This field | 484 // only tracks the number of bytes before that limit. This field |
476 // contains the number of bytes after it. Note that this implies that if | 485 // contains the number of bytes after it. Note that this implies that if |
477 // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've | 486 // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've |
478 // hit a limit. However, if both are zero, it doesn't necessarily mean | 487 // hit a limit. However, if both are zero, it doesn't necessarily mean |
479 // we aren't at a limit -- the buffer may have ended exactly at the limit. | 488 // we aren't at a limit -- the buffer may have ended exactly at the limit. |
480 int buffer_size_after_limit_; | 489 int buffer_size_after_limit_; |
481 | 490 |
482 // Maximum number of bytes to read, period. This is unrelated to | 491 // Maximum number of bytes to read, period. This is unrelated to |
483 // current_limit_. Set using SetTotalBytesLimit(). | 492 // current_limit_. Set using SetTotalBytesLimit(). |
484 int total_bytes_limit_; | 493 int total_bytes_limit_; |
| 494 |
| 495 // If positive/0: Limit for bytes read after which a warning due to size |
| 496 // should be logged. |
| 497 // If -1: Printing of warning disabled. Can be set by client. |
| 498 // If -2: Internal: Limit has been reached, print full size when destructing. |
485 int total_bytes_warning_threshold_; | 499 int total_bytes_warning_threshold_; |
486 | 500 |
487 // Current recursion depth, controlled by IncrementRecursionDepth() and | 501 // Current recursion depth, controlled by IncrementRecursionDepth() and |
488 // DecrementRecursionDepth(). | 502 // DecrementRecursionDepth(). |
489 int recursion_depth_; | 503 int recursion_depth_; |
490 // Recursion depth limit, set by SetRecursionLimit(). | 504 // Recursion depth limit, set by SetRecursionLimit(). |
491 int recursion_limit_; | 505 int recursion_limit_; |
492 | 506 |
493 // See SetExtensionRegistry(). | 507 // See SetExtensionRegistry(). |
494 const DescriptorPool* extension_pool_; | 508 const DescriptorPool* extension_pool_; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 uint32 ReadTagFallback(); | 546 uint32 ReadTagFallback(); |
533 uint32 ReadTagSlow(); | 547 uint32 ReadTagSlow(); |
534 bool ReadStringFallback(string* buffer, int size); | 548 bool ReadStringFallback(string* buffer, int size); |
535 | 549 |
536 // Return the size of the buffer. | 550 // Return the size of the buffer. |
537 int BufferSize() const; | 551 int BufferSize() const; |
538 | 552 |
539 static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB | 553 static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB |
540 | 554 |
541 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB | 555 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB |
542 static const int kDefaultRecursionLimit = 64; | 556 |
| 557 static int default_recursion_limit_; // 100 by default. |
543 }; | 558 }; |
544 | 559 |
545 // Class which encodes and writes binary data which is composed of varint- | 560 // Class which encodes and writes binary data which is composed of varint- |
546 // encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. | 561 // encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. |
547 // Most users will not need to deal with CodedOutputStream. | 562 // Most users will not need to deal with CodedOutputStream. |
548 // | 563 // |
549 // Most methods of CodedOutputStream which return a bool return false if an | 564 // Most methods of CodedOutputStream which return a bool return false if an |
550 // underlying I/O error occurs. Once such a failure occurs, the | 565 // underlying I/O error occurs. Once such a failure occurs, the |
551 // CodedOutputStream is broken and is no longer useful. The Write* methods do | 566 // CodedOutputStream is broken and is no longer useful. The Write* methods do |
552 // not return the stream status, but will invalidate the stream if an error | 567 // not return the stream status, but will invalidate the stream if an error |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, | 899 inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, |
885 int* size) { | 900 int* size) { |
886 *data = buffer_; | 901 *data = buffer_; |
887 *size = buffer_end_ - buffer_; | 902 *size = buffer_end_ - buffer_; |
888 } | 903 } |
889 | 904 |
890 inline bool CodedInputStream::ExpectAtEnd() { | 905 inline bool CodedInputStream::ExpectAtEnd() { |
891 // If we are at a limit we know no more bytes can be read. Otherwise, it's | 906 // If we are at a limit we know no more bytes can be read. Otherwise, it's |
892 // hard to say without calling Refresh(), and we'd rather not do that. | 907 // hard to say without calling Refresh(), and we'd rather not do that. |
893 | 908 |
894 if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) { | 909 if (buffer_ == buffer_end_ && |
| 910 ((buffer_size_after_limit_ != 0) || |
| 911 (total_bytes_read_ == current_limit_))) { |
895 last_tag_ = 0; // Pretend we called ReadTag()... | 912 last_tag_ = 0; // Pretend we called ReadTag()... |
896 legitimate_message_end_ = true; // ... and it hit EOF. | 913 legitimate_message_end_ = true; // ... and it hit EOF. |
897 return true; | 914 return true; |
898 } else { | 915 } else { |
899 return false; | 916 return false; |
900 } | 917 } |
901 } | 918 } |
902 | 919 |
| 920 inline int CodedInputStream::CurrentPosition() const { |
| 921 return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_); |
| 922 } |
| 923 |
903 inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { | 924 inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { |
904 if (buffer_size_ < size) { | 925 if (buffer_size_ < size) { |
905 return NULL; | 926 return NULL; |
906 } else { | 927 } else { |
907 uint8* result = buffer_; | 928 uint8* result = buffer_; |
908 Advance(size); | 929 Advance(size); |
909 return result; | 930 return result; |
910 } | 931 } |
911 } | 932 } |
912 | 933 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 | 1053 |
1033 inline bool CodedInputStream::IncrementRecursionDepth() { | 1054 inline bool CodedInputStream::IncrementRecursionDepth() { |
1034 ++recursion_depth_; | 1055 ++recursion_depth_; |
1035 return recursion_depth_ <= recursion_limit_; | 1056 return recursion_depth_ <= recursion_limit_; |
1036 } | 1057 } |
1037 | 1058 |
1038 inline void CodedInputStream::DecrementRecursionDepth() { | 1059 inline void CodedInputStream::DecrementRecursionDepth() { |
1039 if (recursion_depth_ > 0) --recursion_depth_; | 1060 if (recursion_depth_ > 0) --recursion_depth_; |
1040 } | 1061 } |
1041 | 1062 |
1042 inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool, | 1063 inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, |
1043 MessageFactory* factory) { | 1064 MessageFactory* factory) { |
1044 extension_pool_ = pool; | 1065 extension_pool_ = pool; |
1045 extension_factory_ = factory; | 1066 extension_factory_ = factory; |
1046 } | 1067 } |
1047 | 1068 |
1048 inline const DescriptorPool* CodedInputStream::GetExtensionPool() { | 1069 inline const DescriptorPool* CodedInputStream::GetExtensionPool() { |
1049 return extension_pool_; | 1070 return extension_pool_; |
1050 } | 1071 } |
1051 | 1072 |
1052 inline MessageFactory* CodedInputStream::GetExtensionFactory() { | 1073 inline MessageFactory* CodedInputStream::GetExtensionFactory() { |
(...skipping 11 matching lines...) Expand all Loading... |
1064 total_bytes_read_(0), | 1085 total_bytes_read_(0), |
1065 overflow_bytes_(0), | 1086 overflow_bytes_(0), |
1066 last_tag_(0), | 1087 last_tag_(0), |
1067 legitimate_message_end_(false), | 1088 legitimate_message_end_(false), |
1068 aliasing_enabled_(false), | 1089 aliasing_enabled_(false), |
1069 current_limit_(kint32max), | 1090 current_limit_(kint32max), |
1070 buffer_size_after_limit_(0), | 1091 buffer_size_after_limit_(0), |
1071 total_bytes_limit_(kDefaultTotalBytesLimit), | 1092 total_bytes_limit_(kDefaultTotalBytesLimit), |
1072 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), | 1093 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), |
1073 recursion_depth_(0), | 1094 recursion_depth_(0), |
1074 recursion_limit_(kDefaultRecursionLimit), | 1095 recursion_limit_(default_recursion_limit_), |
1075 extension_pool_(NULL), | 1096 extension_pool_(NULL), |
1076 extension_factory_(NULL) { | 1097 extension_factory_(NULL) { |
1077 // Eagerly Refresh() so buffer space is immediately available. | 1098 // Eagerly Refresh() so buffer space is immediately available. |
1078 Refresh(); | 1099 Refresh(); |
1079 } | 1100 } |
1080 | 1101 |
1081 inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) | 1102 inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) |
1082 : input_(NULL), | 1103 : input_(NULL), |
1083 buffer_(buffer), | 1104 buffer_(buffer), |
1084 buffer_end_(buffer + size), | 1105 buffer_end_(buffer + size), |
1085 total_bytes_read_(size), | 1106 total_bytes_read_(size), |
1086 overflow_bytes_(0), | 1107 overflow_bytes_(0), |
1087 last_tag_(0), | 1108 last_tag_(0), |
1088 legitimate_message_end_(false), | 1109 legitimate_message_end_(false), |
1089 aliasing_enabled_(false), | 1110 aliasing_enabled_(false), |
1090 current_limit_(size), | 1111 current_limit_(size), |
1091 buffer_size_after_limit_(0), | 1112 buffer_size_after_limit_(0), |
1092 total_bytes_limit_(kDefaultTotalBytesLimit), | 1113 total_bytes_limit_(kDefaultTotalBytesLimit), |
1093 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), | 1114 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), |
1094 recursion_depth_(0), | 1115 recursion_depth_(0), |
1095 recursion_limit_(kDefaultRecursionLimit), | 1116 recursion_limit_(default_recursion_limit_), |
1096 extension_pool_(NULL), | 1117 extension_pool_(NULL), |
1097 extension_factory_(NULL) { | 1118 extension_factory_(NULL) { |
1098 // Note that setting current_limit_ == size is important to prevent some | 1119 // Note that setting current_limit_ == size is important to prevent some |
1099 // code paths from trying to access input_ and segfaulting. | 1120 // code paths from trying to access input_ and segfaulting. |
1100 } | 1121 } |
1101 | 1122 |
1102 inline CodedInputStream::~CodedInputStream() { | 1123 inline bool CodedInputStream::IsFlat() const { |
1103 if (input_ != NULL) { | 1124 return input_ == NULL; |
1104 BackUpInputToCurrentPosition(); | |
1105 } | |
1106 } | 1125 } |
1107 | 1126 |
1108 } // namespace io | 1127 } // namespace io |
1109 } // namespace protobuf | 1128 } // namespace protobuf |
1110 | 1129 |
1111 | 1130 |
1112 #if defined(_MSC_VER) && _MSC_VER >= 1300 | 1131 #if defined(_MSC_VER) && _MSC_VER >= 1300 |
1113 #pragma runtime_checks("c", restore) | 1132 #pragma runtime_checks("c", restore) |
1114 #endif // _MSC_VER | 1133 #endif // _MSC_VER |
1115 | 1134 |
1116 } // namespace google | 1135 } // namespace google |
1117 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 1136 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
OLD | NEW |