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
This commit is contained in:
Adrian Vladu 2020-06-24 14:28:56 +03:00
parent 58dfb24a6a
commit cbbcb98680
2 changed files with 20 additions and 25 deletions

View File

@ -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)

View File

@ -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.")