build: separate package identity from storage paths
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package wwpackage;
|
||||
|
||||
import crypto.sha256;
|
||||
import hash;
|
||||
import os;
|
||||
import os.exec;
|
||||
import strconv;
|
||||
@@ -269,9 +271,9 @@ fn pkgkeepfile(name: str) bool = {
|
||||
|
||||
// One explicit package directory; with recurse (the DIR/... form) every
|
||||
// subdirectory whose name does not begin with '.' or '_' is descended as
|
||||
// well, Go's ./... convention. lstat is used for the root and each
|
||||
// candidate so a symlink cannot be used to cross the boundary (including
|
||||
// DT_UNKNOWN files); a symlinked subdirectory is skipped, not followed.
|
||||
// well, Go's ./... convention. An explicitly selected root may be a symlink;
|
||||
// canonical planning coalesces it with the target directory. Recursive child
|
||||
// symlinks remain skipped and symlink source files remain rejected.
|
||||
fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
||||
let rootstat: os.filestat;
|
||||
match (os.lstat(&rootstat, path)) {
|
||||
@@ -283,9 +285,14 @@ fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
||||
};
|
||||
};
|
||||
if (pkgmodeis(rootstat.mode, os.mode.LINK)) {
|
||||
pkgfailpath(path, "symlink traversal is not allowed");
|
||||
st.errors += 1;
|
||||
return;
|
||||
match (os.stat(&rootstat, path)) {
|
||||
case void => void;
|
||||
case let e: os.oserror => {
|
||||
pkgfailpath(path, "cannot stat package directory");
|
||||
st.errors += 1;
|
||||
return;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (!pkgmodeis(rootstat.mode, os.mode.DIR)) {
|
||||
pkgfailpath(path, "expected one package directory");
|
||||
@@ -540,7 +547,25 @@ fn pkgworkescape(s: str) str = {
|
||||
};
|
||||
|
||||
fn pkgworkkey(dir: str) str = {
|
||||
return strings.concat("d_", pkgworkescape(dir));
|
||||
let escaped: str = strings.concat("d_", pkgworkescape(dir));
|
||||
if (escaped.len <= 255) { return escaped; };
|
||||
let state: sha256.state = sha256.sha256();
|
||||
let h: *hash.hash = (&state): *hash.hash;
|
||||
hash.write(h, strings.toutf8("ww-request-workdir-v1:"));
|
||||
hash.write(h, strings.toutf8(dir));
|
||||
let digest: [32]u8;
|
||||
hash.sum(h, digest[0:32]);
|
||||
let out: []u8 = alloc([], 65u64)!;
|
||||
let digits: str = "0123456789abcdef";
|
||||
let i: i32 = 0;
|
||||
for (i < 32) {
|
||||
let high: i32 = (digest[i] / 16u8): i32;
|
||||
let low: i32 = (digest[i] % 16u8): i32;
|
||||
append(out, digits[high]);
|
||||
append(out, digits[low]);
|
||||
i += 1;
|
||||
};
|
||||
return strings.concat("d_", strings.frombytes(out));
|
||||
};
|
||||
|
||||
fn pkgsetplanpaths(p: *pkgplan, groups: []pkggroup, root: str, index: i32,
|
||||
|
||||
Reference in New Issue
Block a user