* infinite recursion in ihungetc()
@ 2015-07-22 11:45 Kamil Dudka
2015-07-22 13:38 ` Peter Stephenson
0 siblings, 1 reply; 3+ messages in thread
From: Kamil Dudka @ 2015-07-22 11:45 UTC (permalink / raw)
To: zsh-workers
Fedora Analysis Framework captured 10 crashes of zsh-5.0.8 due to infinite
recursion in ihungetc():
https://retrace.fedoraproject.org/faf/reports/717794/
The infinite recursion happens at this line:
http://repo.or.cz/w/zsh/mirror.git/blob/a0862f63:/Src/hist.c#l908
The 'hungetc' code pointer is obviously set to ihungetc() itself. We do
not have full bakctrace of the crash but shouldn't there be any condition
to actually stop the recursion when the conditions at lines 906-907 are
true and hungetc points at ihungetc()?
There is no single command that could invalidate any of the conditions
after nesting deeper into the recursion...
Kamil
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: infinite recursion in ihungetc()
2015-07-22 11:45 infinite recursion in ihungetc() Kamil Dudka
@ 2015-07-22 13:38 ` Peter Stephenson
2015-07-22 14:00 ` Kamil Dudka
0 siblings, 1 reply; 3+ messages in thread
From: Peter Stephenson @ 2015-07-22 13:38 UTC (permalink / raw)
To: zsh-workers
On Wed, 22 Jul 2015 13:45:06 +0200
Kamil Dudka <kdudka@redhat.com> wrote:
> Fedora Analysis Framework captured 10 crashes of zsh-5.0.8 due to infinite
> recursion in ihungetc():
>
> https://retrace.fedoraproject.org/faf/reports/717794/
>
> The infinite recursion happens at this line:
>
> http://repo.or.cz/w/zsh/mirror.git/blob/a0862f63:/Src/hist.c#l908
>
> The 'hungetc' code pointer is obviously set to ihungetc() itself. We do
> not have full bakctrace of the crash but shouldn't there be any condition
> to actually stop the recursion when the conditions at lines 906-907 are
> true and hungetc points at ihungetc()?
>
> There is no single command that could invalidate any of the conditions
> after nesting deeper into the recursion...
Yes, it should be straightforward to prevent, although this code isn't
particularly transparent (or new), so I don't know how you could get
there.
pws
diff --git a/Src/hist.c b/Src/hist.c
index 6725313..cf224cb 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -136,6 +136,7 @@ mod_export int hist_skip_flags;
#define HA_NOINC (1<<1) /* Don't store, curhist not incremented */
#define HA_INWORD (1<<2) /* We're inside a word, don't add
start and end markers */
+#define HA_UNGET (1<<3) /* Recursively ungetting */
/* Array of word beginnings and endings in current history line. */
@@ -904,8 +905,13 @@ ihungetc(int c)
while (!lexstop && !errflag) {
if (hptr[-1] != (char) c && stophist < 4 &&
- hptr > chline + 1 && hptr[-1] == '\n' && hptr[-2] == '\\')
- hungetc('\n'), hungetc('\\');
+ hptr > chline + 1 && hptr[-1] == '\n' && hptr[-2] == '\\' &&
+ !(histactive & HA_UNGET)) {
+ histactive |= HA_UNGET;
+ hungetc('\n');
+ hungetc('\\');
+ histactive &= ~HA_UNGET;
+ }
if (expanding) {
zlemetacs--;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: infinite recursion in ihungetc()
2015-07-22 13:38 ` Peter Stephenson
@ 2015-07-22 14:00 ` Kamil Dudka
0 siblings, 0 replies; 3+ messages in thread
From: Kamil Dudka @ 2015-07-22 14:00 UTC (permalink / raw)
To: Peter Stephenson; +Cc: zsh-workers
On Wednesday 22 July 2015 14:38:03 Peter Stephenson wrote:
> Yes, it should be straightforward to prevent, although this code isn't
> particularly transparent (or new), so I don't know how you could get
> there.
>
> pws
I do not know it either because these crash reports are anonymous. I will
just apply your patch to fix it and let you know if we get any feedback.
Thanks for the patch!
Kamil
> diff --git a/Src/hist.c b/Src/hist.c
> index 6725313..cf224cb 100644
> --- a/Src/hist.c
> +++ b/Src/hist.c
> @@ -136,6 +136,7 @@ mod_export int hist_skip_flags;
> #define HA_NOINC (1<<1) /* Don't store, curhist not incremented */
> #define HA_INWORD (1<<2) /* We're inside a word, don't add
> start and end markers */
> +#define HA_UNGET (1<<3) /* Recursively ungetting */
>
> /* Array of word beginnings and endings in current history line. */
>
> @@ -904,8 +905,13 @@ ihungetc(int c)
>
> while (!lexstop && !errflag) {
> if (hptr[-1] != (char) c && stophist < 4 &&
> - hptr > chline + 1 && hptr[-1] == '\n' && hptr[-2] == '\\')
> - hungetc('\n'), hungetc('\\');
> + hptr > chline + 1 && hptr[-1] == '\n' && hptr[-2] == '\\' &&
> + !(histactive & HA_UNGET)) {
> + histactive |= HA_UNGET;
> + hungetc('\n');
> + hungetc('\\');
> + histactive &= ~HA_UNGET;
> + }
>
> if (expanding) {
> zlemetacs--;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-07-22 14:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-22 11:45 infinite recursion in ihungetc() Kamil Dudka
2015-07-22 13:38 ` Peter Stephenson
2015-07-22 14:00 ` Kamil Dudka
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).