This patch fixes many memory issues related with title --
especially with long titles in graphs.

The fix includes:

1. memory overwrite in 'spadAction'

(1) -> vp := draw(x,x=1..2); title(vp, new(100, "a".1)$String)
   Compiling function %C with type DoubleFloat -> DoubleFloat
   Graph data being transmitted to the viewport manager...
   FriCAS2D data being transmitted to the viewport manager...
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  3 (X_GetWindowAttributes)
  Resource id in failed request:  0x61616161
  Serial number of failed request:  777
  Current serial number in output stream:  778

2. buffer overflow in 'makeViewport'

3. memory leakage in 'funView2D'/'funView3D'

(if you run "title" in a loop)

- Qian

--
You received this message because you are subscribed to the Google Groups "FriCAS - 
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/8c7e41a7-de44-4daf-9bd6-68ebf9943aa1%40gmail.com.
diff --git a/src/graph/include/spadAction2d.H1 b/src/graph/include/spadAction2d.H1
index 455fef4a..fd4457ad 100644
--- a/src/graph/include/spadAction2d.H1
+++ b/src/graph/include/spadAction2d.H1
@@ -1,2 +1 @@
-extern int readViewman(void *, int);
 extern int spadAction(void);
diff --git a/src/graph/include/spadAction3d.H1 b/src/graph/include/spadAction3d.H1
index cc2cc432..753346ae 100644
--- a/src/graph/include/spadAction3d.H1
+++ b/src/graph/include/spadAction3d.H1
@@ -1,3 +1,2 @@
-extern int readViewman(void *, int);
 extern void scalePoint(viewTriple *);
 extern int spadAction(void);
diff --git a/src/graph/view2D/spadAction2d.c b/src/graph/view2D/spadAction2d.c
index a923ad88..8440b639 100644
--- a/src/graph/view2D/spadAction2d.c
+++ b/src/graph/view2D/spadAction2d.c
@@ -44,22 +44,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "util.H1"
 #include "strutil.h"
 
-/******************************
- * int readViewman(info,size) *
- ******************************/
-
-int
-readViewman(void * info,int size)
-{
-  int mold = 0;
-
-  fricas_sprintf_to_buf3(errorStr, "%s %d %s", "read of ", size,
-          " bytes from viewport manager\n");
-  mold = check(read(0,info,size));
-  return(mold);
-
-}
-
 /********************
  * int spadAction() *
  ********************/
@@ -95,8 +79,7 @@ spadAction(void)
 
   case changeTitle:
     readViewman(&i1,intSize);
-    readViewman(viewport->title,i1);
-    viewport->title[i1] = '\0';
+    readViewmanStr(viewport->title, i1, sizeof(viewport->title));
     writeTitle();
     writeControlTitle();
     XFlush(dsply);
@@ -105,8 +88,7 @@ spadAction(void)
 
   case writeView:
     readViewman(&i1,intSize);
-    readViewman(filename,i1);
-    filename[i1] = '\0';
+    readViewmanStr(filename, i1, sizeof(filename));
     fricas_sprintf_to_buf1(errorStr, "%s", "writing of viewport data");
     i3 = 0;
     readViewman(&i2,intSize);
diff --git a/src/graph/view2D/viewport2D.c b/src/graph/view2D/viewport2D.c
index 95b15f21..bc428ce5 100644
--- a/src/graph/view2D/viewport2D.c
+++ b/src/graph/view2D/viewport2D.c
@@ -514,7 +514,7 @@ makeViewport(char *title,int vX,int vY,int vW,int vH,int showCP)
   fprintf(stderr,"view2D: Made a viewport\n");
 #endif
 
-  strcpy(viewport->title,title);
+  strncpy(viewport->title, title, sizeof(viewport->title) - 1);
 
   viewport->closing      = no;
   viewport->allowDraw    = yes;   /* just draw axes the first time around */
diff --git a/src/graph/view3D/header.h b/src/graph/view3D/header.h
index 21009335..622b744e 100644
--- a/src/graph/view3D/header.h
+++ b/src/graph/view3D/header.h
@@ -269,7 +269,7 @@ typedef struct _buttonStruct {
 
 typedef struct _controlPanelStruct {
   Window        controlWindow, messageWindow, colormapWindow;
-  char          message[40];
+  char          message[80];
   buttonStruct  buttonQueue[maxButtons3D];
 } controlPanelStruct;
 
diff --git a/src/graph/view3D/spadAction3d.c b/src/graph/view3D/spadAction3d.c
index 1cf79001..23260f05 100644
--- a/src/graph/view3D/spadAction3d.c
+++ b/src/graph/view3D/spadAction3d.c
@@ -46,17 +46,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "all_3d.H1"
 #include "strutil.h"
 
-int
-readViewman (void *info,int size)
-{
-  int m = 0;
-
-  fricas_sprintf_to_buf1(errorStr, "%s", "read from viewport manager\n");
-  m = check(read( 0, info, size));
-
-  return(m);
-
-}
 void
 scalePoint (viewTriple *p)
 {
@@ -398,8 +387,7 @@ spadAction (void)
 
   case changeTitle:
     readViewman(&i1,intSize);
-    readViewman(viewport->title,i1);
-    viewport->title[i1] = '\0';
+    readViewmanStr(viewport->title, i1, sizeof(viewport->title));
     writeTitle();
     switch (doingPanel) {
     case CONTROLpanel:
@@ -418,8 +406,7 @@ spadAction (void)
 
   case writeView:
     readViewman(&i1,intSize);
-    readViewman(filename,i1);
-    filename[i1] = '\0';
+    readViewmanStr(filename, i1, sizeof(filename));
     fricas_sprintf_to_buf1(errorStr, "%s", "writing of viewport data");
     i3 = 0;
     readViewman(&i2,intSize);
diff --git a/src/graph/view3D/viewport3d.c b/src/graph/view3D/viewport3d.c
index 0e6530b9..b50375c5 100644
--- a/src/graph/view3D/viewport3d.c
+++ b/src/graph/view3D/viewport3d.c
@@ -545,7 +545,7 @@ makeViewport (void)
   viewport->thetaObj = 0.0;
   viewport->phiObj   = 0.0;
 
-  strcpy(viewport->title,viewData.title);
+  strncpy(viewport->title, viewData.title, sizeof(viewport->title) - 1);
 
   viewport->axesOn       = yes;
   viewport->regionOn     = no;
diff --git a/src/graph/viewman/fun2D.c b/src/graph/viewman/fun2D.c
index 666fd0e8..b61e24bb 100644
--- a/src/graph/viewman/fun2D.c
+++ b/src/graph/viewman/fun2D.c
@@ -137,6 +137,7 @@ funView2D(int viewCommand)
       i1 = strlen(s1);
       code = write(viewport->viewOut,&i1,intSize);
       code = write(viewport->viewOut,s1,i1);
+      free(s1);
       break;
 
     case writeView:
@@ -151,6 +152,7 @@ funView2D(int viewCommand)
         i2 = get_int(spadSock);
         code = write(viewport->viewOut,&i2,intSize);
       }
+      free(s1);
       break;
 
     case spadPressedAButton:
diff --git a/src/graph/viewman/fun3D.c b/src/graph/viewman/fun3D.c
index fd4e524e..64e59f2c 100644
--- a/src/graph/viewman/fun3D.c
+++ b/src/graph/viewman/fun3D.c
@@ -217,6 +217,7 @@ funView3D(int viewCommand)
       i1 = strlen(s1);
       code = write(viewport->viewOut,&i1,intSize);
       code = write(viewport->viewOut,s1,i1);
+      free(s1);
       break;
 
     case writeView:
@@ -231,6 +232,7 @@ funView3D(int viewCommand)
         i2 = get_int(spadSock);
         code = write(viewport->viewOut,&i2,intSize);
       }
+      free(s1);
       break;
 
     case diagOnOff:
diff --git a/src/include/util.H1 b/src/include/util.H1
index 0adcdc3b..f86a0e0f 100644
--- a/src/include/util.H1
+++ b/src/include/util.H1
@@ -4,3 +4,5 @@ extern char * saymemWithLine(char *, int, int, int);
 extern void myfree(void *, int);
 extern XPoint getWindowPositionXY(Display *, Window);
 extern XPoint getWindowSizeXY(Display *, Window);
+extern int readViewman(void *, int);
+extern int readViewmanStr(char *, int, int);
diff --git a/src/lib/util.c b/src/lib/util.c
index ad468f8d..f40997bd 100644
--- a/src/lib/util.c
+++ b/src/lib/util.c
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "fricas_c_macros.h"
 
+#include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -150,3 +151,35 @@ getWindowSizeXY(Display *display,Window w)
 
   return (size);
 }
+
+int
+readViewman(void *info, int size)
+{
+  int m = 0;
+
+  m = read(0, info, size);
+
+  return(m);
+}
+
+/*
+  Read 'size' bytes from stdin, and store it into 'buf' with size 'buf_size'.
+  If 'buf' is not large enough to hold the string, the result is truncated.
+*/
+
+int
+readViewmanStr(char *buf, int size, int buf_size)
+{
+  int m = 0;
+
+  if (size < buf_size) {
+    m = read(0, buf, size);
+  } else {
+    char *tmp = malloc(size * sizeof(char));
+    m = read(0, tmp, size);
+    strncpy(buf, tmp, buf_size - 1);
+    free(tmp);
+  }
+
+  return(m);
+}

Reply via email to