diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 13:36:33 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | fea3f2c5abf14aada5d9187b82985e51eb5b7a98 (patch) | |
| tree | 6dd3c54c8aaa1ad5941a74200b18da12e512b7fb /test/fs.py | |
| parent | be5f559939fc11cbfba95b4a7d518816bec8677a (diff) | |
| download | pardes-fea3f2c5abf14aada5d9187b82985e51eb5b7a98.tar.gz pardes-fea3f2c5abf14aada5d9187b82985e51eb5b7a98.zip | |
A path with a part over 255 bytes is refused, never a panic
std's statFile takes the kernel's ENAMETOOLONG for a bug (errnoBug), so a name, look, DumpDir or Save path with a part over 255 bytes panicked the editor (exec.kindOf via writeName, recentKeeps, dumpFailed). Every non-test statFile now goes through fs.statPath, which refuses such a name as NameTooLong first; fs.py drives long, looping, not-a-directory and not-ours paths through name, look, DumpDir, Dump and Save.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/fs.py')
| -rw-r--r-- | test/fs.py | 25 |
1 files changed, 25 insertions, 0 deletions
@@ -814,6 +814,30 @@ def signal_cleans_up(binary): assert not address.exists() and not detached.exists(), (sig, list(root.iterdir())) +def odd_paths(binary): + """Long and odd paths written where a path goes -- name, look, DumpDir, + Dump, Save -- are refused or said, never a crash: a part over 255 bytes + (ENAMETOOLONG), a loop of links (ELOOP), a file taken for a directory + (ENOTDIR), one not ours (EACCES).""" + with tempfile.TemporaryDirectory(prefix='pardes-odd-') as directory: + root = Path(directory) + (root / 'loop').symlink_to(root / 'loop') + (root / 'plain').write_bytes(b'x\n') + odd = ['/tmp/' + 'x' * 300 + '/f.txt', str(root / ('y' * 300)), str(root / 'loop' / 'f'), + str(root / 'plain' / 'f'), '/root/nope/f', str(root / 'a' / '..' / 'b.txt')] + with session(binary, root, 'odd') as (client, _): + serial = new_pane(client, b'text\n') + for path in odd: + for where, line in ((f'/pane/{serial}/name', path), ('/look', path), + ('/ctl', f'DumpDir {path}'), ('/ctl', 'Dump'), (f'/pane/{serial}/ctl', 'Save')): + try: + client.write(where, (line + '\n').encode()) + except OSError: + pass + assert client.read('/index'), (where, line) + client.write('/ctl', b'DumpDir\n') + + def cut_writes(binary): """A write bigger than a 9P message comes as several, cut anywhere: each command line runs once, whole, an Edit block once it ends, and a last @@ -846,6 +870,7 @@ def cut_writes(binary): def test(binary, quic=False): started = time.monotonic() cut_writes(binary) + odd_paths(binary) run_file(binary) exit_answers(binary) unattended_messages_expire(binary) |
