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

rs-commit at redwax.eu rs-commit at redwax.eu
Mon Nov 22 10:47:44 CET 2021


Author: minfrin at redwax.eu
Date: Mon Nov 22 10:47:43 2021
New Revision: 50

Log:
Add escaping for xml and yaml.

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 10:47:43 2021
@@ -472,6 +472,137 @@
     return str;
 }
 
+apr_status_t redwax_escape_entity(char *escaped, const char *str,
+        apr_ssize_t slen, int toasc, 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 (strchr("<>&\"", c)) {
+                    switch (c) {
+                    case '>': {
+                        memcpy(d, ">", 4);
+                        size += 4;
+                        d += 4;
+                        break;
+                    }
+                    case '<': {
+                        memcpy(d, "<", 4);
+                        size += 4;
+                        d += 4;
+                        break;
+                    }
+                    case '&': {
+                        memcpy(d, "&", 5);
+                        size += 5;
+                        d += 5;
+                        break;
+                    }
+                    case '\"': {
+                        memcpy(d, """, 6);
+                        size += 6;
+                        d += 6;
+                        break;
+                    }
+                    case '\'': {
+                        memcpy(d, "'", 6);
+                        size += 6;
+                        d += 6;
+                        break;
+                    }
+                    }
+                    found = 1;
+                }
+                else if (toasc && !apr_isascii(c)) {
+                    int offset = apr_snprintf((char *) d, 6, "&#%3.3d;", c);
+                    size += offset;
+                    d += offset;
+                    found = 1;
+                }
+                else {
+                    *d++ = c;
+                    size++;
+                }
+                ++s;
+                slen--;
+            }
+            *d = '\0';
+        }
+        else {
+            while ((c = *s) && slen) {
+                if (strchr("<>&\"", c)) {
+                    switch (c) {
+                    case '>': {
+                        size += 4;
+                        break;
+                    }
+                    case '<': {
+                        size += 4;
+                        break;
+                    }
+                    case '&': {
+                        size += 5;
+                        break;
+                    }
+                    case '\"': {
+                        size += 6;
+                        break;
+                    }
+                    case '\'': {
+                        size += 6;
+                        break;
+                    }
+                    }
+                    found = 1;
+                }
+                else if (toasc && !apr_isascii(c)) {
+                    char buf[8];
+                    size += apr_snprintf(buf, 6, "&#%3.3d;", c);
+                    found = 1;
+                }
+                else {
+                    size++;
+                }
+                ++s;
+                slen--;
+            }
+        }
+    }
+
+    if (len) {
+        *len = size;
+    }
+    if (!found) {
+        return APR_NOTFOUND;
+    }
+
+    return APR_SUCCESS;
+}
+
+const char* apr_pescape_entity(apr_pool_t *p, const char *str, int toasc)
+{
+    apr_size_t len;
+
+    switch (redwax_escape_entity(NULL, str, REDWAX_ESCAPE_STRING, toasc, &len)) {
+    case APR_SUCCESS: {
+        char *cmd = apr_palloc(p, len);
+        redwax_escape_entity(cmd, str, REDWAX_ESCAPE_STRING, toasc, NULL);
+        return cmd;
+    }
+    case APR_NOTFOUND: {
+        break;
+    }
+    }
+
+    return str;
+}
+
 static const char base16[] = "0123456789ABCDEF";
 static const char base16lower[] = "0123456789abcdef";
 
@@ -1076,8 +1207,6 @@
 
     void *k = (void *)key;
     int klen = k ? strlen(k) : 0;
-    void *v = (void *)val;
-    int vlen = v ? strlen(v) : 0;
 
     int array = ml->array;
     int object = ml->object;
@@ -1091,7 +1220,10 @@
     case REDWAX_FORMAT_TEXT:
         break;
     case REDWAX_FORMAT_XML: {
-// FIXME: handle escaping of the value
+
+        void *v = (void *)apr_pescape_entity(m->pool, val, 1);
+        int vlen = v ? strlen(v) : 0;
+
         if (!v) {
 
             const struct iovec vec[] = {
@@ -1125,6 +1257,9 @@
         break;
     }
     case REDWAX_FORMAT_JSON: {
+// FIXME escape json
+        void *v = (void *)val;
+        int vlen = v ? strlen(v) : 0;
 
         if (object) {
 
@@ -1191,6 +1326,8 @@
     }
     case REDWAX_FORMAT_YAML: {
 
+        void *v = (void *)val;
+
         if (object) {
 
             if (!v) {
@@ -1210,11 +1347,59 @@
                         {"\n", 1},
                         {m->prefix, m->prefix_len},
                         {k, klen},
-                        {": ", 2},
-                        {v, vlen},
+                        {": ", 2}
                 };
 
-                status = m->wv(m->ctx, vec, 5);
+                status = m->wv(m->ctx, vec, 4);
+
+                if (APR_SUCCESS == status) {
+
+                    void *l = strchr(v, '\n');
+
+                    if (l) {
+
+                        const struct iovec vec[] = {
+                                {"|\n", 2}
+                        };
+
+                        status = m->wv(m->ctx, vec, 1);
+
+                        while (APR_SUCCESS == status && l) {
+
+                            const struct iovec vec[] = {
+                                    {m->prefix, m->prefix_len},
+	                                {"  ", 2},
+                                    {v, l - v + 1},
+                            };
+
+                            status = m->wv(m->ctx, vec, 3);
+
+                            l = strchr((v = l + 1), '\n');
+                        };
+
+                        if (APR_SUCCESS == status) {
+
+                            const struct iovec vec[] = {
+                                    {m->prefix, m->prefix_len},
+	                                {"  ", 2},
+                                    {v, strlen(v)},
+                            };
+
+                            status = m->wv(m->ctx, vec, 3);
+                        }
+
+                    }
+
+                    else if (APR_SUCCESS == status) {
+
+                        const struct iovec vec[] = {
+                                {v, strlen(v)},
+                        };
+
+                        status = m->wv(m->ctx, vec, 1);
+                    }
+
+                }
             }
 
         }

Modified: redwax-tool/trunk/redwax_util.h
==============================================================================
--- redwax-tool/trunk/redwax_util.h	(original)
+++ redwax-tool/trunk/redwax_util.h	Mon Nov 22 10:47:43 2021
@@ -46,6 +46,11 @@
         const char *str, apr_ssize_t slen, apr_size_t *len);
 
 const char* redwax_pescape_all(apr_pool_t *p, const char *str);
+
+apr_status_t redwax_escape_entity(char *escaped, const char *str,
+        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_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