w6l: size -L/-l/input arrays by argc, not a fixed 64 (F-C)

libdirs, lflags and inputs were fixed 64-slot arrays written with no
bound check; the 65th -L/-l flag (or input) wrote past the allocation
-> heap corruption. Size all three by argc instead, the true upper
bound since each argv slot yields at most one entry, mirroring cstage
cmd/w6l/main.c:63-67 (calloc(argc, ...)). Drop the now-dead maxinputs
"too many inputs" cap -- cstage has none, and argc-sizing makes it
unreachable.

Regenerates the w6l combined.ww. Table-driven 632 test reaches a lib
only via the Nth -L (N in {1,64,65,100,128}, both stages); pre-fix the
nflags=65 row fails (slot one past the 64-array).
This commit is contained in:
2026-06-14 12:36:36 +09:00
parent 533333bd1a
commit 7a6b67fecc
4 changed files with 172 additions and 24 deletions

View File

@@ -176,15 +176,16 @@ fn isso(path: *u8) i32 = {
export fn main(argc: i32, argv: **u8) i32 = {
let outpath: *u8 = nil;
let maxinputs: i32 = 64;
let inputs: []*u8 = alloc([], maxinputs: u64)!;
inputs.len = maxinputs;
// argc is the upper bound on flags/inputs (one each per argv slot),
// mirroring cstage's calloc(argc, ...). No fixed cap.
let inputs: []*u8 = alloc([], argc: u64)!;
inputs.len = argc;
let ninputs: i32 = 0;
let libdirs: []*u8 = alloc([], maxinputs: u64)!;
libdirs.len = maxinputs;
let libdirs: []*u8 = alloc([], argc: u64)!;
libdirs.len = argc;
let nlibdirs: i32 = 0;
let lflags: []*u8 = alloc([], maxinputs: u64)!;
lflags.len = maxinputs;
let lflags: []*u8 = alloc([], argc: u64)!;
lflags.len = argc;
let nlflags: i32 = 0;
let i: i32 = 1;
@@ -242,11 +243,6 @@ export fn main(argc: i32, argv: **u8) i32 = {
return 2;
};};
} else {
if (ninputs >= maxinputs) {
let m: str = "w6l: too many inputs\n";
os.write(2, m.ptr, m.len: u64);
return 2;
};
inputs[ninputs] = a;
ninputs += 1;
};};};};