]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add chunk_escape_string() helper function
authorHyeonggeun Oh <hyeonggeun.oh@plaintexting.com>
Mon, 12 Jan 2026 18:07:15 +0000 (03:07 +0900)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Jan 2026 09:44:19 +0000 (10:44 +0100)
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
src/tools.c

index f181a7601413b9f7486ac798f63c70cb037b0c03..f84f02d7d680cce63c4037ea51e8fd699feb274a 100644 (file)
@@ -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
  */
index 460a34e18f88d3c6bcf99aa554ffb548b50b36ce..9a4e1bf6885d1aabc9862c6a3e5bc5736d8fd724 100644 (file)
@@ -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
  *