From 696e80130b9e4e62128b3293d5d22f9525365059 Mon Sep 17 00:00:00 2001 From: Hyeonggeun Oh Date: Tue, 13 Jan 2026 03:07:15 +0900 Subject: [PATCH] MINOR: tools: add chunk_escape_string() helper function This function takes a string appends it to a buffer in a format compatible with most languages (double-quoted, with special characters escaped). It handles standard escape sequences like \n, \r, \", \\. This generic utility is desined to be used for logging or debugging purposes where arbitrary string data needs to be safely emitted without breaking the output format. It will be primarily used by the upcoming dump_all_vars() sample fetch to dump variable contents safely. --- include/haproxy/tools.h | 7 ++++++ src/tools.c | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index f181a7601..f84f02d7d 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -466,6 +466,13 @@ char *escape_string(char *start, char *stop, const char escape, const long *map, const char *string, const char *string_stop); +/* + * Appends a quoted and escaped string to a chunk buffer. The string is + * enclosed in double quotes and special characters are escaped with backslash. + * Returns 0 on success, -1 if the buffer is too small (output is rolled back). + */ +int chunk_escape_string(struct buffer *chunk, const char *str, size_t len); + /* Below are RFC8949 compliant cbor encode helper functions, see source * file for functions descriptions */ diff --git a/src/tools.c b/src/tools.c index 460a34e18..9a4e1bf68 100644 --- a/src/tools.c +++ b/src/tools.c @@ -2129,6 +2129,60 @@ char *escape_string(char *start, char *stop, return NULL; } +/* + * Appends a quoted and escaped string to a chunk buffer. The string is + * enclosed in double quotes and special characters are escaped with backslash: + * ", \, \r, \n, \b, \0 + * Returns 0 on success, -1 if the buffer is too small (output is rolled back). + */ +int chunk_escape_string(struct buffer *chunk, const char *str, size_t len) +{ + size_t initial_data = chunk->data; + size_t i; + + /* Opening quote */ + if (chunk->data + 1 >= chunk->size) + return -1; + chunk->area[chunk->data++] = '"'; + + /* Escape and append each character */ + for (i = 0; i < len; i++) { + unsigned char c = str[i]; + const char *esc = NULL; + + if (c == '"') esc = "\\\""; + else if (c == '\\') esc = "\\\\"; + else if (c == '\r') esc = "\\r"; + else if (c == '\n') esc = "\\n"; + else if (c == '\b') esc = "\\b"; + else if (c == '\0') esc = "\\0"; + + if (esc) { + if (chunk->data + 2 >= chunk->size) { + chunk->data = initial_data; + return -1; + } + chunk->area[chunk->data++] = esc[0]; + chunk->area[chunk->data++] = esc[1]; + } else { + if (chunk->data + 1 >= chunk->size) { + chunk->data = initial_data; + return -1; + } + chunk->area[chunk->data++] = c; + } + } + + /* Closing quote */ + if (chunk->data + 1 >= chunk->size) { + chunk->data = initial_data; + return -1; + } + chunk->area[chunk->data++] = '"'; + + return 0; +} + /* CBOR helper to encode an uint64 value with prefix (3bits MAJOR type) * according to RFC8949 *