Repository navigation
JSON deserialization does not handle OverflowError #480
Description
Activity
Still reproduces on 1.14.1 and on main (ce04532), just not on the exact path from the report anymore.
The additional_data path was fixed by #664, released in serialization-json 1.11.8.
JsonParseNode.try_get_anythingno longer tries untyped strings as durations, so "50001140846:00021" stays a string. The root cause is still there though.parse_timedelta_stringbuilds a timedelta without guarding against overflow (date_utils.py#L51, #L76), and the callers only catch ValueError. So the same OverflowError still gets out of three other places:- a typed timedelta property in JSON (json_parse_node.py#L262-L270). "not-a-duration" gives None there, but these values crash deserialization of the whole response
FormParseNode.try_get_anything(form_parse_node.py#L277-L279), which still has the old parser chain, so it's the reported bug again in the form packageJsonSerializationWriter.write_timedelta_valuewith a string (json_serialization_writer.py#L144-L155), which leaks the raw OverflowError instead of its own "Invalid timedelta string value found"
It isn't limited to the hh:mm:ss fallback either. "P1000000000D" is a valid ISO 8601 duration, just past timedelta.max.
Repro, after
pip install microsoft-kiota-serialization-json==1.14.1 microsoft-kiota-serialization-form==1.14.1:from kiota_serialization_form.form_parse_node import FormParseNode from kiota_serialization_json.json_parse_node import JsonParseNode from kiota_serialization_json.json_serialization_writer import JsonSerializationWriter for value in ("50001140846:00021", "P1000000000D", "not-a-duration"): print(repr(value)) for label, call in ( ("json try_get_anything", lambda: JsonParseNode(value).try_get_anything(value)), ("json get_timedelta_value", lambda: JsonParseNode(value).get_timedelta_value()), ("form try_get_anything", lambda: FormParseNode(value).try_get_anything(value)), ("json write_timedelta_value", lambda: JsonSerializationWriter().write_timedelta_value("d", value)), ): try: print(f" {label}: {call()!r}") except Exception as exc: print(f" {label}: {type(exc).__name__}: {exc}")
Output on 1.14.1, and main gives the same. On 1.9.3 the json
try_get_anythinglines raise too, with the same traceback as in the report.'50001140846:00021' json try_get_anything: '50001140846:00021' json get_timedelta_value: OverflowError: days=2083380868; must have magnitude <= 999999999 form try_get_anything: OverflowError: days=2083380868; must have magnitude <= 999999999 json write_timedelta_value: OverflowError: days=2083380868; must have magnitude <= 999999999 'P1000000000D' json try_get_anything: 'P1000000000D' json get_timedelta_value: OverflowError: days=1000000000; must have magnitude <= 999999999 form try_get_anything: OverflowError: days=1000000000; must have magnitude <= 999999999 json write_timedelta_value: OverflowError: days=1000000000; must have magnitude <= 999999999 'not-a-duration' json try_get_anything: 'not-a-duration' json get_timedelta_value: None form try_get_anything: 'not-a-duration' json write_timedelta_value: ValueError: Invalid timedelta string value found for property dThe smallest fix is in date_utils: raise ValueError instead of OverflowError in
parse_timedelta_from_iso_formatand in the hh:mm:ss branch ofparse_timedelta_string. The json and form callers already handle ValueError, so that covers all three at once. I can send a PR for it.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone ✔️
Trying to deserialize certain misformatted strings result in an uncaught OverflowError exception instead of passing through the string unchanged. In particular, trying to deserialize a timedelta string such as
"50001140846:00021"results in the following:The issue is that
JsonParseNode.try_get_anything()only handles ValueError exceptions instead of also handling OverflowError. Changing this line to catch both ValueError and OverflowError allows deserialization to be successful:kiota-python/packages/serialization/json/kiota_serialization_json/json_parse_node.py
Line 336 in b23edcb
Most likely the other catch handlers in try_get_anything() should be updated as well.