HTML-escaping mode is bound to come in handy.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 29 Oct 2008 22:41:51 +0000 (22:41 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 29 Oct 2008 22:41:51 +0000 (22:41 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/agedu@8226 cda61777-01e9-0310-a592-d414129be87e

malloc.c
malloc.h

index 3cb5dfe..f326e6d 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -69,7 +69,7 @@ char *dupfmt(const char *fmt, ...)
 
        while (*p) {
            const char *data = NULL;
-           int datalen = 0, stuffcr = 0;
+           int datalen = 0, stuffcr = 0, htmlesc = 0;
 
            if (*p == '%') {
                p++;
@@ -93,6 +93,10 @@ char *dupfmt(const char *fmt, ...)
                } else if (*p == 's') {
                    data = va_arg(ap, const char *);
                    datalen = strlen(data);
+               } else if (*p == 'h') {
+                   htmlesc = 1;
+                   data = va_arg(ap, const char *);
+                   datalen = strlen(data);
                } else if (assert(*p == 'S'), 1) {
                    stuffcr = va_arg(ap, int);
                    data = va_arg(ap, const char *);
@@ -106,20 +110,30 @@ char *dupfmt(const char *fmt, ...)
            }
 
            if (pass == 0) {
-               totallen += datalen;
-               if (stuffcr) {
-                   while (datalen > 0) {
-                       if (*data == '\n')
-                           totallen++;
-                       data++, datalen--;
-                   }
+               while (datalen > 0) {
+                   totallen++;
+                   if (stuffcr && *data == '\n')
+                       totallen++;
+                   if (htmlesc &&
+                       (*data == '<' || *data == '>' || *data == '&'))
+                       totallen += 4; /* max(len("gt;"),len("amp;")) */
+                   data++, datalen--;
                }
            } else {
                while (datalen > 0) {
-                   if (stuffcr && *data == '\n')
-                       *rp++ = '\r';
-                   *rp++ = *data++;
-                   datalen--;
+                   if (htmlesc && (*data < 32 || *data >= 127))
+                       *rp++ = '?';   /* *shrug* */
+                   else if (htmlesc && *data == '<')
+                       rp += sprintf(rp, "&lt;");
+                   else if (htmlesc && *data == '>')
+                       rp += sprintf(rp, "&gt;");
+                   else if (htmlesc && *data == '&')
+                       rp += sprintf(rp, "&amp;");
+                   else if (stuffcr && *data == '\n')
+                       *rp++ = '\r', *rp++ = '\n';
+                   else
+                       *rp++ = *data;
+                   data++, datalen--;
                }
            }
        }
index 608afc7..bd01899 100644 (file)
--- a/malloc.h
+++ b/malloc.h
@@ -40,6 +40,8 @@ char *dupstr(const char *s);
  *    printf)
  *  - %s takes a const char * and formats it like normal %s
  *    (again, no fine-tuning available)
+ *  - %h takes a const char * but escapes it so that it's safe for
+ *    HTML
  *  - %S takes an int followed by a const char *. If the int is
  *    zero, it behaves just like %s. If the int is nonzero, it
  *    transforms the string by stuffing a \r before every \n.