@@ -555,6 +555,78 @@ async def test_get_metadata_with_non_string_content(
555555 assert retrieved is None
556556
557557
558+ NON_OBJECT_JSON = [
559+ pytest .param (b"[1, 2]" , id = "array" ),
560+ pytest .param (b'"x"' , id = "string" ),
561+ pytest .param (b"1" , id = "number" ),
562+ pytest .param (b"null" , id = "null" ),
563+ ]
564+
565+
566+ async def _store_raw_state (
567+ state_manager : StateManager , state : str , content : bytes
568+ ) -> None :
569+ entry = CacheEntry (fingerprint = hashlib .sha256 (content ).hexdigest (), content = content )
570+ await state_manager .backend .set (
571+ f"{ state_manager .key_prefix } { state } " , entry , ttl = 600
572+ )
573+
574+
575+ @pytest .mark .parametrize (
576+ "content" ,
577+ [
578+ pytest .param (b"1" * 5000 , id = "top-level" ),
579+ pytest .param (
580+ b'{"state": "s", "metadata": {"n": ' + b"1" * 5000 + b"}}" , id = "nested"
581+ ),
582+ ],
583+ )
584+ async def test_oversized_json_integer_is_malformed (
585+ state_manager : StateManager , content : bytes
586+ ) -> None :
587+ """An integer past the interpreter's digit limit is malformed data, not a ValueError."""
588+ await _store_raw_state (state_manager , "bad_state" , content )
589+
590+ assert await state_manager .validate_state ("bad_state" ) is False
591+ assert await state_manager .get_state_metadata ("bad_state" ) is None
592+ with pytest .raises (StateDataError , match = "Failed to parse state data" ):
593+ await state_manager .consume_state ("bad_state" )
594+
595+
596+ @pytest .mark .parametrize ("content" , NON_OBJECT_JSON )
597+ async def test_consume_state_with_non_object_json (
598+ state_manager : StateManager , content : bytes
599+ ) -> None :
600+ """consume_state() raises StateDataError (not TypeError) for JSON that is not an object."""
601+ await _store_raw_state (state_manager , "bad_state" , content )
602+
603+ with pytest .raises (StateDataError , match = "expected a JSON object" ):
604+ await state_manager .consume_state ("bad_state" )
605+ assert (
606+ await state_manager .backend .get (f"{ state_manager .key_prefix } bad_state" ) is None
607+ )
608+
609+
610+ @pytest .mark .parametrize ("content" , NON_OBJECT_JSON )
611+ async def test_validate_state_with_non_object_json (
612+ state_manager : StateManager , content : bytes
613+ ) -> None :
614+ """validate_state() returns False for JSON that is not an object."""
615+ await _store_raw_state (state_manager , "bad_state" , content )
616+
617+ assert await state_manager .validate_state ("bad_state" ) is False
618+
619+
620+ @pytest .mark .parametrize ("content" , NON_OBJECT_JSON )
621+ async def test_get_metadata_with_non_object_json (
622+ state_manager : StateManager , content : bytes
623+ ) -> None :
624+ """get_state_metadata() returns None for JSON that is not an object."""
625+ await _store_raw_state (state_manager , "bad_state" , content )
626+
627+ assert await state_manager .get_state_metadata ("bad_state" ) is None
628+
629+
558630async def test_get_metadata_with_non_dict_metadata (state_manager : StateManager ) -> None :
559631 """Test retrieving metadata when metadata is not a dict."""
560632 state = "test_state"
0 commit comments