View Issue Details

IDProjectCategoryView StatusLast Update
0000074tcsh[All Projects] Generalpublic2019-05-08 18:06
ReporterbitstreamoutAssigned Tochristos 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
PlatformOSLinuxOS Version
Product Version 
Target VersionFixed in Version6.21.00 
Summary0000074: Bug in tcsh postcmd alias handling
DescriptionThe postcmd alias destroys boolean handling withing loops
Steps To Reproducesimple script to test this on tcsh 6.18.0 as well as on 6.20.0

 # !/bin/tcsh
 alias postcmd false

 set counter=5

 while ($counter > 0)
   @ counter--
   echo $counter
   sleep 1
 end
 exit 0

... this should break for counter getting 0 but it does not
TagsNo tags attached.

Activities

bitstreamout

2019-04-05 09:16

reporter   ~0003232

Hmmm .. .after some debugging it looks like the function dowhile() of sh.func.c is executed repeated if no postcmd alias is set whereas if one is set the dowhile() is reached only once and does never finish

debug (1,613 bytes)
(gdb) br dowhile
Breakpoint 1 at 0x189e0: file sh.func.c, line 566.
(gdb) run -f x.csh
[...]
Breakpoint 1, dowhile (v=0x5555555fe130, c=0x5555555fdb80) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) cont
Continuing.
4
[Detaching after fork from child process 17695]

Breakpoint 1, dowhile (v=0x5555555fdd30, c=0x5555555fdaf0) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) 
Continuing.
3
[Detaching after fork from child process 17696]

Breakpoint 1, dowhile (v=0x5555555fe1a0, c=0x5555555fe310) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) 
Continuing.
2
[Detaching after fork from child process 17697]

Breakpoint 1, dowhile (v=0x5555555ff850, c=0x5555555ff6a0) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) 
Continuing.
1
[Detaching after fork from child process 17700]

Breakpoint 1, dowhile (v=0x5555555ffd60, c=0x5555555ffbb0) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) 
Continuing.
0
[Detaching after fork from child process 17701]

....


(gdb) br dowhile
Breakpoint 1 at 0x189e0: file sh.func.c, line 566.
(gdb) run -f x.csh
Breakpoint 1, dowhile (v=0x5555555fdf30, c=0x5555555f14e0) at sh.func.c:566
566         int again = whyles != 0 && 
(gdb) cont
Continuing.
4
[Detaching after fork from child process 17713]
3
[Detaching after fork from child process 17714]
2
[Detaching after fork from child process 17715]
1
[Detaching after fork from child process 17716]
0
[Detaching after fork from child process 17717]
-1
[Detaching after fork from child process 17719]
-2
[Detaching after fork from child process 17720]

debug (1,613 bytes)

bitstreamout

2019-04-05 12:56

reporter   ~0003233

The bug is also in tcsh-6.16.00

bitstreamout

2019-04-08 11:38

reporter   ~0003238

Looks like aliasrun() does destroy the current parse tree .... at least this patch make the test case work

tcsh-postcmd.patch (3,043 bytes)
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: .gdb_history
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: Makefile
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: atconfig
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/config and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/config
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: config.log
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: config.status
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/cygwin and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/cygwin
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: debugfiles.list
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: debuglinks.list
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: debugsourcefiles.list
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: debugsources.list
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: elfbins.list
Only in /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/: gethost
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/m4 and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/m4
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/nls and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/nls
diff -x tc.defs.c -x tcsh -x 'testsuite.*' -x '*.h' -x '*.csh' -x '*.o' -up /usr/src/werner/tcsh/tcsh-6.20.00/sh.c /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/sh.c
--- /usr/src/werner/tcsh/tcsh-6.20.00/sh.c	2017-07-19 12:29:15.512471750 +0200
+++ /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/sh.c	2019-04-08 13:35:32.462771640 +0200
@@ -2188,14 +2188,15 @@ process(int catch)
 	    stderror(ERR_OLD);
 	}
 
-	postcmd();
 	/*
 	 * Execute the parse tree From: Michael Schroeder
 	 * <mlschroe@immd4.informatik.uni-erlangen.de> was execute(t, tpgrp);
 	 */
 	execute(t, (tpgrp > 0 ? tpgrp : -1), NULL, NULL, TRUE);
 	freesyn(t);
+	setcopy(STR_, InputBuf, VAR_READWRITE | VAR_NOGLOB);
 
+	postcmd();	/* The potential aliasrun() might destroy the parse tree */
 	/*
 	 * Made it!
 	 */
@@ -2204,7 +2205,6 @@ process(int catch)
 	    (void) check_window_size(0);	/* for window systems */
 	}
 #endif /* SIG_WINDOW */
-	setcopy(STR_, InputBuf, VAR_READWRITE | VAR_NOGLOB);
     cmd_done:
 	if (cleanup_reset())
 	    cleanup_until(&paraml);
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/tests and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/tests
Common subdirectories: /usr/src/werner/tcsh/tcsh-6.20.00/win32 and /abuild/oscbuild/openSUSE_Factory/home/abuild/rpmbuild/BUILD/tcsh-6.20.00/win32
tcsh-postcmd.patch (3,043 bytes)

bitstreamout

2019-04-09 07:25

reporter   ~0003239

This one avoids breaking the testsuit

tcsh-6.20.00-postcmd.patch (1,421 bytes)
https://bugs.astron.com/view.php?id=74#c3238

Avoid trouble with e.g.

 alias postcmd false
 set counter=1
 while ($counter > )
     @ counter--
     echo $counter
 end

and similar scriptlets, maybe there is a better solution to
protect dowhile(), nevertheless this works.

--- 
 tcsh-6.20.00/sh.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- tcsh-6.20.00/sh.c	2017-07-19 12:29:15.512471750 +0200
+++ tcsh-6.20.00/sh.c	2019-04-08 13:35:32.462771640 +0200
@@ -2028,6 +2028,7 @@ process(int catch)
     getexit(osetexit);
     omark = cleanup_push_mark();
     for (;;) {
+	const struct wordent *p;
 	struct command *t;
 	int hadhist, old_pintr_disabled;
 
@@ -2178,7 +2179,9 @@ process(int catch)
 	/*
 	 * Parse the words of the input into a parse tree.
 	 */
-	t = syntax(paraml.next, &paraml, 0);
+	p = paraml.next;
+	t = syntax(p, &paraml, 0);
+
 	/*
 	 * We cannot cleanup push here, because cd /blah; echo foo
 	 * would rewind t on the chdir error, and free the rest of the command
@@ -2188,7 +2191,13 @@ process(int catch)
 	    stderror(ERR_OLD);
 	}
 
-	postcmd();
+	/*
+	 * The potential aliasrun() might destroy the parse tree,
+	 * that is that the dowhile() would be never reached again.
+	 */
+	if (srchx(p->word) != TC_WHILE)
+	    postcmd();
+
 	/*
 	 * Execute the parse tree From: Michael Schroeder
 	 * <mlschroe@immd4.informatik.uni-erlangen.de> was execute(t, tpgrp);

christos

2019-05-08 18:06

manager   ~0003245

Thanks!

Issue History

Date Modified Username Field Change
2019-03-25 09:51 bitstreamout New Issue
2019-04-05 09:16 bitstreamout File Added: debug
2019-04-05 09:16 bitstreamout Note Added: 0003232
2019-04-05 12:56 bitstreamout Note Added: 0003233
2019-04-08 11:38 bitstreamout File Added: tcsh-postcmd.patch
2019-04-08 11:38 bitstreamout Note Added: 0003238
2019-04-09 07:25 bitstreamout File Added: tcsh-6.20.00-postcmd.patch
2019-04-09 07:25 bitstreamout Note Added: 0003239
2019-05-08 18:06 christos Assigned To => christos
2019-05-08 18:06 christos Status new => assigned
2019-05-08 18:06 christos Status assigned => resolved
2019-05-08 18:06 christos Resolution open => fixed
2019-05-08 18:06 christos Fixed in Version => 6.21.00
2019-05-08 18:06 christos Note Added: 0003245