]> granicus.if.org Git - graphviz/commitdiff
smyrna: replace duplicated 'xml_string' with 'xml_escape'
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 30 Oct 2021 16:33:03 +0000 (09:33 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 6 Nov 2021 15:59:03 +0000 (08:59 -0700)
This completes the long journey of unifying four XML escaping routines into one.

Closes #1868.

cmd/smyrna/draw.c
cmd/smyrna/smyrna_utils.c
cmd/smyrna/smyrna_utils.h

index bd27476ab76cd2239f9b4468413afd75191b1ea1..300b78cb3f92a9ea53d10b173fbbe6e98f112c48 100644 (file)
@@ -15,9 +15,12 @@ XDOT DRAWING FUNCTIONS, maybe need to move them somewhere else
 */
 #include "draw.h"
 #include <common/colorprocs.h>
+#include <common/types.h>
+#include <common/utils.h>
 #include "smyrna_utils.h"
 #include <glcomp/glutils.h>
 #include <math.h>
+#include <stdlib.h>
 
 #include <xdot/xdot.h>
 #include "viewport.h"
@@ -320,6 +323,18 @@ static void InsertImage(sdot_op * o, int param)
     }
 }
 
+// see usage in EmbedText
+static int put(void *buffer, const char *s) {
+  char **b = buffer;
+
+  for (; *s != '\0'; ++s) {
+    **b = *s;
+    ++(*b);
+  }
+
+  return 0;
+}
+
 static void EmbedText(sdot_op* o, int param)
 {
        (void)param;
@@ -343,12 +358,22 @@ static void EmbedText(sdot_op* o, int param)
        y=o->op.u.text.y;
        if (!o->font)
        {
-               o->font=glNewFont(
-               view->widgets,
-               xml_string (o->op.u.text.text),
-               &view->penColor,
-               pangotext,
-               font_op->op.u.font.name,font_op->op.u.font.size,0);
+               // allocate a buffer large enough to hold the maximum escaped version of the
+               // text
+               char *escaped = calloc(sizeof(char), strlen(o->op.u.text.text) *
+                                                    sizeof("&#xFFFFFFFF;") + 1);
+               if (escaped == NULL)
+                 return;
+
+               // XML-escape the text
+               const xml_flags_t flags = {.dash = 1, .nbsp = 1};
+               char **ptr = &escaped;
+               (void)xml_escape(o->op.u.text.text, flags, put, ptr);
+
+               o->font = glNewFont(view->widgets, escaped, &view->penColor, pangotext,
+                                   font_op->op.u.font.name, font_op->op.u.font.size, 0);
+
+               free(escaped);
        }
        glCompDrawText3D(o->font,x,y,view->Topview->global_z,o->op.u.text.width,font_op->op.u.font.size);
 
index b2b91e052c660d7fbb893a7c40373e788549b625..a1602ba079c1f1724cfe209eec06ff255000c969 100644 (file)
  * Contributors: Details at https://graphviz.org
  *************************************************************************/
 #include "smyrna_utils.h"
-#include <common/memory.h>
 #include <common/types.h>
 #include <common/utils.h>
 #include <limits.h>
 
-/* return true if *s points to &[A-Za-z]+;      (e.g. &Ccedil; )
- *                          or &#[0-9]*;        (e.g. &#38; )
- *                          or &#x[0-9a-fA-F]*; (e.g. &#x6C34; )
- */
-static int xml_isentity(char *s)
-{
-    s++;                       /* already known to be '&' */
-    if (*s == ';') { // '&;' is not a valid entity
-       return 0;
-    }
-    if (*s == '#') {
-       s++;
-       if (*s == 'x' || *s == 'X') {
-           s++;
-           while ((*s >= '0' && *s <= '9')
-                  || (*s >= 'a' && *s <= 'f')
-                  || (*s >= 'A' && *s <= 'F'))
-               s++;
-       } else {
-           while (*s >= '0' && *s <= '9')
-               s++;
-       }
-    } else {
-       while ((*s >= 'a' && *s <= 'z')
-              || (*s >= 'A' && *s <= 'Z'))
-           s++;
-    }
-    if (*s == ';')
-       return 1;
-    return 0;
-}
-
-char *xml_string(char *s)
-{
-    static char *buf = NULL;
-    static int bufsize = 0;
-    char *p, *sub, *prev = NULL;
-    int len, pos = 0;
-
-    if (!buf) {
-       bufsize = 64;
-       buf = N_NEW(bufsize, char);
-    }
-
-    p = buf;
-    while (s && *s) {
-       if (pos > (bufsize - 8)) {
-           bufsize *= 2;
-           buf = realloc(buf, bufsize);
-           p = buf + pos;
-       }
-       /* escape '&' only if not part of a legal entity sequence */
-       if (*s == '&' && !(xml_isentity(s))) {
-           sub = "&amp;";
-           len = 5;
-       }
-       /* '<' '>' are safe to substitute even if string is already UTF-8 coded
-        * since UTF-8 strings won't contain '<' or '>' */
-       else if (*s == '<') {
-           sub = "&lt;";
-           len = 4;
-       }
-       else if (*s == '>') {
-           sub = "&gt;";
-           len = 4;
-       }
-       else if (*s == '-') {   /* can't be used in xml comment strings */
-           sub = "&#45;";
-           len = 5;
-       }
-       else if (*s == ' ' && prev && *prev == ' ') {
-           /* substitute 2nd and subsequent spaces with required_spaces */
-           sub = "&#160;";  /* inkscape doesn't recognise &nbsp; */
-           len = 6;
-       }
-       else if (*s == '"') {
-           sub = "&quot;";
-           len = 6;
-       }
-       else if (*s == '\'') {
-           sub = "&#39;";
-           len = 5;
-       }
-       else {
-           sub = s;
-           len = 1;
-       }
-       while (len--) {
-           *p++ = *sub++;
-           pos++;
-       }
-       prev = s;
-       s++;
-    }
-    *p = '\0';
-    return buf;
-}
-
 int l_int(void *obj, Agsym_t * attr, int def)
 {
     return late_int(obj, attr, def, INT_MIN);
index 03765c0b844b4c9db43607f94981f26a6f5bb13b..f936caed109fa580d401a44d637ff9599ed66818 100644 (file)
@@ -13,7 +13,6 @@
 #include "smyrnadefs.h"
 #include <cgraph/cgraph.h>
 
-extern char *xml_string(char *s);
 extern int l_int(void *obj, Agsym_t * attr, int def);
 extern float l_float(void *obj, Agsym_t * attr, float def);
 extern int getAttrBool(Agraph_t* g,void* obj,char* attr_name,int def);