From 2d10d171bbeccf1c57370c86f051f4805129de9c Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Sat, 30 Oct 2021 09:33:03 -0700 Subject: [PATCH] smyrna: replace duplicated 'xml_string' with 'xml_escape' This completes the long journey of unifying four XML escaping routines into one. Closes #1868. --- cmd/smyrna/draw.c | 37 ++++++++++++--- cmd/smyrna/smyrna_utils.c | 99 --------------------------------------- cmd/smyrna/smyrna_utils.h | 1 - 3 files changed, 31 insertions(+), 106 deletions(-) diff --git a/cmd/smyrna/draw.c b/cmd/smyrna/draw.c index bd27476ab..300b78cb3 100644 --- a/cmd/smyrna/draw.c +++ b/cmd/smyrna/draw.c @@ -15,9 +15,12 @@ XDOT DRAWING FUNCTIONS, maybe need to move them somewhere else */ #include "draw.h" #include +#include +#include #include "smyrna_utils.h" #include #include +#include #include #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("�") + 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); diff --git a/cmd/smyrna/smyrna_utils.c b/cmd/smyrna/smyrna_utils.c index b2b91e052..a1602ba07 100644 --- a/cmd/smyrna/smyrna_utils.c +++ b/cmd/smyrna/smyrna_utils.c @@ -8,109 +8,10 @@ * Contributors: Details at https://graphviz.org *************************************************************************/ #include "smyrna_utils.h" -#include #include #include #include -/* return true if *s points to &[A-Za-z]+; (e.g. Ç ) - * or &#[0-9]*; (e.g. & ) - * or &#x[0-9a-fA-F]*; (e.g. 水 ) - */ -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 = "&"; - 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 = "<"; - len = 4; - } - else if (*s == '>') { - sub = ">"; - len = 4; - } - else if (*s == '-') { /* can't be used in xml comment strings */ - sub = "-"; - len = 5; - } - else if (*s == ' ' && prev && *prev == ' ') { - /* substitute 2nd and subsequent spaces with required_spaces */ - sub = " "; /* inkscape doesn't recognise   */ - len = 6; - } - else if (*s == '"') { - sub = """; - len = 6; - } - else if (*s == '\'') { - sub = "'"; - 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); diff --git a/cmd/smyrna/smyrna_utils.h b/cmd/smyrna/smyrna_utils.h index 03765c0b8..f936caed1 100644 --- a/cmd/smyrna/smyrna_utils.h +++ b/cmd/smyrna/smyrna_utils.h @@ -13,7 +13,6 @@ #include "smyrnadefs.h" #include -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); -- 2.40.0