Currently GNU ed(1) has a hard-coded limit of 80-characters in
main_loop.c:

  static char prompt_str[80] = "*";

However, this silently truncates if you create a prompt longer than
80 characters:

  ed -p"$(tput sc; tput home; seq $(( $COLUMNS / 10 )) | xargs printf %10i ; 
tput rc)" file.txt

The above maintains a ruler at the top of the screen and works in BSD
ed(1) but fails in GNU ed(1) because the resulting prompt is longer
than 80 chars.  GNU ed(1) silently truncates with strncpy() which can
truncate in the middle of ANSI escape sequences (or allow them to set
attributes but then be unable to unset them).

The attached diff dynamically allocates the prompt at run-time.  In
theory, it's just pointing at a constant/known string from argv so
these should be able to use `const * char` but ap_argument's .data
element doesn't seem to point directly to the const argv string but
rather a (non-const) copy of it.

Consider the patch released under whatever OSI-approved license you
need (WTFPL, BSD, MIT, Apache, GPL v2 or v3 or AGPL).

-Tim





--- ./main_loop.c	2019/04/15 15:00:20	1.1
+++ ./main_loop.c	2019/04/15 15:03:52
@@ -29,7 +29,8 @@
 
 static char def_filename[1024] = "";	/* default filename */
 static char errmsg[80] = "";		/* error message buffer */
-static char prompt_str[80] = "*";	/* command prompt */
+static char default_prompt_str[2] = "*";	/* default command prompt */
+static char * prompt_str = default_prompt_str;	/* command prompt */
 static int first_addr = 0, second_addr = 0;
 static bool prompt_on = false;		/* if set, show command prompt */
 static bool verbose = false;		/* if set, print all error messages */
@@ -50,9 +51,16 @@
 
 void set_prompt( const char * const s )
   {
+  size_t new_len;
+  char * new_prompt;
   prompt_on = true;
-  strncpy( prompt_str, s, sizeof prompt_str );
-  prompt_str[sizeof(prompt_str)-1] = 0;
+  new_len = strlen(s) + 1;
+  if ((new_prompt = malloc(new_len)))
+    if (strcpy(new_prompt, s))
+      {
+        if (prompt_str != default_prompt_str) free(prompt_str);
+        prompt_str = new_prompt;
+      }
   }
 
 void set_verbose( void ) { verbose = true; }
_______________________________________________
bug-ed mailing list
bug-ed@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-ed

Reply via email to