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 '%' */