lib/dirs: abort loudly on over-long path, not silent truncation (#69)
dirs build() capped the composed path at the 256B pathbuf with a silent break, so a HOME (or XDG_*) near/over ~240 bytes produced a truncated path that lookup() then mkdir'd and returned rc=0 — a silently-wrong, freshly-created directory. ref/hare/dirs/xdg.ha routes through path::set/push whose too_long error the `!` aborts loudly. Precompute the composition length in build() and rt_abort when it won't fit; drop the now-dead silent caps. (Shape (a); routing dirs through lib/path is the filed fidelity follow-up.) 975_dirs_toolong_run pins the abort + no-stray-dir on both driver twins.
This commit is contained in:
@@ -90,15 +90,24 @@ fn puts(off: i32, s: str) i32 = {
|
||||
// Embedded '/' in `sub` (e.g. ".local/share") is fine — [[os.mkdirs]]
|
||||
// handles intermediate dirs.
|
||||
fn build(base: str, sub: str, prog: str) void = {
|
||||
// ref/hare/dirs/xdg.ha routes through path::set/push, whose too_long
|
||||
// error the `!` turns into a loud abort. ww's fixed 256B pathbuf
|
||||
// (dirs.ww:58) is a documented simplification, but the overflow must
|
||||
// be LOUD, not a silently-wrong directory that then gets mkdir'd:
|
||||
// reject up front when the composition (+ trailing NUL) won't fit.
|
||||
// Shape (a); routing dirs through lib/path is the fidelity follow-up.
|
||||
let need: i32 = base.len + 1 + prog.len;
|
||||
if (sub.len > 0) { need += 1 + sub.len; };
|
||||
if (need >= 256) { rtabort("dirs: path too long"); };
|
||||
|
||||
let off: i32 = 0;
|
||||
off = puts(off, base);
|
||||
if (sub.len > 0) {
|
||||
if (off < 255) { pathbuf[off] = SEP; off += 1; };
|
||||
pathbuf[off] = SEP; off += 1;
|
||||
off = puts(off, sub);
|
||||
};
|
||||
if (off < 255) { pathbuf[off] = SEP; off += 1; };
|
||||
pathbuf[off] = SEP; off += 1;
|
||||
off = puts(off, prog);
|
||||
if (off > 255) { off = 255; };
|
||||
pathbuf[off] = 0u8;
|
||||
pathlen = off;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user