Bugfixes to the json un-escaping function. Added some unit tests

for that.
pull/1/head
Michael Chisholm 2020-06-03 19:03:29 -04:00
parent 2179028c91
commit f17f782134
2 changed files with 43 additions and 15 deletions

View File

@ -521,6 +521,24 @@ def _make_json_serializable(value):
return json_value
_JSON_ESCAPE_RE = re.compile(r"\\.")
# I don't think I should need to worry about the unicode escapes (\uXXXX)
# since I use ensure_ascii=False when generating it. I will just fix all
# the other escapes, e.g. \n, \r, etc.
#
# This list is taken from RFC8259 section 7:
# https://tools.ietf.org/html/rfc8259#section-7
# Maps the second char of a "\X" style escape, to a replacement char
_JSON_ESCAPE_MAP = {
'"': '"',
"\\": "\\",
"/": "/",
"b": "\b",
"f": "\f",
"n": "\n",
"r": "\r",
"t": "\t"
}
def _un_json_escape(json_string):
"""
Removes JSON string literal escapes. We should undo these things Python's
@ -532,21 +550,13 @@ def _un_json_escape(json_string):
:return: The unescaped string
"""
# I don't think I should need to worry about the unicode escapes (\uXXXX)
# since I use ensure_ascii=False when generating it. I will just fix all
# the other escapes, e.g. \n, \r, etc.
#
# This list is taken from RFC8259 section 7:
# https://tools.ietf.org/html/rfc8259#section-7
def replace(m):
replacement = _JSON_ESCAPE_MAP.get(m.group(0)[1])
if replacement is None:
raise ValueError("Unrecognized JSON escape: " + m.group(0))
result = json_string\
.replace(r"\"", "\"")\
.replace(r"\/", "/")\
.replace(r"\b", "\b")\
.replace(r"\f", "\f")\
.replace(r"\n", "\n")\
.replace(r"\r", "\r")\
.replace(r"\t", "\t")\
.replace(r"\\", "\\") # Must do this one last!
return replacement
result = _JSON_ESCAPE_RE.sub(replace, json_string)
return result

View File

@ -210,3 +210,21 @@ def test_empty_hash():
with pytest.raises(stix2.exceptions.InvalidValueError):
SomeSCO(hashes={})
@pytest.mark.parametrize("json_escaped, expected_unescaped", [
("", ""),
("a", "a"),
(r"\n", "\n"),
(r"\n\r\b\t\\\/\"", "\n\r\b\t\\/\""),
(r"\\n", r"\n"),
(r"\\\n", "\\\n")
])
def test_json_unescaping(json_escaped, expected_unescaped):
actual_unescaped = stix2.base._un_json_escape(json_escaped)
assert actual_unescaped == expected_unescaped
def test_json_unescaping_bad_escape():
with pytest.raises(ValueError):
stix2.base._un_json_escape(r"\x")