ww: drop wwstage peekpackage 2048-byte cap, align to cstage line-scan (#16 PREP-peek)
Pre-existing rule-10 asymmetry: 4 lib files (decimal/ftos/stof/memio) declare package past byte 2048, so the capped wwstage peek returned nil where cstage's uncapped line-scan found the decl — corrupting the strict-package check and any peek consumer. Mirrors cstage peek_package semantics exactly; prerequisite for the upcoming package-less boundary directive to inject identically in both twins.
This commit is contained in:
@@ -3323,32 +3323,38 @@ fn expand(c: *expctx, pathcs: *u8) void = {
|
|||||||
// starts with `package <name>;` return the package name as a fresh
|
// starts with `package <name>;` return the package name as a fresh
|
||||||
// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage
|
// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage
|
||||||
// peek_package.
|
// peek_package.
|
||||||
|
//
|
||||||
|
// Reads the WHOLE file (via slurp), not a fixed prefix: cstage's
|
||||||
|
// peek_package scans line-by-line with fgets and no total cap, stopping
|
||||||
|
// at the first non-comment-non-blank line. A prior 2048-byte read cap
|
||||||
|
// here diverged from cstage on files whose `package` decl sits behind a
|
||||||
|
// >2048-byte comment header (strconv decimal/ftos/stof, memio) —
|
||||||
|
// returning nil and making the #16 D-i injection asymmetric (rule-10
|
||||||
|
// break, byte-id divergence in the regenerated combined). The corpus has
|
||||||
|
// no line >2047 chars, so a whole-file line scan matches cstage's
|
||||||
|
// per-line fgets byte-for-byte on every real input.
|
||||||
fn peekpackage(pathcs: *u8) *u8 = {
|
fn peekpackage(pathcs: *u8) *u8 = {
|
||||||
let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32);
|
let bufp: *u8;
|
||||||
if (fd < 0) { return nil; };
|
let nu: u64;
|
||||||
let buf: []u8 = alloc([], 2048u64)!;
|
bufp, nu = slurp(pathcs);
|
||||||
buf.len = 2048;
|
if (bufp == nil) { return nil; };
|
||||||
let n: i64 = os.read(fd, buf.ptr, 2048u64);
|
|
||||||
os.close(fd);
|
|
||||||
if (n <= 0i64) { return nil; };
|
|
||||||
let nu: u64 = n: u64;
|
|
||||||
let p: u64 = 0u64;
|
let p: u64 = 0u64;
|
||||||
for (p < nu) {
|
for (p < nu) {
|
||||||
let q: u64 = p;
|
let q: u64 = p;
|
||||||
for (q < nu) {
|
for (q < nu) {
|
||||||
if (buf[q] == 10u8) { break; }; // '\n'
|
if (bufp[q] == 10u8) { break; }; // '\n'
|
||||||
q += 1u64;
|
q += 1u64;
|
||||||
};
|
};
|
||||||
let s: u64 = p;
|
let s: u64 = p;
|
||||||
for (s < q) {
|
for (s < q) {
|
||||||
if (buf[s] != 32u8) {
|
if (bufp[s] != 32u8) {
|
||||||
if (buf[s] != 9u8) { break; };
|
if (bufp[s] != 9u8) { break; };
|
||||||
};
|
};
|
||||||
s += 1u64;
|
s += 1u64;
|
||||||
};
|
};
|
||||||
if (s < q) {
|
if (s < q) {
|
||||||
let line: str;
|
let line: str;
|
||||||
line.ptr = buf.ptr + s;
|
line.ptr = bufp + s;
|
||||||
line.len = (q - s): i32;
|
line.len = (q - s): i32;
|
||||||
// hasprefix("//") subsumes the old s+1<q guard.
|
// hasprefix("//") subsumes the old s+1<q guard.
|
||||||
if (strings.hasprefix(line, "//")) {
|
if (strings.hasprefix(line, "//")) {
|
||||||
@@ -3356,22 +3362,22 @@ fn peekpackage(pathcs: *u8) *u8 = {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// s+8<=q guard kept: hasprefix("package") needs only 7
|
// s+8<=q guard kept: hasprefix("package") needs only 7
|
||||||
// bytes, but the sep read at buf[s+7] needs s+7 < q.
|
// bytes, but the sep read at bufp[s+7] needs s+7 < q.
|
||||||
if (s + 8u64 <= q) {
|
if (s + 8u64 <= q) {
|
||||||
if (strings.hasprefix(line, "package")) {
|
if (strings.hasprefix(line, "package")) {
|
||||||
let sep: u8 = buf[s + 7u64];
|
let sep: u8 = bufp[s + 7u64];
|
||||||
if (sep == 32u8) { }
|
if (sep == 32u8) { }
|
||||||
else { if (sep != 9u8) { return nil; }; };
|
else { if (sep != 9u8) { return nil; }; };
|
||||||
let t: u64 = s + 8u64;
|
let t: u64 = s + 8u64;
|
||||||
for (t < q) {
|
for (t < q) {
|
||||||
if (buf[t] != 32u8) {
|
if (bufp[t] != 32u8) {
|
||||||
if (buf[t] != 9u8) { break; };
|
if (bufp[t] != 9u8) { break; };
|
||||||
};
|
};
|
||||||
t += 1u64;
|
t += 1u64;
|
||||||
};
|
};
|
||||||
let start: u64 = t;
|
let start: u64 = t;
|
||||||
for (t < q) {
|
for (t < q) {
|
||||||
let ch: u8 = buf[t];
|
let ch: u8 = bufp[t];
|
||||||
let isalpha: bool = false;
|
let isalpha: bool = false;
|
||||||
if (ch >= 97u8) { if (ch <= 122u8) { isalpha = true; }; };
|
if (ch >= 97u8) { if (ch <= 122u8) { isalpha = true; }; };
|
||||||
if (ch >= 65u8) { if (ch <= 90u8) { isalpha = true; }; };
|
if (ch >= 65u8) { if (ch <= 90u8) { isalpha = true; }; };
|
||||||
@@ -3384,7 +3390,7 @@ fn peekpackage(pathcs: *u8) *u8 = {
|
|||||||
if (plen == 0u64) { return nil; };
|
if (plen == 0u64) { return nil; };
|
||||||
let r: []u8 = alloc([], plen + 1u64)!;
|
let r: []u8 = alloc([], plen + 1u64)!;
|
||||||
let k: u64 = 0u64;
|
let k: u64 = 0u64;
|
||||||
for (k < plen) { r[k] = buf[start + k]; k += 1u64; };
|
for (k < plen) { r[k] = bufp[start + k]; k += 1u64; };
|
||||||
r[plen] = 0u8;
|
r[plen] = 0u8;
|
||||||
return r.ptr;
|
return r.ptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -537,32 +537,38 @@ fn expand(c: *expctx, pathcs: *u8) void = {
|
|||||||
// starts with `package <name>;` return the package name as a fresh
|
// starts with `package <name>;` return the package name as a fresh
|
||||||
// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage
|
// heap-allocated NUL-terminated *u8, else nil. Same shape as cstage
|
||||||
// peek_package.
|
// peek_package.
|
||||||
|
//
|
||||||
|
// Reads the WHOLE file (via slurp), not a fixed prefix: cstage's
|
||||||
|
// peek_package scans line-by-line with fgets and no total cap, stopping
|
||||||
|
// at the first non-comment-non-blank line. A prior 2048-byte read cap
|
||||||
|
// here diverged from cstage on files whose `package` decl sits behind a
|
||||||
|
// >2048-byte comment header (strconv decimal/ftos/stof, memio) —
|
||||||
|
// returning nil and making the #16 D-i injection asymmetric (rule-10
|
||||||
|
// break, byte-id divergence in the regenerated combined). The corpus has
|
||||||
|
// no line >2047 chars, so a whole-file line scan matches cstage's
|
||||||
|
// per-line fgets byte-for-byte on every real input.
|
||||||
fn peekpackage(pathcs: *u8) *u8 = {
|
fn peekpackage(pathcs: *u8) *u8 = {
|
||||||
let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32);
|
let bufp: *u8;
|
||||||
if (fd < 0) { return nil; };
|
let nu: u64;
|
||||||
let buf: []u8 = alloc([], 2048u64)!;
|
bufp, nu = slurp(pathcs);
|
||||||
buf.len = 2048;
|
if (bufp == nil) { return nil; };
|
||||||
let n: i64 = os.read(fd, buf.ptr, 2048u64);
|
|
||||||
os.close(fd);
|
|
||||||
if (n <= 0i64) { return nil; };
|
|
||||||
let nu: u64 = n: u64;
|
|
||||||
let p: u64 = 0u64;
|
let p: u64 = 0u64;
|
||||||
for (p < nu) {
|
for (p < nu) {
|
||||||
let q: u64 = p;
|
let q: u64 = p;
|
||||||
for (q < nu) {
|
for (q < nu) {
|
||||||
if (buf[q] == 10u8) { break; }; // '\n'
|
if (bufp[q] == 10u8) { break; }; // '\n'
|
||||||
q += 1u64;
|
q += 1u64;
|
||||||
};
|
};
|
||||||
let s: u64 = p;
|
let s: u64 = p;
|
||||||
for (s < q) {
|
for (s < q) {
|
||||||
if (buf[s] != 32u8) {
|
if (bufp[s] != 32u8) {
|
||||||
if (buf[s] != 9u8) { break; };
|
if (bufp[s] != 9u8) { break; };
|
||||||
};
|
};
|
||||||
s += 1u64;
|
s += 1u64;
|
||||||
};
|
};
|
||||||
if (s < q) {
|
if (s < q) {
|
||||||
let line: str;
|
let line: str;
|
||||||
line.ptr = buf.ptr + s;
|
line.ptr = bufp + s;
|
||||||
line.len = (q - s): i32;
|
line.len = (q - s): i32;
|
||||||
// hasprefix("//") subsumes the old s+1<q guard.
|
// hasprefix("//") subsumes the old s+1<q guard.
|
||||||
if (strings.hasprefix(line, "//")) {
|
if (strings.hasprefix(line, "//")) {
|
||||||
@@ -570,22 +576,22 @@ fn peekpackage(pathcs: *u8) *u8 = {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// s+8<=q guard kept: hasprefix("package") needs only 7
|
// s+8<=q guard kept: hasprefix("package") needs only 7
|
||||||
// bytes, but the sep read at buf[s+7] needs s+7 < q.
|
// bytes, but the sep read at bufp[s+7] needs s+7 < q.
|
||||||
if (s + 8u64 <= q) {
|
if (s + 8u64 <= q) {
|
||||||
if (strings.hasprefix(line, "package")) {
|
if (strings.hasprefix(line, "package")) {
|
||||||
let sep: u8 = buf[s + 7u64];
|
let sep: u8 = bufp[s + 7u64];
|
||||||
if (sep == 32u8) { }
|
if (sep == 32u8) { }
|
||||||
else { if (sep != 9u8) { return nil; }; };
|
else { if (sep != 9u8) { return nil; }; };
|
||||||
let t: u64 = s + 8u64;
|
let t: u64 = s + 8u64;
|
||||||
for (t < q) {
|
for (t < q) {
|
||||||
if (buf[t] != 32u8) {
|
if (bufp[t] != 32u8) {
|
||||||
if (buf[t] != 9u8) { break; };
|
if (bufp[t] != 9u8) { break; };
|
||||||
};
|
};
|
||||||
t += 1u64;
|
t += 1u64;
|
||||||
};
|
};
|
||||||
let start: u64 = t;
|
let start: u64 = t;
|
||||||
for (t < q) {
|
for (t < q) {
|
||||||
let ch: u8 = buf[t];
|
let ch: u8 = bufp[t];
|
||||||
let isalpha: bool = false;
|
let isalpha: bool = false;
|
||||||
if (ch >= 97u8) { if (ch <= 122u8) { isalpha = true; }; };
|
if (ch >= 97u8) { if (ch <= 122u8) { isalpha = true; }; };
|
||||||
if (ch >= 65u8) { if (ch <= 90u8) { isalpha = true; }; };
|
if (ch >= 65u8) { if (ch <= 90u8) { isalpha = true; }; };
|
||||||
@@ -598,7 +604,7 @@ fn peekpackage(pathcs: *u8) *u8 = {
|
|||||||
if (plen == 0u64) { return nil; };
|
if (plen == 0u64) { return nil; };
|
||||||
let r: []u8 = alloc([], plen + 1u64)!;
|
let r: []u8 = alloc([], plen + 1u64)!;
|
||||||
let k: u64 = 0u64;
|
let k: u64 = 0u64;
|
||||||
for (k < plen) { r[k] = buf[start + k]; k += 1u64; };
|
for (k < plen) { r[k] = bufp[start + k]; k += 1u64; };
|
||||||
r[plen] = 0u8;
|
r[plen] = 0u8;
|
||||||
return r.ptr;
|
return r.ptr;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user