Skip to content

Commit

Permalink
Make python text-format reject octal floats
Browse files Browse the repository at this point in the history
These are disallowed by the spec, and rejected by other languages (and python implementations).

PiperOrigin-RevId: 707222813
  • Loading branch information
mkruskal-google authored and copybara-github committed Dec 17, 2024
1 parent 7004a92 commit 8f2ad12
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 6 deletions.
2 changes: 0 additions & 2 deletions conformance/text_format_failure_list_python.txt
Original file line number Diff line number Diff line change
@@ -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\
Expand Down
2 changes: 0 additions & 2 deletions conformance/text_format_failure_list_python_cpp.txt
Original file line number Diff line number Diff line change
@@ -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\
Expand Down
2 changes: 0 additions & 2 deletions conformance/text_format_failure_list_python_upb.txt
Original file line number Diff line number Diff line change
@@ -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\
Expand Down
11 changes: 11 additions & 0 deletions python/google/protobuf/internal/text_format_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
3 changes: 3 additions & 0 deletions python/google/protobuf/text_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 '
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8f2ad12

Please sign in to comment.