From fa0a77f84c67a70fa84769dd778a2b771345f667 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Mon, 17 Aug 2026 19:02:15 +0200 Subject: [PATCH] Add missing esc_tag() in status and parity split log tags --- AGENTS.md | 1 + cmdline/parity.c | 12 ++++++------ cmdline/state.c | 2 +- cmdline/status.c | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f4147f83..571f8203 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,6 +103,7 @@ SnapRAID is designed to recover from an interruption, including `SIGKILL`, at an - **Return codes**: `0` means no-error; `< 0` means error; positive for specific results - **Logging**: Use `log_fatal()`, `log_tag()`, `msg_info()`, `msg_progress()`, `msg_verbose()` from `support.h` +- **Tag Escaping**: When emitting structured tags with `log_tag()`, always wrap file paths, directory paths, link targets, disk names, filter patterns, and arbitrary string fields with `esc_tag()` to prevent colons (e.g., Windows drive letters `C:`), backslashes, or newlines from breaking colon-delimited tag parsing. - **Allocation**: Always use custom `malloc_nofail()`, `calloc_nofail()`, `nalloc_nofail()`, or `strdup_nofail()` wrappers (which handle OOM by aborting) - **Path Manipulation**: Never use standard unsafe string functions (`strcpy`, `strcat`, `strcmp`) on paths. Always use the platform-correct, size-bounded wrappers in `support.h` (e.g., `pathcpy()`, `pathcat()`, `pathcmp()`, `pathslash()`). - **TommyDS Iteration**: For `tommy_list`, iterate using: diff --git a/cmdline/parity.c b/cmdline/parity.c index 6bb78f3d..f6d2182d 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -291,9 +291,9 @@ static int parity_handle_grow(struct snapraid_split_handle* split, data_off_t pr #endif if (ret != 0) - log_tag("split:grow:%s:%" PRIu64 ": failed with error %s\n", split->path, size, strerror(errno)); + log_tag("split:grow:%s:%" PRIu64 ": failed with error %s\n", esc_tag(split->path), size, strerror(errno)); else - log_tag("split:grow:%s:%" PRIu64 ": ok\n", split->path, size); + log_tag("split:grow:%s:%" PRIu64 ": ok\n", esc_tag(split->path), size); return ret; } @@ -305,9 +305,9 @@ static int parity_handle_shrink(struct snapraid_split_handle* split, data_off_t ret = ftruncate(split->f, size); if (ret != 0) - log_tag("split:shrink:%s:%" PRIu64 ": failed with error %s\n", split->path, size, strerror(errno)); + log_tag("split:shrink:%s:%" PRIu64 ": failed with error %s\n", esc_tag(split->path), size, strerror(errno)); else - log_tag("split:shrink:%s:%" PRIu64 ": ok\n", split->path, size); + log_tag("split:shrink:%s:%" PRIu64 ": ok\n", esc_tag(split->path), size); return ret; } @@ -395,7 +395,7 @@ static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t si /* size we have to increase */ delta = size - base; - log_tag("split:fill:%s:%" PRIu64 ":%" PRIu64 ":\n", split->path, base, size); + log_tag("split:fill:%s:%" PRIu64 ":%" PRIu64 ":\n", esc_tag(split->path), base, size); /* grow the size one bit at time, like a kind of binary search */ while (delta != 0) { @@ -405,7 +405,7 @@ static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t si /* mask out the bit we process */ delta &= ~run; - log_tag("split:delta:%s:%" PRIu64 ":%" PRIu64 ":\n", split->path, base, run); + log_tag("split:delta:%s:%" PRIu64 ":%" PRIu64 ":\n", esc_tag(split->path), base, run); ret = parity_handle_grow(split, base, base + run, skip_fallocate); if (ret != 0) { diff --git a/cmdline/state.c b/cmdline/state.c index ea061a98..d3236a1e 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -3745,7 +3745,7 @@ static void* state_write_thread(void* arg) log_tag("content_parity_split:%s:%s:%s:%" PRIi64 "\n", parity_name, uuid, - state->parity[l].split_map[s].path, + esc_tag(state->parity[l].split_map[s].path), state->parity[l].split_map[s].size); } } diff --git a/cmdline/status.c b/cmdline/status.c index 27ad87fb..82059864 100644 --- a/cmdline/status.c +++ b/cmdline/status.c @@ -130,9 +130,9 @@ int state_status(struct snapraid_state* state) ++file_zerosubsecond; ++disk_file_zerosubsecond; if (disk_file_zerosubsecond < 50) - log_tag("zerosubsecond:%s:%s: \n", disk->name, file->sub); + log_tag("zerosubsecond:%s:%s: \n", disk->name, esc_tag(file->sub)); if (disk_file_zerosubsecond == 50) - log_tag("zerosubsecond:%s:%s: (more follow)\n", disk->name, file->sub); + log_tag("zerosubsecond:%s:%s: (more follow)\n", disk->name, esc_tag(file->sub)); } /* check fragmentation */