From cbbcb9868099e359302622842270d7fe824122d4 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Wed, 24 Jun 2020 14:28:56 +0300 Subject: [PATCH] serialization: catch yaml and json errors It is necessary to catch yaml and json errors that come from invalid json / yaml streams like '{}}'. Having an enumeration after a key value was set is a yaml parser error. Change-Id: Ia8b298c3f1b36c6dee29326955d1e76ade3104b1 --- .../tests/utils/test_serialization.py | 39 ++++++++----------- cloudbaseinit/utils/serialization.py | 6 ++- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/cloudbaseinit/tests/utils/test_serialization.py b/cloudbaseinit/tests/utils/test_serialization.py index 49cb2ea8..f7729418 100644 --- a/cloudbaseinit/tests/utils/test_serialization.py +++ b/cloudbaseinit/tests/utils/test_serialization.py @@ -15,39 +15,32 @@ import unittest import ddt -import yaml -try: - import unittest.mock as mock -except ImportError: - import mock from cloudbaseinit.utils import serialization +YAML_PARSER_ERROR_STRING = b""" +a: b +- c: d +""" + @ddt.ddt class SerializationUtilsTests(unittest.TestCase): - @ddt.data((b'', (None, False)), - (b'{}', ({}, False)), + @ddt.data((b'', (None, True)), + (b'{}', ({}, True)), + (YAML_PARSER_ERROR_STRING, (None, False)), + (b'{}}', (None, False)), (b'---', (None, True)), (b'test: test', ({"test": "test"}, True))) @ddt.unpack - @mock.patch("json.loads") - @mock.patch("yaml.load") def test_parse_data(self, stream, expected_parsed_output, - mock_yaml_load, mock_json_loads): - if not expected_parsed_output[1]: - mock_json_loads.return_value = expected_parsed_output[0] - else: - mock_json_loads.side_effect = TypeError("Failed to parse json") - mock_yaml_load.return_value = expected_parsed_output[0] - - parsed_output = serialization.parse_json_yaml(stream) - - mock_json_loads.assert_called_once_with(stream) + ): + print(expected_parsed_output) if expected_parsed_output[1]: - loader = getattr(yaml, 'CLoader', yaml.Loader) - mock_yaml_load.assert_called_once_with(stream, Loader=loader) - - self.assertEqual(parsed_output, expected_parsed_output[0]) + parsed_output = serialization.parse_json_yaml(stream) + self.assertEqual(parsed_output, expected_parsed_output[0]) + else: + with self.assertRaises(serialization.YamlParserConfigError): + serialization.parse_json_yaml(stream) diff --git a/cloudbaseinit/utils/serialization.py b/cloudbaseinit/utils/serialization.py index c3c73c9a..b51a7fb6 100644 --- a/cloudbaseinit/utils/serialization.py +++ b/cloudbaseinit/utils/serialization.py @@ -26,9 +26,11 @@ def parse_json_yaml(raw_data): try: return json.loads(raw_data) - except (TypeError, ValueError, AttributeError): + except (TypeError, ValueError, AttributeError, + json.decoder.JSONDecodeError): loader = getattr(yaml, 'CLoader', yaml.Loader) try: return yaml.load(raw_data, Loader=loader) - except (TypeError, ValueError, AttributeError): + except (TypeError, ValueError, AttributeError, + yaml.parser.ParserError, yaml.scanner.ScannerError): raise YamlParserConfigError("Invalid yaml data provided.")