From 5cb75f0d4114f83a7cf072ff8201445ae721f8c6 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Wed, 21 Oct 2015 15:13:17 -0700 Subject: 36909: in getargs(), sanity-check the offsets for start and end of the requested words, in case of overflow --- ChangeLog | 3 +++ Src/hist.c | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22e4b9478..e40242eb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2015-10-21 Barton E. Schaefer + * 36909: Src/hist.c: in getargs(), sanity-check the offsets for + start and end of the requested words, in case of overflow + * 36871: Functions/Zle/bracketed-paste-magic: move initial call to "zle .bracketed-paste-magic" to occur earlier in the function diff --git a/Src/hist.c b/Src/hist.c index 9c42d85c9..007366a49 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2254,7 +2254,7 @@ static char * getargs(Histent elist, int arg1, int arg2) { short *words = elist->words; - int pos1, nwords = elist->nwords; + int pos1, pos2, nwords = elist->nwords; if (arg2 < arg1 || arg1 >= nwords || arg2 >= nwords) { /* remember, argN is indexed from 0, nwords is total no. of words */ @@ -2263,8 +2263,22 @@ getargs(Histent elist, int arg1, int arg2) return NULL; } + /* optimization for accessing entire history event */ + if (arg1 == 0 && arg2 == nwords - 1) + return dupstring(elist->node.nam); + pos1 = words[2*arg1]; - return dupstrpfx(elist->node.nam + pos1, words[2*arg2+1] - pos1); + pos2 = words[2*arg2+1]; + + /* a word has to be at least one character long, so if the position + * of a word is less than its index, we've overflowed our signed + * short integer word range and the recorded position is garbage. */ + if (pos1 < 0 || pos1 < arg1 || pos2 < 0 || pos2 < arg2) { + herrflush(); + zerr("history event too long, can't index requested words"); + return NULL; + } + return dupstrpfx(elist->node.nam + pos1, pos2 - pos1); } /**/ -- cgit 1.4.1