@@ -276,6 +276,37 @@ def test_loader(self):
276
276
self .assertEqual (linecache .getlines (filename , module_globals ),
277
277
['source for x.y.z\n ' ])
278
278
279
+ def test_invalid_names (self ):
280
+ for name , desc in [
281
+ ('\x00 ' , 'NUL bytes filename' ),
282
+ (__file__ + '\x00 ' , 'filename with embedded NUL bytes' ),
283
+ # A filename with surrogate codes. A UnicodeEncodeError is raised
284
+ # by os.stat() upon querying, which is a subclass of ValueError.
285
+ ("\uD834 \uDD1E .py" , 'surrogate codes (MUSICAL SYMBOL G CLEF)' ),
286
+ # For POSIX platforms, an OSError will be raised but for Windows
287
+ # platforms, a ValueError is raised due to the path_t converter.
288
+ # See: https://github.com/python/cpython/issues/122170
289
+ ('a' * 1_000_000 , 'very long filename' ),
290
+ ]:
291
+ with self .subTest (f'updatecache: { desc } ' ):
292
+ linecache .clearcache ()
293
+ lines = linecache .updatecache (name )
294
+ self .assertListEqual (lines , [])
295
+ self .assertNotIn (name , linecache .cache )
296
+
297
+ # hack into the cache (it shouldn't be allowed
298
+ # but we never know what people do...)
299
+ for key , fullname in [(name , 'ok' ), ('key' , name ), (name , name )]:
300
+ with self .subTest (f'checkcache: { desc } ' ,
301
+ key = key , fullname = fullname ):
302
+ linecache .clearcache ()
303
+ linecache .cache [key ] = (0 , 1234 , [], fullname )
304
+ linecache .checkcache (key )
305
+ self .assertNotIn (key , linecache .cache )
306
+
307
+ # just to be sure that we did not mess with cache
308
+ linecache .clearcache ()
309
+
279
310
280
311
class LineCacheInvalidationTests (unittest .TestCase ):
281
312
def setUp (self ):
0 commit comments