From 062904f44555b9b03096497ead5d456b5aabde73 Mon Sep 17 00:00:00 2001
From: Albert Graef <aggraef@gmail.com>
Date: Thu, 1 Apr 2021 10:51:45 +0200
Subject: [PATCH] Some bits of defensive programming to prevent string buffer
 overflows.

---
 pd/src/g_editor.c |  9 ++++++---
 pd/src/s_path.c   | 20 ++++++++++++++------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index c17610e03..f8db767e8 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -2412,7 +2412,7 @@ static int do_replace_subpatches(t_canvas *x, const char* label, t_binbuf *origi
 static void abstracthandler_callback(t_abstracthandler *x, t_symbol *s)
 {
     char fullpath[MAXPDSTRING], label[MAXPDSTRING], *dir, *filename;
-    char basename[MAXPDSTRING];
+    char basename[MAXPDSTRING], buf[MAXPDSTRING];
     memset(fullpath, '\0', MAXPDSTRING);
     memset(basename, '\0', MAXPDSTRING);
     memset(label, '\0', MAXPDSTRING);
@@ -2424,9 +2424,12 @@ static void abstracthandler_callback(t_abstracthandler *x, t_symbol *s)
     dir = fullpath;
     strncpy(basename, filename, strlen(filename) - 3);
     int flag, prefix = 0;
+    strncpy(buf,
+            canvas_getdir(canvas_getrootfor(x->tarjet))->s_name,
+            MAXPDSTRING);
+    buf[MAXPDSTRING-1] = 0;
     if (flag =
-        sys_relativizepath(canvas_getdir(canvas_getrootfor(x->tarjet))->s_name,
-            dir, label))
+        sys_relativizepath(buf, dir, label))
     {
         int len = strlen(label), creator, fd = -1;
         if (len && label[len-1] != '/')
diff --git a/pd/src/s_path.c b/pd/src/s_path.c
index 6c721c30c..d9c4e6360 100644
--- a/pd/src/s_path.c
+++ b/pd/src/s_path.c
@@ -196,11 +196,17 @@ int sys_isabsolutepath(const char *dir)
 }
 
 int sys_relativizepath(const char *from, const char *to, char *result)
+// precond: from and to fit into char[MAXPDSTRING]
+// postcond: result will fit into char[MAXPDSTRING]
 {
-    char fromext[FILENAME_MAX];
+    char fromext[MAXPDSTRING];
     sys_unbashfilename(from, fromext);
-    char toext[FILENAME_MAX];
+    char toext[MAXPDSTRING];
     sys_unbashfilename(to, toext);
+    // this will be large enough to hold the result in any case (FLW)
+    char buf[4*MAXPDSTRING];
+
+    memset(buf, '\0', 4*MAXPDSTRING);
 
     int i = 0, j;
     while(fromext[i] && toext[i] && fromext[i] == toext[i]) i++;
@@ -221,12 +227,12 @@ int sys_relativizepath(const char *from, const char *to, char *result)
             {
                 if(k == 0)
                 {
-                    strcpy(result+k, "..");
+                    strcpy(buf+k, "..");
                     k += 2;
                 }
                 else
                 {
-                    strcpy(result+k, "/..");
+                    strcpy(buf+k, "/..");
                     k += 3;
                 }
             }
@@ -234,9 +240,11 @@ int sys_relativizepath(const char *from, const char *to, char *result)
         }
         if(toext[j])
         {
-            result[k] = '/';
-            strcpy(result+k+1, toext+j+1);
+            buf[k] = '/';
+            strcpy(buf+k+1, toext+j+1);
         }
+        strncpy(result, buf, MAXPDSTRING);
+        result[MAXPDSTRING-1] = '\0';
     }
     else if(!fromext[i] && toext[j])
     {
-- 
GitLab