From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9799 invoked by alias); 11 Oct 2014 03:23:36 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 33429 Received: (qmail 9697 invoked from network); 11 Oct 2014 03:23:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <141010202340.ZM32229@torch.brasslantern.com> Date: Fri, 10 Oct 2014 20:23:40 -0700 In-reply-to: <20141010104744.GM5405@sym.noone.org> Comments: In reply to Axel Beckert "Crash after history/fc -p if history size is set to 0 or non-numerical value" (Oct 10, 12:47pm) References: <20141010104744.GM5405@sym.noone.org> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: PATCH Re: Crash after history/fc -p if history size is set to 0 or non-numerical value MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Oct 10, 12:47pm, Axel Beckert wrote: } } ~ -> zsh -f } kiva6% fc -p a b } kiva6% c } [1] 4284 segmentation fault (core dumped) zsh -f This rejects non-integer values but also handles a zero value. The hunk in putoldhistentryontop() is just extra defensive programming, the small change in prepnexthistent() is the real repair. diff --git a/Src/builtin.c b/Src/builtin.c index 4a10c7d..5b711ed 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1363,10 +1363,19 @@ bin_fc(char *nam, char **argv, Options ops, int func) if (*argv) { hf = *argv++; if (*argv) { - hs = zstrtol(*argv++, NULL, 10); - if (*argv) - shs = zstrtol(*argv++, NULL, 10); - else + char *check; + hs = zstrtol(*argv++, &check, 10); + if (*check) { + zwarnnam("fc", "HISTSIZE must be an integer"); + return 1; + } + if (*argv) { + shs = zstrtol(*argv++, &check, 10); + if (*check) { + zwarnnam("fc", "SAVEHIST must be an integer"); + return 1; + } + } else shs = hs; if (*argv) { zwarnnam("fc", "too many arguments"); diff --git a/Src/hist.c b/Src/hist.c index 4660fd0..0831756 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1110,8 +1110,11 @@ static void putoldhistentryontop(short keep_going) { static Histent next = NULL; - Histent he = keep_going? next : hist_ring->down; - next = he->down; + Histent he = (keep_going || !hist_ring) ? next : hist_ring->down; + if (he) + next = he->down; + else + return; if (isset(HISTEXPIREDUPSFIRST) && !(he->node.flags & HIST_DUP)) { static zlong max_unique_ct = 0; if (!keep_going) @@ -1151,7 +1154,7 @@ prepnexthistent(void) freehistnode(&hist_ring->node); } - if (histlinect < histsiz) { + if (histlinect < histsiz || !hist_ring) { he = (Histent)zshcalloc(sizeof *he); if (!hist_ring) hist_ring = he->up = he->down = he;