protobuf 5.29.4__py3-none-any.whl → 6.33.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of protobuf might be problematic. Click here for more details.

Files changed (45) hide show
  1. google/protobuf/__init__.py +1 -1
  2. google/protobuf/any.py +15 -1
  3. google/protobuf/any_pb2.py +4 -4
  4. google/protobuf/api_pb2.py +14 -10
  5. google/protobuf/compiler/plugin_pb2.py +4 -4
  6. google/protobuf/descriptor.py +413 -248
  7. google/protobuf/descriptor_database.py +22 -4
  8. google/protobuf/descriptor_pb2.py +319 -119
  9. google/protobuf/descriptor_pool.py +31 -13
  10. google/protobuf/duration_pb2.py +4 -4
  11. google/protobuf/empty_pb2.py +4 -4
  12. google/protobuf/field_mask_pb2.py +4 -4
  13. google/protobuf/internal/api_implementation.py +0 -6
  14. google/protobuf/internal/builder.py +4 -3
  15. google/protobuf/internal/containers.py +13 -0
  16. google/protobuf/internal/decoder.py +163 -133
  17. google/protobuf/internal/extension_dict.py +3 -3
  18. google/protobuf/internal/field_mask.py +6 -4
  19. google/protobuf/internal/python_edition_defaults.py +1 -1
  20. google/protobuf/internal/python_message.py +86 -70
  21. google/protobuf/internal/testing_refleaks.py +11 -2
  22. google/protobuf/internal/type_checkers.py +52 -5
  23. google/protobuf/internal/well_known_types.py +63 -46
  24. google/protobuf/json_format.py +113 -71
  25. google/protobuf/message.py +26 -0
  26. google/protobuf/message_factory.py +16 -63
  27. google/protobuf/proto.py +38 -1
  28. google/protobuf/proto_text.py +129 -0
  29. google/protobuf/reflection.py +0 -49
  30. google/protobuf/runtime_version.py +8 -28
  31. google/protobuf/source_context_pb2.py +4 -4
  32. google/protobuf/struct_pb2.py +4 -4
  33. google/protobuf/symbol_database.py +0 -18
  34. google/protobuf/text_format.py +49 -29
  35. google/protobuf/timestamp_pb2.py +4 -4
  36. google/protobuf/type_pb2.py +4 -4
  37. google/protobuf/unknown_fields.py +3 -4
  38. google/protobuf/wrappers_pb2.py +4 -4
  39. {protobuf-5.29.4.dist-info → protobuf-6.33.3.dist-info}/METADATA +3 -3
  40. protobuf-6.33.3.dist-info/RECORD +58 -0
  41. google/protobuf/internal/_parameterized.py +0 -420
  42. google/protobuf/service.py +0 -213
  43. protobuf-5.29.4.dist-info/RECORD +0 -59
  44. {protobuf-5.29.4.dist-info → protobuf-6.33.3.dist-info}/LICENSE +0 -0
  45. {protobuf-5.29.4.dist-info → protobuf-6.33.3.dist-info}/WHEEL +0 -0
@@ -58,6 +58,7 @@ we repeatedly read a tag, look up the corresponding decoder, and invoke it.
58
58
  __author__ = 'kenton@google.com (Kenton Varda)'
59
59
 
60
60
  import math
61
+ import numbers
61
62
  import struct
62
63
 
63
64
  from google.protobuf import message
@@ -71,6 +72,27 @@ from google.protobuf.internal import wire_format
71
72
  _DecodeError = message.DecodeError
72
73
 
73
74
 
75
+ def IsDefaultScalarValue(value):
76
+ """Returns whether or not a scalar value is the default value of its type.
77
+
78
+ Specifically, this should be used to determine presence of implicit-presence
79
+ fields, where we disallow custom defaults.
80
+
81
+ Args:
82
+ value: A scalar value to check.
83
+
84
+ Returns:
85
+ True if the value is equivalent to a default value, False otherwise.
86
+ """
87
+ if isinstance(value, numbers.Number) and math.copysign(1.0, value) < 0:
88
+ # Special case for negative zero, where "truthiness" fails to give the right
89
+ # answer.
90
+ return False
91
+
92
+ # Normally, we can just use Python's boolean conversion.
93
+ return not value
94
+
95
+
74
96
  def _VarintDecoder(mask, result_type):
75
97
  """Return an encoder for a basic varint value (does not include tag).
76
98
 
@@ -168,6 +190,19 @@ def ReadTag(buffer, pos):
168
190
  return tag_bytes, pos
169
191
 
170
192
 
193
+ def DecodeTag(tag_bytes):
194
+ """Decode a tag from the bytes.
195
+
196
+ Args:
197
+ tag_bytes: the bytes of the tag
198
+
199
+ Returns:
200
+ Tuple[int, int] of the tag field number and wire type.
201
+ """
202
+ (tag, _) = _DecodeVarint(tag_bytes, 0)
203
+ return wire_format.UnpackTag(tag)
204
+
205
+
171
206
  # --------------------------------------------------------------------
172
207
 
173
208
 
@@ -184,7 +219,10 @@ def _SimpleDecoder(wire_type, decode_value):
184
219
  clear_if_default=False):
185
220
  if is_packed:
186
221
  local_DecodeVarint = _DecodeVarint
187
- def DecodePackedField(buffer, pos, end, message, field_dict):
222
+ def DecodePackedField(
223
+ buffer, pos, end, message, field_dict, current_depth=0
224
+ ):
225
+ del current_depth # unused
188
226
  value = field_dict.get(key)
189
227
  if value is None:
190
228
  value = field_dict.setdefault(key, new_default(message))
@@ -199,11 +237,15 @@ def _SimpleDecoder(wire_type, decode_value):
199
237
  del value[-1] # Discard corrupt value.
200
238
  raise _DecodeError('Packed element was truncated.')
201
239
  return pos
240
+
202
241
  return DecodePackedField
203
242
  elif is_repeated:
204
243
  tag_bytes = encoder.TagBytes(field_number, wire_type)
205
244
  tag_len = len(tag_bytes)
206
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
245
+ def DecodeRepeatedField(
246
+ buffer, pos, end, message, field_dict, current_depth=0
247
+ ):
248
+ del current_depth # unused
207
249
  value = field_dict.get(key)
208
250
  if value is None:
209
251
  value = field_dict.setdefault(key, new_default(message))
@@ -218,17 +260,21 @@ def _SimpleDecoder(wire_type, decode_value):
218
260
  if new_pos > end:
219
261
  raise _DecodeError('Truncated message.')
220
262
  return new_pos
263
+
221
264
  return DecodeRepeatedField
222
265
  else:
223
- def DecodeField(buffer, pos, end, message, field_dict):
266
+
267
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
268
+ del current_depth # unused
224
269
  (new_value, pos) = decode_value(buffer, pos)
225
270
  if pos > end:
226
271
  raise _DecodeError('Truncated message.')
227
- if clear_if_default and not new_value:
272
+ if clear_if_default and IsDefaultScalarValue(new_value):
228
273
  field_dict.pop(key, None)
229
274
  else:
230
275
  field_dict[key] = new_value
231
276
  return pos
277
+
232
278
  return DecodeField
233
279
 
234
280
  return SpecificDecoder
@@ -364,7 +410,9 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
364
410
  enum_type = key.enum_type
365
411
  if is_packed:
366
412
  local_DecodeVarint = _DecodeVarint
367
- def DecodePackedField(buffer, pos, end, message, field_dict):
413
+ def DecodePackedField(
414
+ buffer, pos, end, message, field_dict, current_depth=0
415
+ ):
368
416
  """Decode serialized packed enum to its value and a new position.
369
417
 
370
418
  Args:
@@ -377,6 +425,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
377
425
  Returns:
378
426
  int, new position in serialized data.
379
427
  """
428
+ del current_depth # unused
380
429
  value = field_dict.get(key)
381
430
  if value is None:
382
431
  value = field_dict.setdefault(key, new_default(message))
@@ -407,11 +456,14 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
407
456
  # pylint: enable=protected-access
408
457
  raise _DecodeError('Packed element was truncated.')
409
458
  return pos
459
+
410
460
  return DecodePackedField
411
461
  elif is_repeated:
412
462
  tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
413
463
  tag_len = len(tag_bytes)
414
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
464
+ def DecodeRepeatedField(
465
+ buffer, pos, end, message, field_dict, current_depth=0
466
+ ):
415
467
  """Decode serialized repeated enum to its value and a new position.
416
468
 
417
469
  Args:
@@ -424,6 +476,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
424
476
  Returns:
425
477
  int, new position in serialized data.
426
478
  """
479
+ del current_depth # unused
427
480
  value = field_dict.get(key)
428
481
  if value is None:
429
482
  value = field_dict.setdefault(key, new_default(message))
@@ -446,9 +499,11 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
446
499
  if new_pos > end:
447
500
  raise _DecodeError('Truncated message.')
448
501
  return new_pos
502
+
449
503
  return DecodeRepeatedField
450
504
  else:
451
- def DecodeField(buffer, pos, end, message, field_dict):
505
+
506
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
452
507
  """Decode serialized repeated enum to its value and a new position.
453
508
 
454
509
  Args:
@@ -461,11 +516,12 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
461
516
  Returns:
462
517
  int, new position in serialized data.
463
518
  """
519
+ del current_depth # unused
464
520
  value_start_pos = pos
465
521
  (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
466
522
  if pos > end:
467
523
  raise _DecodeError('Truncated message.')
468
- if clear_if_default and not enum_value:
524
+ if clear_if_default and IsDefaultScalarValue(enum_value):
469
525
  field_dict.pop(key, None)
470
526
  return pos
471
527
  # pylint: disable=protected-access
@@ -480,6 +536,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
480
536
  (tag_bytes, buffer[value_start_pos:pos].tobytes()))
481
537
  # pylint: enable=protected-access
482
538
  return pos
539
+
483
540
  return DecodeField
484
541
 
485
542
 
@@ -538,7 +595,10 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default,
538
595
  tag_bytes = encoder.TagBytes(field_number,
539
596
  wire_format.WIRETYPE_LENGTH_DELIMITED)
540
597
  tag_len = len(tag_bytes)
541
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
598
+ def DecodeRepeatedField(
599
+ buffer, pos, end, message, field_dict, current_depth=0
600
+ ):
601
+ del current_depth # unused
542
602
  value = field_dict.get(key)
543
603
  if value is None:
544
604
  value = field_dict.setdefault(key, new_default(message))
@@ -553,18 +613,22 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default,
553
613
  if buffer[new_pos:pos] != tag_bytes or new_pos == end:
554
614
  # Prediction failed. Return.
555
615
  return new_pos
616
+
556
617
  return DecodeRepeatedField
557
618
  else:
558
- def DecodeField(buffer, pos, end, message, field_dict):
619
+
620
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
621
+ del current_depth # unused
559
622
  (size, pos) = local_DecodeVarint(buffer, pos)
560
623
  new_pos = pos + size
561
624
  if new_pos > end:
562
625
  raise _DecodeError('Truncated string.')
563
- if clear_if_default and not size:
626
+ if clear_if_default and IsDefaultScalarValue(size):
564
627
  field_dict.pop(key, None)
565
628
  else:
566
629
  field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
567
630
  return new_pos
631
+
568
632
  return DecodeField
569
633
 
570
634
 
@@ -579,7 +643,10 @@ def BytesDecoder(field_number, is_repeated, is_packed, key, new_default,
579
643
  tag_bytes = encoder.TagBytes(field_number,
580
644
  wire_format.WIRETYPE_LENGTH_DELIMITED)
581
645
  tag_len = len(tag_bytes)
582
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
646
+ def DecodeRepeatedField(
647
+ buffer, pos, end, message, field_dict, current_depth=0
648
+ ):
649
+ del current_depth # unused
583
650
  value = field_dict.get(key)
584
651
  if value is None:
585
652
  value = field_dict.setdefault(key, new_default(message))
@@ -594,18 +661,22 @@ def BytesDecoder(field_number, is_repeated, is_packed, key, new_default,
594
661
  if buffer[new_pos:pos] != tag_bytes or new_pos == end:
595
662
  # Prediction failed. Return.
596
663
  return new_pos
664
+
597
665
  return DecodeRepeatedField
598
666
  else:
599
- def DecodeField(buffer, pos, end, message, field_dict):
667
+
668
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
669
+ del current_depth # unused
600
670
  (size, pos) = local_DecodeVarint(buffer, pos)
601
671
  new_pos = pos + size
602
672
  if new_pos > end:
603
673
  raise _DecodeError('Truncated string.')
604
- if clear_if_default and not size:
674
+ if clear_if_default and IsDefaultScalarValue(size):
605
675
  field_dict.pop(key, None)
606
676
  else:
607
677
  field_dict[key] = buffer[pos:new_pos].tobytes()
608
678
  return new_pos
679
+
609
680
  return DecodeField
610
681
 
611
682
 
@@ -621,7 +692,9 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
621
692
  tag_bytes = encoder.TagBytes(field_number,
622
693
  wire_format.WIRETYPE_START_GROUP)
623
694
  tag_len = len(tag_bytes)
624
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
695
+ def DecodeRepeatedField(
696
+ buffer, pos, end, message, field_dict, current_depth=0
697
+ ):
625
698
  value = field_dict.get(key)
626
699
  if value is None:
627
700
  value = field_dict.setdefault(key, new_default(message))
@@ -630,7 +703,13 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
630
703
  if value is None:
631
704
  value = field_dict.setdefault(key, new_default(message))
632
705
  # Read sub-message.
633
- pos = value.add()._InternalParse(buffer, pos, end)
706
+ current_depth += 1
707
+ if current_depth > _recursion_limit:
708
+ raise _DecodeError(
709
+ 'Error parsing message: too many levels of nesting.'
710
+ )
711
+ pos = value.add()._InternalParse(buffer, pos, end, current_depth)
712
+ current_depth -= 1
634
713
  # Read end tag.
635
714
  new_pos = pos+end_tag_len
636
715
  if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
@@ -640,19 +719,26 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
640
719
  if buffer[new_pos:pos] != tag_bytes or new_pos == end:
641
720
  # Prediction failed. Return.
642
721
  return new_pos
722
+
643
723
  return DecodeRepeatedField
644
724
  else:
645
- def DecodeField(buffer, pos, end, message, field_dict):
725
+
726
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
646
727
  value = field_dict.get(key)
647
728
  if value is None:
648
729
  value = field_dict.setdefault(key, new_default(message))
649
730
  # Read sub-message.
650
- pos = value._InternalParse(buffer, pos, end)
731
+ current_depth += 1
732
+ if current_depth > _recursion_limit:
733
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
734
+ pos = value._InternalParse(buffer, pos, end, current_depth)
735
+ current_depth -= 1
651
736
  # Read end tag.
652
737
  new_pos = pos+end_tag_len
653
738
  if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
654
739
  raise _DecodeError('Missing group end tag.')
655
740
  return new_pos
741
+
656
742
  return DecodeField
657
743
 
658
744
 
@@ -666,7 +752,9 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
666
752
  tag_bytes = encoder.TagBytes(field_number,
667
753
  wire_format.WIRETYPE_LENGTH_DELIMITED)
668
754
  tag_len = len(tag_bytes)
669
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
755
+ def DecodeRepeatedField(
756
+ buffer, pos, end, message, field_dict, current_depth=0
757
+ ):
670
758
  value = field_dict.get(key)
671
759
  if value is None:
672
760
  value = field_dict.setdefault(key, new_default(message))
@@ -677,18 +765,29 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
677
765
  if new_pos > end:
678
766
  raise _DecodeError('Truncated message.')
679
767
  # Read sub-message.
680
- if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
768
+ current_depth += 1
769
+ if current_depth > _recursion_limit:
770
+ raise _DecodeError(
771
+ 'Error parsing message: too many levels of nesting.'
772
+ )
773
+ if (
774
+ value.add()._InternalParse(buffer, pos, new_pos, current_depth)
775
+ != new_pos
776
+ ):
681
777
  # The only reason _InternalParse would return early is if it
682
778
  # encountered an end-group tag.
683
779
  raise _DecodeError('Unexpected end-group tag.')
780
+ current_depth -= 1
684
781
  # Predict that the next tag is another copy of the same repeated field.
685
782
  pos = new_pos + tag_len
686
783
  if buffer[new_pos:pos] != tag_bytes or new_pos == end:
687
784
  # Prediction failed. Return.
688
785
  return new_pos
786
+
689
787
  return DecodeRepeatedField
690
788
  else:
691
- def DecodeField(buffer, pos, end, message, field_dict):
789
+
790
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
692
791
  value = field_dict.get(key)
693
792
  if value is None:
694
793
  value = field_dict.setdefault(key, new_default(message))
@@ -698,11 +797,16 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
698
797
  if new_pos > end:
699
798
  raise _DecodeError('Truncated message.')
700
799
  # Read sub-message.
701
- if value._InternalParse(buffer, pos, new_pos) != new_pos:
800
+ current_depth += 1
801
+ if current_depth > _recursion_limit:
802
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
803
+ if value._InternalParse(buffer, pos, new_pos, current_depth) != new_pos:
702
804
  # The only reason _InternalParse would return early is if it encountered
703
805
  # an end-group tag.
704
806
  raise _DecodeError('Unexpected end-group tag.')
807
+ current_depth -= 1
705
808
  return new_pos
809
+
706
810
  return DecodeField
707
811
 
708
812
 
@@ -730,7 +834,6 @@ def MessageSetItemDecoder(descriptor):
730
834
 
731
835
  local_ReadTag = ReadTag
732
836
  local_DecodeVarint = _DecodeVarint
733
- local_SkipField = SkipField
734
837
 
735
838
  def DecodeItem(buffer, pos, end, message, field_dict):
736
839
  """Decode serialized message set to its value and new position.
@@ -762,9 +865,10 @@ def MessageSetItemDecoder(descriptor):
762
865
  elif tag_bytes == item_end_tag_bytes:
763
866
  break
764
867
  else:
765
- pos = SkipField(buffer, pos, end, tag_bytes)
868
+ field_number, wire_type = DecodeTag(tag_bytes)
869
+ _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type)
766
870
  if pos == -1:
767
- raise _DecodeError('Missing group end tag.')
871
+ raise _DecodeError('Unexpected end-group tag.')
768
872
 
769
873
  if pos > end:
770
874
  raise _DecodeError('Truncated message.')
@@ -822,9 +926,10 @@ def UnknownMessageSetItemDecoder():
822
926
  elif tag_bytes == item_end_tag_bytes:
823
927
  break
824
928
  else:
825
- pos = SkipField(buffer, pos, end, tag_bytes)
929
+ field_number, wire_type = DecodeTag(tag_bytes)
930
+ _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type)
826
931
  if pos == -1:
827
- raise _DecodeError('Missing group end tag.')
932
+ raise _DecodeError('Unexpected end-group tag.')
828
933
 
829
934
  if pos > end:
830
935
  raise _DecodeError('Truncated message.')
@@ -851,7 +956,8 @@ def MapDecoder(field_descriptor, new_default, is_message_map):
851
956
  # Can't read _concrete_class yet; might not be initialized.
852
957
  message_type = field_descriptor.message_type
853
958
 
854
- def DecodeMap(buffer, pos, end, message, field_dict):
959
+ def DecodeMap(buffer, pos, end, message, field_dict, current_depth=0):
960
+ del current_depth # Unused.
855
961
  submsg = message_type._concrete_class()
856
962
  value = field_dict.get(key)
857
963
  if value is None:
@@ -882,30 +988,6 @@ def MapDecoder(field_descriptor, new_default, is_message_map):
882
988
 
883
989
  return DecodeMap
884
990
 
885
- # --------------------------------------------------------------------
886
- # Optimization is not as heavy here because calls to SkipField() are rare,
887
- # except for handling end-group tags.
888
-
889
- def _SkipVarint(buffer, pos, end):
890
- """Skip a varint value. Returns the new position."""
891
- # Previously ord(buffer[pos]) raised IndexError when pos is out of range.
892
- # With this code, ord(b'') raises TypeError. Both are handled in
893
- # python_message.py to generate a 'Truncated message' error.
894
- while ord(buffer[pos:pos+1].tobytes()) & 0x80:
895
- pos += 1
896
- pos += 1
897
- if pos > end:
898
- raise _DecodeError('Truncated message.')
899
- return pos
900
-
901
- def _SkipFixed64(buffer, pos, end):
902
- """Skip a fixed64 value. Returns the new position."""
903
-
904
- pos += 8
905
- if pos > end:
906
- raise _DecodeError('Truncated message.')
907
- return pos
908
-
909
991
 
910
992
  def _DecodeFixed64(buffer, pos):
911
993
  """Decode a fixed64."""
@@ -913,28 +995,21 @@ def _DecodeFixed64(buffer, pos):
913
995
  return (struct.unpack('<Q', buffer[pos:new_pos])[0], new_pos)
914
996
 
915
997
 
916
- def _SkipLengthDelimited(buffer, pos, end):
917
- """Skip a length-delimited value. Returns the new position."""
918
-
919
- (size, pos) = _DecodeVarint(buffer, pos)
920
- pos += size
921
- if pos > end:
922
- raise _DecodeError('Truncated message.')
923
- return pos
998
+ def _DecodeFixed32(buffer, pos):
999
+ """Decode a fixed32."""
924
1000
 
1001
+ new_pos = pos + 4
1002
+ return (struct.unpack('<I', buffer[pos:new_pos])[0], new_pos)
1003
+ DEFAULT_RECURSION_LIMIT = 100
1004
+ _recursion_limit = DEFAULT_RECURSION_LIMIT
925
1005
 
926
- def _SkipGroup(buffer, pos, end):
927
- """Skip sub-group. Returns the new position."""
928
1006
 
929
- while 1:
930
- (tag_bytes, pos) = ReadTag(buffer, pos)
931
- new_pos = SkipField(buffer, pos, end, tag_bytes)
932
- if new_pos == -1:
933
- return pos
934
- pos = new_pos
1007
+ def SetRecursionLimit(new_limit):
1008
+ global _recursion_limit
1009
+ _recursion_limit = new_limit
935
1010
 
936
1011
 
937
- def _DecodeUnknownFieldSet(buffer, pos, end_pos=None):
1012
+ def _DecodeUnknownFieldSet(buffer, pos, end_pos=None, current_depth=0):
938
1013
  """Decode UnknownFieldSet. Returns the UnknownFieldSet and new position."""
939
1014
 
940
1015
  unknown_field_set = containers.UnknownFieldSet()
@@ -944,14 +1019,18 @@ def _DecodeUnknownFieldSet(buffer, pos, end_pos=None):
944
1019
  field_number, wire_type = wire_format.UnpackTag(tag)
945
1020
  if wire_type == wire_format.WIRETYPE_END_GROUP:
946
1021
  break
947
- (data, pos) = _DecodeUnknownField(buffer, pos, wire_type)
1022
+ (data, pos) = _DecodeUnknownField(
1023
+ buffer, pos, end_pos, field_number, wire_type, current_depth
1024
+ )
948
1025
  # pylint: disable=protected-access
949
1026
  unknown_field_set._add(field_number, wire_type, data)
950
1027
 
951
1028
  return (unknown_field_set, pos)
952
1029
 
953
1030
 
954
- def _DecodeUnknownField(buffer, pos, wire_type):
1031
+ def _DecodeUnknownField(
1032
+ buffer, pos, end_pos, field_number, wire_type, current_depth=0
1033
+ ):
955
1034
  """Decode a unknown field. Returns the UnknownField and new position."""
956
1035
 
957
1036
  if wire_type == wire_format.WIRETYPE_VARINT:
@@ -965,72 +1044,23 @@ def _DecodeUnknownField(buffer, pos, wire_type):
965
1044
  data = buffer[pos:pos+size].tobytes()
966
1045
  pos += size
967
1046
  elif wire_type == wire_format.WIRETYPE_START_GROUP:
968
- (data, pos) = _DecodeUnknownFieldSet(buffer, pos)
1047
+ end_tag_bytes = encoder.TagBytes(
1048
+ field_number, wire_format.WIRETYPE_END_GROUP
1049
+ )
1050
+ current_depth += 1
1051
+ if current_depth >= _recursion_limit:
1052
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
1053
+ data, pos = _DecodeUnknownFieldSet(buffer, pos, end_pos, current_depth)
1054
+ current_depth -= 1
1055
+ # Check end tag.
1056
+ if buffer[pos - len(end_tag_bytes) : pos] != end_tag_bytes:
1057
+ raise _DecodeError('Missing group end tag.')
969
1058
  elif wire_type == wire_format.WIRETYPE_END_GROUP:
970
1059
  return (0, -1)
971
1060
  else:
972
1061
  raise _DecodeError('Wrong wire type in tag.')
973
1062
 
974
- return (data, pos)
975
-
976
-
977
- def _EndGroup(buffer, pos, end):
978
- """Skipping an END_GROUP tag returns -1 to tell the parent loop to break."""
979
-
980
- return -1
981
-
982
-
983
- def _SkipFixed32(buffer, pos, end):
984
- """Skip a fixed32 value. Returns the new position."""
985
-
986
- pos += 4
987
- if pos > end:
1063
+ if pos > end_pos:
988
1064
  raise _DecodeError('Truncated message.')
989
- return pos
990
1065
 
991
-
992
- def _DecodeFixed32(buffer, pos):
993
- """Decode a fixed32."""
994
-
995
- new_pos = pos + 4
996
- return (struct.unpack('<I', buffer[pos:new_pos])[0], new_pos)
997
-
998
-
999
- def _RaiseInvalidWireType(buffer, pos, end):
1000
- """Skip function for unknown wire types. Raises an exception."""
1001
-
1002
- raise _DecodeError('Tag had invalid wire type.')
1003
-
1004
- def _FieldSkipper():
1005
- """Constructs the SkipField function."""
1006
-
1007
- WIRETYPE_TO_SKIPPER = [
1008
- _SkipVarint,
1009
- _SkipFixed64,
1010
- _SkipLengthDelimited,
1011
- _SkipGroup,
1012
- _EndGroup,
1013
- _SkipFixed32,
1014
- _RaiseInvalidWireType,
1015
- _RaiseInvalidWireType,
1016
- ]
1017
-
1018
- wiretype_mask = wire_format.TAG_TYPE_MASK
1019
-
1020
- def SkipField(buffer, pos, end, tag_bytes):
1021
- """Skips a field with the specified tag.
1022
-
1023
- |pos| should point to the byte immediately after the tag.
1024
-
1025
- Returns:
1026
- The new position (after the tag value), or -1 if the tag is an end-group
1027
- tag (in which case the calling loop should break).
1028
- """
1029
-
1030
- # The wire type is always in the first byte since varints are little-endian.
1031
- wire_type = ord(tag_bytes[0:1]) & wiretype_mask
1032
- return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
1033
-
1034
- return SkipField
1035
-
1036
- SkipField = _FieldSkipper()
1066
+ return (data, pos)
@@ -61,7 +61,7 @@ class _ExtensionDict(object):
61
61
  if result is not None:
62
62
  return result
63
63
 
64
- if extension_handle.label == FieldDescriptor.LABEL_REPEATED:
64
+ if extension_handle.is_repeated:
65
65
  result = extension_handle._default_constructor(self._extended_message)
66
66
  elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
67
67
  message_type = extension_handle.message_type
@@ -129,7 +129,7 @@ class _ExtensionDict(object):
129
129
 
130
130
  _VerifyExtensionHandle(self._extended_message, extension_handle)
131
131
 
132
- if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or
132
+ if (extension_handle.is_repeated or
133
133
  extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE):
134
134
  raise TypeError(
135
135
  'Cannot assign to extension "%s" because it is a repeated or '
@@ -183,7 +183,7 @@ class _ExtensionDict(object):
183
183
  if extension_handle not in self._extended_message._fields:
184
184
  return False
185
185
 
186
- if extension_handle.label == FieldDescriptor.LABEL_REPEATED:
186
+ if extension_handle.is_repeated:
187
187
  return bool(self._extended_message._fields.get(extension_handle))
188
188
 
189
189
  if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
@@ -100,7 +100,7 @@ def _IsValidPath(message_descriptor, path):
100
100
  for name in parts:
101
101
  field = message_descriptor.fields_by_name.get(name)
102
102
  if (field is None or
103
- field.label == FieldDescriptor.LABEL_REPEATED or
103
+ field.is_repeated or
104
104
  field.type != FieldDescriptor.TYPE_MESSAGE):
105
105
  return False
106
106
  message_descriptor = field.message_type
@@ -271,7 +271,7 @@ def _MergeMessage(
271
271
  name, source_descriptor.full_name))
272
272
  if child:
273
273
  # Sub-paths are only allowed for singular message fields.
274
- if (field.label == FieldDescriptor.LABEL_REPEATED or
274
+ if (field.is_repeated or
275
275
  field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE):
276
276
  raise ValueError('Error: Field {0} in message {1} is not a singular '
277
277
  'message field and cannot have sub-fields.'.format(
@@ -281,7 +281,7 @@ def _MergeMessage(
281
281
  child, getattr(source, name), getattr(destination, name),
282
282
  replace_message, replace_repeated)
283
283
  continue
284
- if field.label == FieldDescriptor.LABEL_REPEATED:
284
+ if field.is_repeated:
285
285
  if replace_repeated:
286
286
  destination.ClearField(_StrConvert(name))
287
287
  repeated_source = getattr(source, name)
@@ -293,8 +293,10 @@ def _MergeMessage(
293
293
  destination.ClearField(_StrConvert(name))
294
294
  if source.HasField(name):
295
295
  getattr(destination, name).MergeFrom(getattr(source, name))
296
- else:
296
+ elif not field.has_presence or source.HasField(name):
297
297
  setattr(destination, name, getattr(source, name))
298
+ else:
299
+ destination.ClearField(_StrConvert(name))
298
300
 
299
301
 
300
302
  def _AddFieldPaths(node, prefix, field_mask):
@@ -2,4 +2,4 @@
2
2
  This file contains the serialized FeatureSetDefaults object corresponding to
3
3
  the Pure Python runtime. This is used for feature resolution under Editions.
4
4
  """
5
- _PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS = b"\n\023\030\204\007\"\000*\014\010\001\020\002\030\002 \003(\0010\002\n\023\030\347\007\"\000*\014\010\002\020\001\030\001 \002(\0010\001\n\023\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\000 \346\007(\350\007"
5
+ _PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS = b"\n\027\030\204\007\"\000*\020\010\001\020\002\030\002 \003(\0010\0028\002@\001\n\027\030\347\007\"\000*\020\010\002\020\001\030\001 \002(\0010\0018\002@\001\n\027\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\0048\002@\001\n\027\030\351\007\"\020\010\001\020\001\030\001 \002(\0010\0018\001@\002*\000 \346\007(\351\007"