Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug with the new prompt redraw code



Bart Schaefer wrote:
> On Sun, 11 Jul 2004, Peter Stephenson wrote:
> > > (1) zle-line-init runs before the prompt is displayed
> > > (2) the prompt printing code has stashed a pointer to the value of 
> > > $PS1, which ends up pointing at reclaimed memory
> > 
> > How about passing the address of the prompt variable (the internal one,
> > i.e. prompt, rprompt, etc., not the parameter) to zle instead of the
> > prompt itself?
> 
> That might do it, but it'd be a moderately extensive change,

It's less than I thought.  That's because the caller either passes the
prompt string unmodified, or a locally defined prompt (in vared), or
NULL, so changing it to an address was relatively straightforward.  So
far.

> and it has to 
> be done carefully, because some other callers of zleread() pass NULL for 
> the rprompt and so on.

In any case, you learn to program defensively round here, since (e.g.) six
years ago somebody relied on an undocumented side effect.

> Also it doesn't address (1) but then maybe that doesn't matter.

I could be convinced it does, but see if this makes the problem go away
first.

Index: Doc/Zsh/zle.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v
retrieving revision 1.37
diff -u -r1.37 zle.yo
--- Doc/Zsh/zle.yo	2 Jul 2004 15:59:14 -0000	1.37
+++ Doc/Zsh/zle.yo	11 Jul 2004 22:34:21 -0000
@@ -1740,13 +1740,13 @@
 tindex(reset-prompt)
 item(tt(reset-prompt) (unbound) (unbound) (unbound))(
 Force the prompts on both the left and right of the screen to be
-re-expanded, then redisplay the edit buffer.  Note that this
-does not reflect changes to the prompt variables themselves, only changes
+re-expanded, then redisplay the edit buffer.  This
+reflects changes both to the prompt variables themselves and changes
 in the expansion of the values (for example, changes in time or
 directory, or changes to the value of variables referred to by the
 prompt).
 
-Otherwise, the prompt is only expaned each time zle starts, and
+Otherwise, the prompt is only expanded each time zle starts, and
 when the display as been interrupted by output from another part of the
 shell (such as a job notification) which causes the command line to be
 reprinted.
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.41
diff -u -r1.41 init.c
--- Src/init.c	2 Jun 2004 22:14:26 -0000	1.41
+++ Src/init.c	11 Jul 2004 22:34:42 -0000
@@ -1148,7 +1148,7 @@
 
 /**/
 unsigned char *
-autoload_zleread(char *lp, char *rp, int ha, int con)
+autoload_zleread(char **lp, char **rp, int ha, int con)
 {
     zlereadptr = fallback_zleread;
     if (load_module("zsh/zle"))
@@ -1158,12 +1158,12 @@
 
 /**/
 mod_export unsigned char *
-fallback_zleread(char *lp, UNUSED(char *rp), UNUSED(int ha), UNUSED(int con))
+fallback_zleread(char **lp, UNUSED(char **rp), UNUSED(int ha), UNUSED(int con))
 {
     char *pptbuf;
     int pptlen;
 
-    pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen);
+    pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL), &pptlen);
     write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
     free(pptbuf);
 
Index: Src/input.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/input.c,v
retrieving revision 1.10
diff -u -r1.10 input.c
--- Src/input.c	15 Dec 2003 22:45:29 -0000	1.10
+++ Src/input.c	11 Jul 2004 22:34:48 -0000
@@ -222,21 +222,21 @@
 static int
 inputline(void)
 {
-    char *ingetcline, *ingetcpmptl = NULL, *ingetcpmptr = NULL;
+    char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL;
     int context = ZLCON_LINE_START;
 
     /* If reading code interactively, work out the prompts. */
     if (interact && isset(SHINSTDIN)) {
 	if (!isfirstln) {
-	    ingetcpmptl = prompt2;
+	    ingetcpmptl = &prompt2;
 	    if (rprompt2)
-		ingetcpmptr = rprompt2;
+		ingetcpmptr = &rprompt2;
 	    context = ZLCON_LINE_CONT;
 	}
 	else {
-	    ingetcpmptl = prompt;
+	    ingetcpmptl = &prompt;
 	    if (rprompt)
-		ingetcpmptr = rprompt;
+		ingetcpmptr = &rprompt;
 	}
     }
     if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
@@ -255,7 +255,8 @@
 	     */
 	    char *pptbuf;
 	    int pptlen;
-	    pptbuf = unmetafy(promptexpand(ingetcpmptl, 0, NULL, NULL), &pptlen);
+	    pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL,
+					   0, NULL, NULL), &pptlen);
 	    write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
 	    free(pptbuf);
 	}
Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.14
diff -u -r1.14 loop.c
--- Src/loop.c	22 Jun 2004 13:10:02 -0000	1.14
+++ Src/loop.c	11 Jul 2004 22:34:54 -0000
@@ -245,7 +245,7 @@
 		    int oef = errflag;
 
 		    isfirstln = 1;
-		    str = (char *)zleread(prompt3, NULL, 0, ZLCON_SELECT);
+		    str = (char *)zleread(&prompt3, NULL, 0, ZLCON_SELECT);
 		    if (errflag)
 			str = NULL;
 		    errflag = oef;
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.57
diff -u -r1.57 zsh.h
--- Src/zsh.h	22 Jun 2004 13:10:02 -0000	1.57
+++ Src/zsh.h	11 Jul 2004 22:35:13 -0000
@@ -1800,7 +1800,7 @@
 
 typedef void (*ZleVoidFn) _((void));
 typedef void (*ZleVoidIntFn) _((int));
-typedef unsigned char * (*ZleReadFn) _((char *, char *, int, int));
+typedef unsigned char * (*ZleReadFn) _((char **, char **, int, int));
 
 /***************************************/
 /* Hooks in core.                      */
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.47
diff -u -r1.47 zle_main.c
--- Src/Zle/zle_main.c	2 Jul 2004 15:59:14 -0000	1.47
+++ Src/Zle/zle_main.c	11 Jul 2004 22:35:48 -0000
@@ -150,7 +150,7 @@
 /**/
 mod_export char *zlenoargs[1] = { NULL };
 
-static char *raw_lp, *raw_rp;
+static char **raw_lp, **raw_rp;
 
 #ifdef FIONREAD
 static int delayzsetterm;
@@ -742,7 +742,7 @@
 
 /**/
 unsigned char *
-zleread(char *lp, char *rp, int flags, int context)
+zleread(char **lp, char **rp, int flags, int context)
 {
     unsigned char *s;
     int old_errno = errno;
@@ -761,7 +761,8 @@
 	char *pptbuf;
 	int pptlen;
 
-	pptbuf = unmetafy(promptexpand(lp, 0, NULL, NULL), &pptlen);
+	pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL),
+			  &pptlen);
 	write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
 	free(pptbuf);
 	return (unsigned char *)shingetline();
@@ -788,10 +789,10 @@
     eofsent = 0;
     resetneeded = 0;
     raw_lp = lp;
-    lpromptbuf = promptexpand(lp, 1, NULL, NULL);
+    lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL);
     pmpt_attr = txtchange;
     raw_rp = rp;
-    rpromptbuf = promptexpand(rp, 1, NULL, NULL);
+    rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL);
     rpmpt_attr = txtchange;
     free_prepostdisplay();
 
@@ -1169,7 +1170,7 @@
     if (OPT_ISSET(ops,'h'))
 	hbegin(2);
     isfirstln = OPT_ISSET(ops,'e');
-    t = (char *) zleread(p1, p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0,
+    t = (char *) zleread(&p1, &p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0,
 			 ZLCON_VARED);
     if (OPT_ISSET(ops,'h'))
 	hend(NULL);
@@ -1315,9 +1316,9 @@
 reexpandprompt(void)
 {
     free(lpromptbuf);
-    lpromptbuf = promptexpand(raw_lp, 1, NULL, NULL);
+    lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL);
     free(rpromptbuf);
-    rpromptbuf = promptexpand(raw_rp, 1, NULL, NULL);
+    rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL);
 }
 
 /**/

-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxxxxxxxxx>
Work: pws@xxxxxxx
Web: http://www.pwstephenson.fsnet.co.uk



Messages sorted by: Reverse Date, Date, Thread, Author