From 00448223c5964c0c582c63b9e09efea9a6b0dcfe Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Mon, 19 Jun 2017 21:00:53 -0400
Subject: [PATCH] don't use functions that expect null-terminated strings with
 non-null-terminated strings

---
 pd/src/g_rtext.c | 11 ++++++++++-
 pd/src/g_text.c  |  8 +++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/pd/src/g_rtext.c b/pd/src/g_rtext.c
index ed03e36ce..6c4b9cdfc 100644
--- a/pd/src/g_rtext.c
+++ b/pd/src/g_rtext.c
@@ -557,6 +557,7 @@ void rtext_activate(t_rtext *x, int state)
 {
     //fprintf(stderr,"rtext_activate state=%d\n", state);
     int w = 0, h = 0, widthspec, heightspec, indx, isgop;
+    char *tmpbuf;
     t_glist *glist = x->x_glist;
     t_canvas *canvas = glist_getcanvas(glist);
     //if (state && x->x_active) printf("duplicate rtext_activate\n");
@@ -610,6 +611,13 @@ void rtext_activate(t_rtext *x, int state)
     /* we need to get scroll to make sure we've got the
        correct bbox for the svg */
     canvas_getscroll(glist_getcanvas(canvas));
+    /* ugly hack to get around the fact that x_buf is not
+       null terminated. If this becomes a problem we can revisit
+       it later */
+    tmpbuf = t_getbytes(x->x_bufsize + 1);
+    sprintf(tmpbuf, "%.*s", x->x_bufsize, x->x_buf);
+    /* in case x_bufsize is 0... */
+    tmpbuf[x->x_bufsize] = '\0';
     gui_vmess("gui_textarea", "xssiiiisiii",
         canvas,
         x->x_tag,
@@ -618,10 +626,11 @@ void rtext_activate(t_rtext *x, int state)
         x->x_text->te_ypix,
         widthspec,
         heightspec,
-        x->x_buf,
+        tmpbuf,
         sys_hostfontsize(glist_getfont(glist)),
         isgop,
         state);
+    freebytes(tmpbuf, x->x_bufsize + 1);
 }
 
 // outputs 1 if found one of the special chars
diff --git a/pd/src/g_text.c b/pd/src/g_text.c
index 7d8385b22..074d5aed7 100644
--- a/pd/src/g_text.c
+++ b/pd/src/g_text.c
@@ -3009,7 +3009,9 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
             //any point of recreating the object
             binbuf_gettext(x->te_binbuf, &c1, &i1);
             binbuf_gettext(b, &c2, &i2);
-            if (strcmp(c1, c2))
+            /* must remember that binbuf_gettext does *not*
+               null-terminate, so we have to be careful here... */
+            if (i1 != i2 || strncmp(c1, c2, i1))
             {
                 //fprintf(stderr,"string differs\n");
                 canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
@@ -3063,7 +3065,7 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
                more than just a series of nearly-incomprehensible
                side-effects, perhaps the issue may be revisited.
             */
-            if (strcmp(c1, c2))
+            if (i1 != i2 || strncmp(c1, c2, i1))
             {
                 //fprintf(stderr,"text_setto calls canvas_undo_add recreate\n");
                 canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
@@ -3130,7 +3132,7 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
         t_binbuf *b = binbuf_new();
         binbuf_text(b, buf, bufsize);
         binbuf_gettext(b, &c2, &i2);
-        if (!c1 || strcmp(c1, c2))
+        if (!c1 || i1 != i2 || strncmp(c1, c2, i1))
         {
             canvas_undo_add(glist_getcanvas(glist), 10, "typing",
                 (void *)canvas_undo_set_recreate(glist_getcanvas(glist),
-- 
GitLab