ww source: reject malformed UTF-8

This commit is contained in:
2026-08-22 03:14:53 +09:00
parent d61805262e
commit 4069eda942
10 changed files with 1146 additions and 30 deletions

View File

@@ -699,23 +699,34 @@ fn pkgident(c: u8) bool = {
return c >= '0' && c <= '9';
};
fn pkgnulerrors(path: str, src: str) bool = {
// Validate the selected physical source before package-clause classification.
// Go's source reader consumes malformed UTF-8 one byte at a time; raw NUL is
// the independent ASCII source error. Reporting both in byte order preserves
// the decoder's diagnostic precedence and raw-byte columns.
fn pkgsourceerrors(path: str, src: str) bool = {
let i: i32 = 0;
let ln: i32 = 1;
let cl: i32 = 1;
let found: bool = false;
for (i < src.len) {
if (src[i] == 0u8) {
let c: u8 = src[i];
let width: i32 = 1;
if (c >= 128u8) { width = pkgutf8width(src, i); };
if (c == 0u8) {
pkgfailsource(path, ln, cl, "invalid NUL character");
found = true;
} else { if (c >= 128u8 && width == 1) {
pkgfailsource(path, ln, cl, "invalid UTF-8 encoding");
found = true;
};
if (src[i] == '\n') {
};
if (c == '\n') {
ln += 1;
cl = 1;
} else {
cl += 1;
cl += width;
};
i += 1;
i += width;
};
return found;
};
@@ -2299,7 +2310,7 @@ export fn packagecommand(args: []str) int = {
pkgfailpath(ds.paths[i], "invalid or missing package clause");
return pkgteststatusfail(explicitstatus, compileonly);
};
if (pkgnulerrors(ds.paths[i], body)) {
if (pkgsourceerrors(ds.paths[i], body)) {
return pkgteststatusfail(explicitstatus, compileonly);
};
if (!pkgclause(body, &pn)) {