Am Sat, Sep 05, 2026 at 05:35:22PM -0400 schrieb Andrew L. Moore:
> On 2026-09-05, 09:03, Harry Graf wrote:> IMHO filenames as a c-string in the 
> shell context should
> > be escapted.
> The following example works on every version of ed, ex and vi in the
> last last fifty plus years. This includes macOS ed (which preceded GNU

This is a very strong argument!
Probably it is a good idea to combine it with
the command flag: --unsafe-names

If the flag is set filenames will be escaped.

--- main_loop.c.bak     2026-09-05 14:40:30.916912956 +0200
+++ main_loop.c 2026-09-05 14:53:05.057013757 +0200
@@ -43,6 +43,41 @@
 static bool verbose = false;           /* print all error messages */
 
 
+static size_t shell_escape(char **esc, const char *str) {
+    size_t len;
+    size_t max_len;
+    size_t i;
+    char *escaped;
+    char *p;
+
+    if (!esc) return 0;
+    *esc = NULL;
+    if (!str) return 0;
+
+    len = strlen(str);
+    max_len = len * 4 + 3;
+    escaped = (char *)malloc(max_len);
+    if (!escaped) return 0;
+
+    p = escaped;
+    *p++ = '\'';
+    for (i = 0; i < len; i++) {
+        if (str[i] == '\'') {
+            *p++ = '\'';
+            *p++ = '\\';
+            *p++ = '\'';
+            *p++ = '\'';
+        } else {
+            *p++ = str[i];
+        }
+    }
+    *p++ = '\'';
+    *p = '\0';
+
+    *esc = escaped;
+    
+    return (size_t)(p - escaped);
+}
 int first_e_command( const char * const filename )
   { return read_file( filename, 0, &read_only ); }
 
@@ -143,9 +178,14 @@
     if( **ibufpp == '%' )      /* replace '%' with the default filename */
       {
       if( !def_filename[0] ) { set_error_msg( no_cur_fn ); return 0; }
-      len = strlen( def_filename );
+
+      char *esc_filename;
+      len = shell_escape( &esc_filename, def_filename );
+      if( esc_filename == NULL) return 0;
       if( !resize_buffer( &buf, &bufsz, i + len ) ) return 0;
-      memcpy( buf + i, def_filename, len );
+      memcpy( buf + i, esc_filename, len );
+      free( esc_filename);
+
       i += len; ++*ibufpp; replacement = true;
       }
     else               /* copy char or escape sequence unescaping any '%' */

Reply via email to