diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index a44bc6567720deb809624bda5deea25676493845..523ec2b843bc786b342c0b783599978e4e8504dd 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -1716,7 +1716,7 @@ char * canvas_path_replace(
 	{
 		// allocate memory for the new string
 		size_t const retlen = orilen + patcnt * (replen - patlen);
-		char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );
+		char * returned = (char *) malloc( sizeof(char) * (retlen + 1) );
 
 		if (returned != NULL)
 		{
@@ -1741,6 +1741,23 @@ char * canvas_path_replace(
 }
 
 
+char * canvas_parse_sys_filename_args(const char *name)
+{
+	//check for @sys_extra path and replace
+	char *final_name = NULL;
+	if (strstr(name, "@pd_extra") != NULL) {
+		t_namelist *path = pd_extrapath;
+		while (path->nl_next)
+			path = path->nl_next;
+		final_name = canvas_path_replace(name, "@pd_extra", path->nl_string);
+	}
+	else {
+		final_name = (char *) malloc( sizeof(char) * (strlen(name) + 1) );
+		strcpy(final_name, name); 
+	}
+	return(final_name);
+}
+
     /* utility function to read a file, looking first down the canvas's search
     path (set with "declare" objects in the patch and recursively in calling
     patches), then down the system one.  The filename is the concatenation of
@@ -1759,19 +1776,12 @@ int canvas_open(t_canvas *x, const char *name, const char *ext,
 {
     t_namelist *nl, thislist;
     int fd = -1;
+	int result = 0;
     t_canvas *y;
-	const char *final_name;
+	char *final_name;
 
-	//check for @sys_extra path and replace
-	if (strstr(name, "@pd_extra") != NULL) {
-		t_namelist *path = pd_extrapath;
-		while (path->nl_next)
-			path = path->nl_next;
-		final_name = canvas_path_replace(name, "@pd_extra", path->nl_string);
-	}
-	else {
-		final_name = name; 
-	}
+	//check for sys path and replace
+	final_name = canvas_parse_sys_filename_args(name);
 
         /* first check if "name" is absolute (and if so, try to open) */
     if (sys_open_absolute(final_name, ext, dirresult, nameresult, size, bin, &fd))
@@ -1808,8 +1818,9 @@ int canvas_open(t_canvas *x, const char *name, const char *ext,
                     return (fd);
         }
     }
-    return (open_via_path((x ? canvas_getdir(x)->s_name : "."), final_name, ext,
-        dirresult, nameresult, size, bin));
+    result = open_via_path((x ? canvas_getdir(x)->s_name : "."), final_name, ext, dirresult, nameresult, size, bin);
+	freebytes((void *)final_name, strlen(final_name));
+	return(result);
 }
 
 void canvasgop_draw_move(t_canvas *x, int doit)
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 66643201e1ced137946f97a2f703fc6772398db0..b4e01a937a79b1471058febbb390a16eb050076e 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -548,6 +548,10 @@ EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos,
     int *x1p, int *y1p, int *x2p, int *y2p);
 EXTERN int canvas_setdeleting(t_canvas *x, int flag);
 
+/* ---- for parsing @pd_extra and other sys paths in filenames  --------------------- */
+
+EXTERN char * canvas_parse_sys_filename_args(const char *name);
+
 typedef void (*t_undofn)(t_canvas *canvas, void *buf,
     int action);        /* a function that does UNDO/REDO */
 #define UNDO_FREE 0                     /* free current undo/redo buffer */
diff --git a/pd/src/s_path.c b/pd/src/s_path.c
index 0025096543f2a56e33718c14fa4e22d98e685d40..131c4ab70500cf6d92655afab5d29bd3be85843f 100644
--- a/pd/src/s_path.c
+++ b/pd/src/s_path.c
@@ -344,6 +344,8 @@ there is no search and instead we just try to open the file literally.  */
 /* see also canvas_open() which, in addition, searches down the
 canvas-specific path. */
 
+EXTERN const char * canvas_parse_sys_filename_args(const char *name);
+
 static int do_open_via_path(const char *dir, const char *name,
     const char *ext, char *dirresult, char **nameresult, unsigned int size,
     int bin, t_namelist *searchpath)
@@ -351,31 +353,38 @@ static int do_open_via_path(const char *dir, const char *name,
     t_namelist *nl;
     int fd = -1;
 
+	//check for sys path and replace
+	const char *final_name = canvas_parse_sys_filename_args(name);	
+
         /* first check if "name" is absolute (and if so, try to open) */
-    if (sys_open_absolute(name, ext, dirresult, nameresult, size, bin, &fd))
-        return (fd);
+    if (sys_open_absolute(final_name, ext, dirresult, nameresult, size, bin, &fd))
+        goto do_open_via_path_end;
     
         /* otherwise "name" is relative; try the directory "dir" first. */
-    if ((fd = sys_trytoopenone(dir, name, ext,
+    if ((fd = sys_trytoopenone(dir, final_name, ext,
         dirresult, nameresult, size, bin)) >= 0)
-            return (fd);
+            goto do_open_via_path_end;
 
         /* next go through the search path */
     for (nl = searchpath; nl; nl = nl->nl_next)
-        if ((fd = sys_trytoopenone(nl->nl_string, name, ext,
+        if ((fd = sys_trytoopenone(nl->nl_string, final_name, ext,
             dirresult, nameresult, size, bin)) >= 0)
-                return (fd);
+				goto do_open_via_path_end;
 
         /* next look in built-in paths like "extra" */
     if (sys_usestdpath)
         for (nl = pd_extrapath; nl; nl = nl->nl_next)
-            if ((fd = sys_trytoopenone(nl->nl_string, name, ext,
+            if ((fd = sys_trytoopenone(nl->nl_string, final_name, ext,
                 dirresult, nameresult, size, bin)) >= 0)
-                    return (fd);
+                    goto do_open_via_path_end;
 
     *dirresult = 0;
     *nameresult = dirresult;
+	freebytes((void *)final_name, strlen(final_name));
     return (-1);
+do_open_via_path_end:
+	freebytes((void *)final_name, strlen(final_name));
+	return (fd);
 }
 
     /* open via path, using the global search path. */