@@ -1977,3 +1977,59 @@ def test_uuid_map_key(self):
19771977 self .assertEqual (llsd .format_notation (llsdmap ), b"{'00000000-0000-0000-0000-000000000000':'uuid'}" )
19781978
19791979
1980+ class InvalidInputTypes (unittest .TestCase ):
1981+ '''
1982+ Tests for handling invalid input types that should raise LLSDParseError
1983+ instead of hanging or consuming infinite memory.
1984+ '''
1985+
1986+ @unittest .skipIf (PY2 , "MagicMock requires Python 3" )
1987+ def test_parse_magicmock_raises_error (self ):
1988+ '''
1989+ Parsing a MagicMock object should raise LLSDParseError, not hang.
1990+ This is a regression test for a bug where llsd.parse() would go into
1991+ an infinite loop when passed a MagicMock (e.g., from an improperly
1992+ mocked requests.Response.content).
1993+ '''
1994+ from unittest .mock import MagicMock
1995+ mock = MagicMock ()
1996+ with self .assertRaises (llsd .LLSDParseError ) as context :
1997+ llsd .parse (mock )
1998+ self .assertIn ('MagicMock' , str (context .exception ))
1999+
2000+ def test_parse_string_raises_error (self ):
2001+ '''
2002+ Parsing a string (not bytes) should raise LLSDParseError.
2003+ Only applies to Python 3 where str and bytes are distinct.
2004+ '''
2005+ with self .assertRaises (llsd .LLSDParseError ) as context :
2006+ llsd .parse (b'not bytes' .decode ('ascii' ))
2007+ self .assertIn ('unicode' if PY2 else 'str' , str (context .exception ))
2008+
2009+ def test_parse_none_raises_error (self ):
2010+ '''
2011+ Parsing None should raise LLSDParseError.
2012+ '''
2013+ with self .assertRaises (llsd .LLSDParseError ) as context :
2014+ llsd .parse (None )
2015+ self .assertIn ('NoneType' , str (context .exception ))
2016+
2017+ def test_parse_int_raises_error (self ):
2018+ '''
2019+ Parsing an integer should raise LLSDParseError.
2020+ '''
2021+ with self .assertRaises (llsd .LLSDParseError ) as context :
2022+ llsd .parse (42 )
2023+ self .assertIn ('int' , str (context .exception ))
2024+
2025+ def test_parse_non_seekable_stream_raises_error (self ):
2026+ '''
2027+ Parsing a non-seekable stream should raise LLSDParseError.
2028+ '''
2029+ stream = io .BytesIO ()
2030+ stream .seekable = lambda : False
2031+ with self .assertRaises (llsd .LLSDParseError ) as context :
2032+ llsd .parse (stream )
2033+ self .assertIn ('non-seekable' , str (context .exception ))
2034+
2035+
0 commit comments