summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2022-06-10 13:15:18 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2022-06-10 13:15:18 -0400
commit91ce3b085738f9279e903ec8eb0d1339f7a6a0f0 (patch)
tree371e1d3e394d91c3fd4e2704ab230b50476a60d1 /src/buffer.c
parentca407dca5d367cf5778449634cc63687630efa7d (diff)
downloadlighttpd-git-91ce3b085738f9279e903ec8eb0d1339f7a6a0f0.tar.gz
[core] buffer_append_bs_escaped_json()
separate func from buffer_append_bs_escaped() so that both buffer_append_bs_escaped() and buffer_append_bs_escaped_json() can be slightly more specialized and optimized
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c82
1 files changed, 56 insertions, 26 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 35fed054..a0eae151 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -715,12 +715,10 @@ void buffer_append_string_c_escaped(buffer * const restrict b, const char * cons
void
buffer_append_bs_escaped (buffer * const restrict b,
- const char * restrict s, const size_t len,
- const buffer_bs_escape_t esc)
+ const char * restrict s, const size_t len)
{
/* replaces non-printable chars with escaped string
* default: \xHH where HH is the hex representation of the byte
- * json: \u00HH where HH is the hex representation of the byte
* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
/* Intended for use escaping string to be surrounded by double-quotes */
/* Performs single pass over string and is optimized for ASCII;
@@ -755,29 +753,61 @@ buffer_append_bs_escaped (buffer * const restrict b,
d[1] = c;
break;
default:
- if (0 == esc) { /* BS_ESCAPE_DEFAULT */
- /* non printable char => \xHH */
- d = buffer_extend(b, 4);
- d[0] = '\\';
- d[1] = 'x';
- d += 2;
- }
- else { /* BS_ESCAPE_JSON */
- /*(technically do not have to escape DEL (\127) or higher)*/
- /*(would be faster if handled in tighter do/while loop above)*/
- if (c >= 127) {
- buffer_append_char(b, (char)c);
- break;
- }
- d = buffer_extend(b, 6);
- d[0] = '\\';
- d[1] = 'u';
- d[2] = '0';
- d[3] = '0';
- d += 4;
- }
- d[0] = hex_chars_uc[c >> 4];
- d[1] = hex_chars_uc[c & 0xF];
+ /* non printable char => \xHH */
+ d = buffer_extend(b, 4);
+ d[0] = '\\';
+ d[1] = 'x';
+ d[2] = hex_chars_uc[c >> 4];
+ d[3] = hex_chars_uc[c & 0xF];
+ break;
+ }
+ }
+}
+
+
+void
+buffer_append_bs_escaped_json (buffer * const restrict b,
+ const char * restrict s, const size_t len)
+{
+ /* replaces non-printable chars with escaped string
+ * json: \u00HH where HH is the hex representation of the byte
+ * exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
+ /* Intended for use escaping string to be surrounded by double-quotes */
+ buffer_string_prepare_append(b, len);
+ for (const char * const end = s+len; s < end; ++s) {
+ unsigned int c;
+ const char * const ptr = s;
+ do {
+ c = *(const unsigned char *)s;
+ } while (c >= ' ' && c != '"' && c != '\\' && ++s < end);
+ if (s - ptr) buffer_append_string_len(b, ptr, s - ptr);
+
+ if (s == end)
+ return;
+
+ /* ('\a', '\v' shortcuts are technically not json-escaping) */
+ /* ('\0' is also omitted due to the possibility of string corruption if
+ * the receiver supports decoding octal escapes (\000) and the escaped
+ * string contains \0 followed by two digits not part of escaping)*/
+
+ char *d;
+ switch (c) {
+ case '\a':case '\b':case '\t':case '\n':case '\v':case '\f':case '\r':
+ c = "0000000abtnvfr"[c];
+ __attribute_fallthrough__
+ case '"': case '\\':
+ d = buffer_extend(b, 2);
+ d[0] = '\\';
+ d[1] = c;
+ break;
+ default:
+ d = buffer_extend(b, 6);
+ d[0] = '\\';
+ d[1] = 'u';
+ d[2] = '0';
+ d[3] = '0';
+ d[4] = hex_chars_uc[c >> 4];
+ d[5] = hex_chars_uc[c & 0xF];
break;
}
}