diff --git a/conformance/text_format_failure_list_python.txt b/conformance/text_format_failure_list_python.txt index e25f68052b521..fbfcbc31267e9 100644 --- a/conformance/text_format_failure_list_python.txt +++ b/conformance/text_format_failure_list_python.txt @@ -1,8 +1,6 @@ # This is the list of text format conformance tests that are known to fail right # now. # TODO: These should be fixed. -Required.*.TextFormatInput.FloatFieldNoNegativeOctal # Should have failed to parse, but didn't. -Required.*.TextFormatInput.FloatFieldNoOctal # Should have failed to parse, but didn't. Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput # Output was not equivalent to reference message: modified: optional_string: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\ diff --git a/conformance/text_format_failure_list_python_cpp.txt b/conformance/text_format_failure_list_python_cpp.txt index d3c95d141d201..c853d9d6c5604 100644 --- a/conformance/text_format_failure_list_python_cpp.txt +++ b/conformance/text_format_failure_list_python_cpp.txt @@ -1,5 +1,3 @@ -Required.*.TextFormatInput.FloatFieldNoNegativeOctal # Should have failed to parse, but didn't. -Required.*.TextFormatInput.FloatFieldNoOctal # Should have failed to parse, but didn't. Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput # Output was not equivalent to reference message: modified: optional_string: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\ diff --git a/conformance/text_format_failure_list_python_upb.txt b/conformance/text_format_failure_list_python_upb.txt index e25f68052b521..fbfcbc31267e9 100644 --- a/conformance/text_format_failure_list_python_upb.txt +++ b/conformance/text_format_failure_list_python_upb.txt @@ -1,8 +1,6 @@ # This is the list of text format conformance tests that are known to fail right # now. # TODO: These should be fixed. -Required.*.TextFormatInput.FloatFieldNoNegativeOctal # Should have failed to parse, but didn't. -Required.*.TextFormatInput.FloatFieldNoOctal # Should have failed to parse, but didn't. Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput # Output was not equivalent to reference message: modified: optional_bytes: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\t Required.*.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput # Output was not equivalent to reference message: modified: optional_string: "\007\010\014\n\r\t\013?\\\'\"" -> "\007\010\014\n\r\ diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 952c74ad1d010..614daa7d1a499 100644 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -2468,6 +2468,17 @@ def testConsumeOctalIntegers(self): self.assertEqual(1, tokenizer.ConsumeInteger()) self.assertTrue(tokenizer.AtEnd()) + @parameterized.parameters('00', '09', '01.123', '-00', '-09', '-01.234') + def testConsumeOctalFloats(self, text): + """Test rejection of for octal-formatted floats.""" + tokenizer = text_format.Tokenizer([text]) + + self.assertRaisesRegex( + text_format.ParseError, + 'Invalid octal float: %s' % text, + tokenizer.ConsumeFloat, + ) + def testConsumeByteString(self): text = '"string1\'' tokenizer = text_format.Tokenizer(text.splitlines()) diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index ae49e269dcfef..e8e1a30d722b0 100644 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -42,6 +42,7 @@ type_checkers.Int64ValueChecker()) _FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE) _FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE) +_FLOAT_OCTAL_PREFIX = re.compile('-?0[0-9]+') _QUOTES = frozenset(("'", '"')) _ANY_FULL_TYPE_NAME = 'google.protobuf.Any' _DEBUG_STRING_SILENT_MARKER = '\t ' @@ -1791,6 +1792,8 @@ def ParseFloat(text): Raises: ValueError: If a floating point number couldn't be parsed. """ + if _FLOAT_OCTAL_PREFIX.match(text): + raise ValueError('Invalid octal float: %s' % text) try: # Assume Python compatible syntax. return float(text)