[rs-commit] r52 - in /redwax-tool/trunk: redwax_util.c redwax_util.h

rs-commit at redwax.eu rs-commit at redwax.eu
Mon Nov 22 12:30:02 CET 2021


Author: minfrin at redwax.eu
Date: Mon Nov 22 12:30:01 2021
New Revision: 52

Log:
Handle json escaping.

Modified:
    redwax-tool/trunk/redwax_util.c
    redwax-tool/trunk/redwax_util.h

Modified: redwax-tool/trunk/redwax_util.c
==============================================================================
--- redwax-tool/trunk/redwax_util.c	(original)
+++ redwax-tool/trunk/redwax_util.c	Mon Nov 22 12:30:01 2021
@@ -112,6 +112,20 @@
     return where;
 }
 
+static APR_INLINE unsigned char *c2xx(unsigned what, unsigned char prefix,
+        unsigned char *where)
+{
+#if APR_CHARSET_EBCDIC
+    what = convert_e2a[(unsigned char)what];
+#endif /*APR_CHARSET_EBCDIC*/
+    *where++ = prefix;
+    *where++ = c2x_table[what >> 12 & 0xf];
+    *where++ = c2x_table[what >> 8 & 0xf];
+    *where++ = c2x_table[what >> 4 & 0xf];
+    *where++ = c2x_table[what & 0xf];
+    return where;
+}
+
 static int test_echo(char c)
 {
     if (c && (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c))) {
@@ -131,6 +145,14 @@
 static int test_all(char c)
 {
     return 1;
+}
+
+static int test_json(char c)
+{
+    if (c && (c == '"' || c == '\\' || apr_iscntrl(c))) {
+        return 1;
+    }
+    return 0;
 }
 
 apr_status_t redwax_escape_echo(char *escaped, const char *str,
@@ -603,6 +625,132 @@
     return str;
 }
 
+apr_status_t redwax_escape_json(char *escaped, const char *str,
+        apr_ssize_t slen, apr_size_t *len)
+{
+    apr_size_t size = 1;
+    int found = 0;
+    const unsigned char *s = (const unsigned char *) str;
+    unsigned char *d = (unsigned char *) escaped;
+    unsigned c;
+
+    if (s) {
+        if (d) {
+            while ((c = *s) && slen) {
+                if (test_json(c)) {
+                    *d++ = '\\';
+                    size++;
+                    switch (c) {
+                    case '\n':
+                        *d++ = 'n';
+                        size++;
+                        found = 1;
+                        break;
+                    case '\r':
+                        *d++ = 'r';
+                        size++;
+                        found = 1;
+                        break;
+                    case '\t':
+                        *d++ = 't';
+                        size++;
+                        found = 1;
+                        break;
+                    case '\b':
+                        *d++ = 'b';
+                        size++;
+                        found = 1;
+                        break;
+                    case '\f':
+                        *d++ = 'f';
+                        size++;
+                        found = 1;
+                        break;
+                    case '\\':
+                        *d++ = '\\';
+                        size++;
+                        found = 1;
+                        break;
+                    case '"':
+                        *d++ = c;
+                        size++;
+                        found = 1;
+                        break;
+                    default:
+                        c2xx(c, 'u', d);
+                        d += 5;
+                        size += 5;
+                        found = 1;
+                        break;
+                    }
+                }
+                else {
+                    *d++ = c;
+                    size++;
+                }
+                ++s;
+                slen--;
+            }
+            *d = '\0';
+        }
+        else {
+            while ((c = *s) && slen) {
+                if (test_json(c)) {
+                    size++;
+                    switch (c) {
+                    case '\n':
+                    case '\r':
+                    case '\t':
+                    case '\b':
+                    case '\f':
+                    case '\\':
+                    case '"':
+                        size++;
+                        found = 1;
+                        break;
+                    default:
+                        size += 5;
+                        found = 1;
+                        break;
+                    }
+                }
+                else {
+                    size++;
+                }
+                ++s;
+                slen--;
+            }
+        }
+    }
+
+    if (len) {
+        *len = size;
+    }
+    if (!found) {
+        return APR_NOTFOUND;
+    }
+
+    return APR_SUCCESS;
+}
+
+const char *redwax_pescape_json(apr_pool_t *p, const char *str)
+{
+    apr_size_t len;
+
+    switch (redwax_escape_json(NULL, str, REDWAX_ESCAPE_STRING, &len)) {
+    case APR_SUCCESS: {
+        char *cmd = apr_palloc(p, len);
+        redwax_escape_json(cmd, str, REDWAX_ESCAPE_STRING, NULL);
+        return cmd;
+    }
+    case APR_NOTFOUND: {
+        break;
+    }
+    }
+
+    return str;
+}
+
 static const char base16[] = "0123456789ABCDEF";
 static const char base16lower[] = "0123456789abcdef";
 
@@ -1257,8 +1405,8 @@
         break;
     }
     case REDWAX_FORMAT_JSON: {
-// FIXME escape json
-        void *v = (void *)val;
+
+        void *v = (void *)redwax_pescape_json(m->pool, val);
         int vlen = v ? strlen(v) : 0;
 
         if (object) {
@@ -1368,7 +1516,7 @@
 
                             const struct iovec vec[] = {
                                     {m->prefix, m->prefix_len},
-	                                {"  ", 2},
+                                    {"  ", 2},
                                     {v, l - v + 1},
                             };
 
@@ -1381,7 +1529,7 @@
 
                             const struct iovec vec[] = {
                                     {m->prefix, m->prefix_len},
-	                                {"  ", 2},
+                                    {"  ", 2},
                                     {v, strlen(v)},
                             };
 

Modified: redwax-tool/trunk/redwax_util.h
==============================================================================
--- redwax-tool/trunk/redwax_util.h	(original)
+++ redwax-tool/trunk/redwax_util.h	Mon Nov 22 12:30:01 2021
@@ -51,6 +51,11 @@
         apr_ssize_t slen, int toasc, apr_size_t *len);
 
 const char* apr_pescape_entity(apr_pool_t *p, const char *str, int toasc);
+
+apr_status_t redwax_escape_json(char *escaped, const char *str,
+        apr_ssize_t slen, apr_size_t *len);
+
+const char *redwax_pescape_json(apr_pool_t *p, const char *str);
 
 apr_status_t redwax_encode_base16_binary(char *dest, const unsigned char *src,
         apr_ssize_t slen, int flags, apr_size_t *len);



More information about the rs-commit mailing list