@@ -218,8 +218,9 @@ def test_file_parsing_timeout(self):
218218 os.symlink("file", f"file{i}")
219219 """
220220 ).strip ()
221-
222- nsjail = NsJail (memfs_instance_size = 32 * Size .MiB , files_timeout = 1 )
221+ # A value higher than the actual memory needed is used to avoid the limit
222+ # on total file size being reached before the timeout when reading.
223+ nsjail = NsJail (memfs_instance_size = 512 * Size .MiB , files_timeout = 1 )
223224 result = nsjail .python3 (["-c" , code ])
224225 self .assertEqual (result .returncode , None )
225226 self .assertEqual (
@@ -250,6 +251,60 @@ def test_file_parsing_depth_limit(self):
250251 )
251252 self .assertEqual (result .stderr , None )
252253
254+ def test_file_parsing_size_limit_sparse_files (self ):
255+ tmpfs_size = 8 * Size .MiB
256+ code = dedent (
257+ f"""
258+ import os
259+ with open("test.txt", "w") as f:
260+ os.truncate(f.fileno(), { tmpfs_size // 2 + 1 } )
261+
262+ with open("test2.txt", "w") as f:
263+ os.truncate(f.fileno(), { tmpfs_size // 2 + 1 } )
264+ """
265+ )
266+ nsjail = NsJail (memfs_instance_size = tmpfs_size , files_timeout = 5 )
267+ result = nsjail .python3 (["-c" , code ])
268+ self .assertEqual (result .returncode , 0 )
269+ self .assertEqual (len (result .files ), 1 )
270+
271+ def test_file_parsing_size_limit_sparse_files_large (self ):
272+ tmpfs_size = 8 * Size .MiB
273+ code = dedent (
274+ f"""
275+ import os
276+ with open("test.txt", "w") as f:
277+ # Use a very large value to ensure the test fails if the
278+ # file is read even if would have been discarded later.
279+ os.truncate(f.fileno(), { 1024 * Size .TiB } )
280+ """
281+ )
282+ nsjail = NsJail (memfs_instance_size = tmpfs_size , files_timeout = 5 )
283+ result = nsjail .python3 (["-c" , code ])
284+ self .assertEqual (result .returncode , 0 )
285+ self .assertEqual (len (result .files ), 0 )
286+
287+ def test_file_parsing_size_limit_symlinks (self ):
288+ tmpfs_size = 8 * Size .MiB
289+ code = dedent (
290+ f"""
291+ import os
292+ data = "a" * 1024
293+ size = { tmpfs_size // 8 }
294+
295+ with open("file", "w") as f:
296+ for _ in range(size // 1024):
297+ f.write(data)
298+
299+ for i in range(20):
300+ os.symlink("file", f"file{{i}}")
301+ """
302+ )
303+ nsjail = NsJail (memfs_instance_size = tmpfs_size , files_timeout = 5 )
304+ result = nsjail .python3 (["-c" , code ])
305+ self .assertEqual (result .returncode , 0 )
306+ self .assertEqual (len (result .files ), 8 )
307+
253308 def test_file_write_error (self ):
254309 """Test errors during file write."""
255310 result = self .nsjail .python3 (
0 commit comments