From 487cb8718e3aaaf118263cc5f0ef33879747eaea Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 2 Jul 2026 17:37:17 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20preserve=20newlines=20in=20config=5Fupda?= =?UTF-8?q?ter=20insert/update=20=E2=80=94=20no=20extra=20newlines=20on=20?= =?UTF-8?q?key=20replacement,=20add=20leading=20nl=20when=20inserting=20at?= =?UTF-8?q?=20end=20without=20trailing=20nl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config_updater.c | 61 +++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/config_updater.c b/src/config_updater.c index 21256003..66b1e39b 100644 --- a/src/config_updater.c +++ b/src/config_updater.c @@ -151,21 +151,25 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap char *opt_pos = find_option(*buf, *buf_len, option); if (opt_pos) { - // Find option line end - char *line_end = strchr(opt_pos, '\n'); + // Determine if old line has trailing \n + char *nl = strchr(opt_pos, '\n'); + int has_trailing_nl = (nl != NULL); + char *line_end = nl ? nl : *buf + *buf_len; - if (!line_end) line_end = *buf + *buf_len; - // Prepare new line char new_line[MAX_LINE_LEN]; - int new_len = snprintf(new_line, sizeof(new_line), "%s=%s\n", option, value); - + int new_len; + if (has_trailing_nl) { + new_len = snprintf(new_line, sizeof(new_line), "%s=%s\n", option, value); + } else { + new_len = snprintf(new_line, sizeof(new_line), "%s=%s", option, value); + } if (new_len <= 0 || new_len >= (int)sizeof(new_line)) return -1; - + // Calculate length difference - size_t old_line_len = line_end - opt_pos + 1; + size_t old_line_len = has_trailing_nl ? (line_end - opt_pos + 1) : (line_end - opt_pos); long len_diff = new_len - old_line_len; - + // Ensure buffer capacity if (*buf_len + len_diff + 1 > *buf_capacity) { *buf_capacity = *buf_len + len_diff + 1024; @@ -177,11 +181,11 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap opt_pos = find_option(*buf, *buf_len, option); if (!opt_pos) return -1; - line_end = strchr(opt_pos, '\n'); - - if (!line_end) line_end = *buf + *buf_len; + nl = strchr(opt_pos, '\n'); + has_trailing_nl = (nl != NULL); + line_end = nl ? nl : *buf + *buf_len; } - + // Move content and insert new line memmove(opt_pos + new_len, line_end, *buf_len - (line_end - *buf) + 1); @@ -194,24 +198,31 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap char *section_end = find_section_global(*buf, *buf_len); if (!section_end) return -1; - + // Find end of global section (next [ or end of buffer) char *insert_pos = strchr(section_end, '['); + int need_leading_nl = 0; - if (!insert_pos) insert_pos = *buf + *buf_len; - else { + if (!insert_pos) { + insert_pos = *buf + *buf_len; + if (*buf_len > 0 && (*buf)[*buf_len - 1] != '\n') + need_leading_nl = 1; + } else { // Move to beginning of next line char *prev_nl = insert_pos; while (prev_nl > *buf && *prev_nl != '\n') prev_nl--; if (*prev_nl == '\n') insert_pos = prev_nl + 1; } - + // Prepare new line char new_line[MAX_LINE_LEN]; - int new_len = snprintf(new_line, sizeof(new_line), "%s=%s\n", option, value); - + int new_len; + if (need_leading_nl) + new_len = snprintf(new_line, sizeof(new_line), "\n%s=%s\n", option, value); + else + new_len = snprintf(new_line, sizeof(new_line), "%s=%s\n", option, value); if (new_len <= 0 || new_len >= (int)sizeof(new_line)) return -1; - + // Ensure buffer capacity if (*buf_len + new_len + 1 > *buf_capacity) { *buf_capacity = *buf_len + new_len + 1024; @@ -224,15 +235,19 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap if (!section_end) return -1; insert_pos = strchr(section_end, '['); + need_leading_nl = 0; - if (!insert_pos) insert_pos = *buf + *buf_len; - else { + if (!insert_pos) { + insert_pos = *buf + *buf_len; + if (*buf_len > 0 && (*buf)[*buf_len - 1] != '\n') + need_leading_nl = 1; + } else { char *prev_nl = insert_pos; while (prev_nl > *buf && *prev_nl != '\n') prev_nl--; if (*prev_nl == '\n') insert_pos = prev_nl + 1; } } - + // Move content and insert new line memmove(insert_pos + new_len, insert_pos, *buf_len - (insert_pos - *buf) + 1);