Stop bash arrays ending at the first ) inside a comment
Both the reader and the writer ran to the first closing paren, which is only the array's own close if nothing inside contains one. HOST1_WATCHDOG_SCAN_IGNORE has carried "(exit 127 — bad image)" for weeks: writes spliced into the middle of it and were refused by bash -n with a bare false, and reads returned the entries above it — the Rsync tab showed no intermediate scripts at all and 10 of 17 daily. Arrays now close on a ) that starts its own line, as confform already did.
This commit is contained in:
@@ -645,6 +645,31 @@ function vv_format_uptime(int $seconds): string {
|
||||
return ($d ? "{$d}d " : '') . ($h ? "{$h}h " : '') . "{$m}m";
|
||||
}
|
||||
|
||||
// ── Where a bash array ends ──────────────────────────────────────────────────────────────────
|
||||
// Both halves of this had the same bug independently, which is why the rule now lives in one
|
||||
// place: `[^)]*\)` — run to the first closing paren — is only the array's own close if no entry
|
||||
// or comment contains one. HOST1_WATCHDOG_SCAN_IGNORE has carried
|
||||
// `# broken test container (exit 127 — bad image)` for weeks, and the two sides failed differently
|
||||
// against it:
|
||||
//
|
||||
// writing vv_conf_write_file() spliced the new body into the middle of that comment and left
|
||||
// the real `)` stranded below as a stray token. `bash -n` caught it and vv_conf_edit()
|
||||
// rolled the file back, so no conf was corrupted — but the caller got a bare `false`
|
||||
// with an empty $rejected, and every future save of that list would have failed the
|
||||
// same silent way.
|
||||
// reading vv_parse_bash_array() stopped there and returned the entries above it, so the array
|
||||
// was quietly short. Only the PHP layer was affected: bash sources the file itself and
|
||||
// always saw every entry, so the watchdogs behaved correctly while the pages under-
|
||||
// reported what they were configured with — the failure mode with no symptom.
|
||||
//
|
||||
// confform.php's own reader was always right, and this is its rule: a multi-line array closes on
|
||||
// a `)` that starts its own line. Parens anywhere else are just text.
|
||||
//
|
||||
// CLOSE is non-capturing, for splicing a new body in. BODY captures — group 1 when the array is
|
||||
// written on one line, group 2 when it spans several.
|
||||
const VV_CONF_ARRAY_CLOSE = '(?:[^)\n]*\)|.*?\n[ \t]*\))';
|
||||
const VV_CONF_ARRAY_BODY = '(?:([^)\n]*)\)|\n(.*?)^[ \t]*\)[ \t]*$)';
|
||||
|
||||
// Parse a scalar value from raw conf text. Matches KEY="value" or KEY=value.
|
||||
// Identical logic was previously duplicated as vv_arr_scalar / vv_wd_scalar /
|
||||
// vv_fb_scalar / vv_media_conf_scalar — all reduce to this one regex.
|
||||
|
||||
Reference in New Issue
Block a user