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

3.5 KiB

id status status_updated status_note component severity timestamp last_seen occurrences files tags related fix_commits
bug-1912 fixed 2026-10-03 lib wrong-result 2026-10-03T12:14:09Z 2026-10-03T12:14:09Z 1
src/lib/cluster.c
peers
parser
xceadmin
consistency
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