From 58aea1911f9e5742020f757bb61e37dc7919dd7f Mon Sep 17 00:00:00 2001 From: Atul Merchia Date: Sun, 26 Jan 2025 01:23:01 -0800 Subject: [PATCH] Make ParseDict nondestructive for Any --- .../protobuf/internal/json_format_test.py | 21 +++++++++++++++++++ python/google/protobuf/json_format.py | 6 ++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index f323d0e23a..90e1f1606c 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -1601,6 +1601,27 @@ class JsonFormatTest(JsonFormatBase): 'TestAny.any_value.', ) + def testParseDictNestedAnyDescriptorPoolMissingType(self): + # Confirm that ParseDict nondestructive with empty pool + js_dict = { + '@type': 'type.googleapis.com/google.protobuf.Any', + 'value': { + '@type': 'type.googleapis.com/protobuf_unittest.TestAny', + 'any_value': { + '@type': 'type.googleapis.com/UnknownMessageType', + } + } + } + js_dict_copy = json.loads(json.dumps(js_dict)) + with self.assertRaises(json_format.ParseError) as cm: + json_format.ParseDict(js_dict_copy, any_pb2.Any()) + self.assertEqual( + str(cm.exception), + 'Failed to parse any_value field: Can not find message descriptor by' + ' type_url: type.googleapis.com/UnknownMessageType at Any.value.any_value.', + ) + self.assertEqual(js_dict, js_dict_copy) + def testParseDictUnknownValueType(self): class UnknownClass(object): diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 7891be94ba..3eafd13215 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -734,8 +734,10 @@ class _Parser(object): )(self) else: del value['@type'] - self._ConvertFieldValuePair(value, sub_message, path) - value['@type'] = type_url + try: + self._ConvertFieldValuePair(value, sub_message, path) + finally: + value['@type'] = type_url # Sets Any message message.value = sub_message.SerializeToString() message.type_url = type_url