myxce/.wolf/bugs/bug-1912.md
Rongsong Shen 91782e4089
docs: bug-1909..1912 fixed; controller-peers-env-fallback gap notes resolved
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-03 13:07:37 +00:00

57 lines
3.5 KiB
Markdown

---
id: "bug-1912"
status: "fixed"
status_updated: "2026-10-03"
status_note: ""
component: "lib"
severity: "wrong-result"
timestamp: "2026-10-03T12:14:09Z"
last_seen: "2026-10-03T12:14:09Z"
occurrences: 1
files: ["src/lib/cluster.c"]
tags: ["peers", "parser", "xceadmin", "consistency"]
related: []
fix_commits: ["ef6e562c"]
---
# bug-1912: xce_parse_peers keeps spaces around entries; xceadmin trims them, so name matching differs
## Description
**Observed:**
```
$ XCE_CONTROLLER_PEERS="a=localhost:1, b=localhost:2, c=localhost:3" xce_controller --myname b ...
xce_controller: XCE_CONTROLLER_PEERS (a=localhost:1, b=localhost:2, c=localhost:3) has no candidate named 'b'; pass --myname <one of: a, b, c> ...
```
`xce_parse_peers()` splits on `,` and keeps the surrounding whitespace, so the second candidate's name is `" b"`. xceadmin's `resolve_controllers()` strips whitespace around each entry, so the same value works there.
**Expected:** spaces around entries are ignored, as in xceadmin: `"a=h:1, b=h:2"` parses as names `a` and `b`.
**Impact:** a peers list written with spaces after commas (natural in a shell variable or config) makes the controller's identity match fail (1.6 refusal from the env var, or a listener refusal with explicit --peers) and gives names/hosts with stray spaces in every C component. Shared libxce parser: affects controller, scheduler, worker, harness, apiserver backend.
**Found by:** audit (controller-peers-env-fallback feature validation)
## Environment
- OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64
- libc: glibc 2.42-47 (interpreter /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2)
- Toolchain: gcc (GCC) 15.2.0, meson 1.9.1
- Build: asan (xce.build)
- Code: scheduler-framework @ 66520e6b-dirty
- Deployment: n/a — single local process
## Reproduction
1. `XCE_CONTROLLER_PEERS="a=localhost:1, b=localhost:2, c=localhost:3" src/xce.build/controller/xce_controller --myname b --workdir <scratch> --certdir <empty scratch> --logfile <scratch>/c.log`
2. stderr shows the refusal listing candidates `a, b, c` (leading spaces).
- Frequency: deterministic, 2026-10-03
- Evidence: not kept
## Root cause
`xce_parse_peers()` (`src/lib/cluster.c`) splits on `,` with `strtok_r` and uses each token as-is, so whitespace after a comma becomes part of the next candidate's name (or hostname), and a blank entry is a parse error. xceadmin's `resolve_controllers()` strips each entry and skips blanks, so the same value meant different things to the C components and xceadmin.
## Fix
Trim leading/trailing `isspace()` characters from each token in place and skip tokens that are empty after trimming (they no longer use a `MAX_HA_CANDIDATES` slot); doc comment in `src/include/xce/cluster.h` updated. Previously valid inputs parse identically apart from losing stray outer whitespace.
## Verification
- Test: `test_parse_peers_trims_spaces_around_entries`, `test_parse_peers_trims_unnamed_entry`, `test_parse_peers_skips_blank_entries` (+ guards `test_parse_peers_all_blank_rejected`, `test_parse_peers_entry_without_port_rejected`) in `src/lib/testsuite/test_cluster.c` — RED before (`Expected 'b' Was ' b'`, `Expected 'localhost' Was ' localhost'`, `Expected 0 Was -1`), GREEN after; regression case `case_controller_env_spaced_list` RED → GREEN.
- Suites: libxce 730/0; `xce-build.sh all --incremental` (asan): C tests 127/0, scheduler 16/0, xceadmin 364 passed, no ASAN; regression script 35/35, 2026-10-03.
- Live: n/a
## References
- Related: none