Document the PHP api layer and fix what documenting it exposed
Writing down what each endpoint actually guarantees made the places it didn't obvious — shell arguments reaching a crontab or a bash -c unescaped, master.conf written without tmp+rename, and conf edits that could be saved without ever being parsed.
This commit is contained in:
@@ -282,7 +282,23 @@ function vv_conf_write_changes(array $changes): array {
|
||||
) ?? $raw;
|
||||
}
|
||||
}
|
||||
$results[$file] = vv_write_conf_raw($file, $raw);
|
||||
// Only the scalar path escapes its value; the array, array_single and assoc_array
|
||||
// paths splice the caller's text into the file verbatim, and the type comes from the
|
||||
// request. Every script sources these files, so the result is parsed before it is
|
||||
// allowed to replace a working conf.
|
||||
$results[$file] = vv_conf_syntax_ok($raw) && vv_write_conf_raw($file, $raw);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
// bash -n against a private temp copy. Returns true when the content parses as a sourceable
|
||||
// conf, false otherwise — never writes anything itself.
|
||||
function vv_conf_syntax_ok(string $content): bool {
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'vvconf');
|
||||
if ($tmp === false) return true; // cannot check — do not block the write
|
||||
file_put_contents($tmp, $content);
|
||||
$out = []; $rc = 0;
|
||||
exec('bash -n ' . escapeshellarg($tmp) . ' 2>&1', $out, $rc);
|
||||
@unlink($tmp);
|
||||
return $rc === 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user