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