Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: zle: various issues
historysearchforward advanced zlecs instead of histpos
(historysearchbackward already correctly uses CCRIGHTPOS(histpos)
ST is actually 0x9c per ctlseqs.txt
ESC \
String Terminator (ST is 0x9c).
fix plenty of indexing confusion with prompt_markers(), it was never
returning pre because markers did not include it. constants were
compared against the wrong variable, or using the wrong hardcoded index
(and those indices also changed now that pre is in markers).
in bracketedstring, the imeta(next) branch writes two bytes to pbuf,
make sure they both fit.
only reallocate once in sizeline, and correct the comment for
stringaszleline, though I don't think anyone will do that.
putreplaceselection used a stale buffer in the following scenario:
% blah
set region to bl with cursor on a, hit ctrl-k, then invoke
put-replace-selection via alt-x or bind it in advance.
==10588== Invalid read of size 2
==10588== by 0x6588FAA: pastebuf (zle_misc.c:597)
==10588== by 0x65895A6: putreplaceselection (zle_misc.c:720)
==10588== Address 0x6219550 is 0 bytes inside a block of size 16 free'd
==10588== at 0x483C17B: free (vgpreload_memcheck-amd64-linux.so)
==10588== by 0x65A347A: cuttext (zle_utils.c:1023)
==10588== Block was alloc'd at
==10588== at 0x483E82F: realloc (vgpreload_memcheck-amd64-linux.so)
==10588== by 0x65A34E8: cuttext (zle_utils.c:1028)
also set clear so the stringaszleline allocation is freed in the same
function, and fix the same leak in viputbefore and viputafter.
fix out of bounds access in vimatchbracket
==11986== Invalid read of size 4
==11986== at 0x658D14C: vimatchbracket (zle_move.c:645)
fix out of bounds access in backwardmetafiedchar, this one won't cause a
valgrind warning because the memory is owned by us.
fix two separate leaks (impressive) when assigning to $registers special zle parameter
==16615== 2,799,972 bytes in 99,999 blocks are definitely lost in loss record 631 of 631
==16615== at 0x48397B5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==16615== by 0x473836: zalloc (mem.c:966)
==16615== by 0x65A1EEC: stringaszleline (zle_utils.c:440)
==16615== by 0x658EF17: set_register (zle_params.c:775)
==16615== 599,988 bytes in 99,998 blocks are definitely lost in loss record 630 of 631
==16615== at 0x48397B5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==16615== by 0x473836: zalloc (mem.c:966)
==16615== by 0x4AA101: ztrdup (string.c:68)
==16615== by 0x435536: addvars (exec.c:2604)
don't crash on 'bindkey x foo; zle -l foo'
==21910== Process terminating with default action of signal 11 (SIGSEGV)
==21910== Access not within mapped region at address 0x0
==21910== at 0x6597303: bin_zle_list (zle_thingy.c:406)
==21910== by 0x6597229: bin_zle (zle_thingy.c:388)
restore keymap and zmod when erroring out of bin_zle_call
inststrlen used the wrong len to advance zlecs which would cause it to
advance way past the end of zleline. fortunately this function is never
called with zlemetaline == NULL.
fix expand-cmd-path to not just move the cursor an arbitrary
amount forward, and convert the indices from zlemetaline to zleline.
bangq in magicspace could be used after zleline was realloc()d,
calculate the offset before calling selfinsert()
the memo field wasn't always freed for region highlights
vi-indent was skipping the last line for 4+ line ranges
vi-unindent buffer overrun
==3900== Conditional jump or move depends on uninitialised value(s)
==3900== at 0x65A3CE6: findeol (zle_utils.c:1180)
==3900== by 0x65A6E01: viunindent (zle_vi.c:880)
break the loop on eof in vi-caps-lock-panic, though we do exit anyway
when the terminal closes
off by one in condition in vi-backward-word-end, this only prevented us
moving to the start of the buffer if we were on the second character
exactly.
seq in cursor_form() was one byte too small to fit the nul terminator:
zsh% zle_cursorform=( edit:steady,color=\#abcdef )
Breakpoint 1, cursor_form () at termquery.c:987
987 if (s - seq)
(gdb) p s - seq
$1 = 31
fix negation of h-3 in setmstatus. this was very noticable in interactive
menu selection if you typed a long string. the entire string would be
replaced by three dots instead of just the start of it.
---
Src/Zle/complist.c | 2 +-
Src/Zle/termquery.c | 4 ++--
Src/Zle/zle_hist.c | 2 +-
Src/Zle/zle_keymap.c | 6 +++---
Src/Zle/zle_main.c | 11 ++++++-----
Src/Zle/zle_misc.c | 19 ++++++++++++++++---
Src/Zle/zle_move.c | 4 +++-
Src/Zle/zle_params.c | 20 ++++++++++++++------
Src/Zle/zle_refresh.c | 12 ++++++------
Src/Zle/zle_thingy.c | 27 +++++++++------------------
Src/Zle/zle_tricky.c | 30 +++++++++++++++++++++++-------
Src/Zle/zle_utils.c | 30 ++++++++++++++++++------------
Src/Zle/zle_vi.c | 12 ++++++++----
Src/Zle/zle_word.c | 2 +-
14 files changed, 111 insertions(+), 70 deletions(-)
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 9c26b6f994..21d0d6e60e 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -2244,7 +2244,7 @@ setmstatus(char *status, char *sline, int sll, int scs,
strcpy(status, "interactive: ");
if (pl > h - 3) {
strcat(status, "...");
- strcat(status, p + pl - h - 3);
+ strcat(status, p + pl - h + 3);
} else
strcat(status, p);
diff --git a/Src/Zle/termquery.c b/Src/Zle/termquery.c
index 9a330a4b82..6b545fe1aa 100644
--- a/Src/Zle/termquery.c
+++ b/Src/Zle/termquery.c
@@ -755,7 +755,7 @@ prompt_markers(void)
static const char PR[] = "\033]133;P;k=i\033\\"; /* primary (PS1) */
static const char SE[] = "\033]133;P;k=s\033\\"; /* secondary (PS2) */
static const char RI[] = "\033]133;P;k=r\033\\"; /* right (RPS1,2) */
- static const char *markers[] = { PR, SE, RI };
+ static const char *markers[] = { pre, PR, SE, RI };
static const char *nomark[] = { NULL, NULL, NULL, NULL };
if (!extension_enabled("integration", "prompt", 11, 1))
@@ -934,7 +934,7 @@ free_cursor_forms(void)
void
cursor_form(void)
{
- char seq[31];
+ char seq[32];
char *s = seq;
unsigned int want, changed;
static unsigned int state = CURF_DEFAULT;
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index af450fb438..84143168da 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -539,7 +539,7 @@ historysearchforward(char **args)
;
if (histpos < zlell)
histpos++;
- CCRIGHT();
+ CCRIGHTPOS(histpos);
srch_str = zlelineasstring(zleline, histpos, 0, NULL, NULL, 0);
}
free(line);
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index ea80f9e3cc..e26895a2be 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -989,7 +989,7 @@ bin_bindkey_meta(char *name, char *kmname, Keymap km, UNUSED(char **argv), UNUSE
/* Change key bindings. func can be: *
* 'r' bind sequences to undefined-key *
- * 's' bind sequneces to specified send-strings *
+ * 's' bind sequences to specified send-strings *
* 0 bind sequences to specified functions *
* If the -R option is used, bind to key ranges *
* instead of single key sequences. */
@@ -1675,8 +1675,8 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
if (keybuf[keybuflen - 1] == '\007' || /* BEL sometimes used */
(keybuf[keybuflen - 2] == '\033' &&
keybuf[keybuflen - 1] == '\\') ||
- (keybuf[keybuflen - 2] == Meta && /* ST can be 0x9b */
- (unsigned char) keybuf[keybuflen - 1] == (0x9b ^ 32)))
+ (keybuf[keybuflen - 2] == Meta && /* ST can be 0x9c */
+ (unsigned char) keybuf[keybuflen - 1] == (0x9c ^ 32)))
{
keybuflen = oscdcs - 2; /* discard */
timeout = oscdcs = 0;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index aee62a505d..37d587d023 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1272,10 +1272,10 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
raw_lp = lp;
txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0;
lpromptbuf = promptexpand(lp ? *lp : NULL, 1,
- markers[flags == ZLCON_LINE_CONT ? 2 : 1], NULL, NULL);
+ markers[context == ZLCON_LINE_CONT ? 2 : 1], NULL, NULL);
pmpt_attr = txtcurrentattrs;
raw_rp = rp;
- rpromptbuf = promptexpand(rp ? *rp : NULL, 1, markers[2], NULL, NULL);
+ rpromptbuf = promptexpand(rp ? *rp : NULL, 1, markers[3], NULL, NULL);
rpmpt_attr = txtcurrentattrs;
prompt_attr = mixattrs(pmpt_attr, pmpt_attr & TXT_ATTR_ALL, rpmpt_attr);
free_prepostdisplay();
@@ -2022,7 +2022,8 @@ reexpandprompt(void)
looping = reexpanding;
txtcurrentattrs = txtpendingattrs = txtunknownattrs = 0;
- new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, markers[0], NULL, NULL);
+ new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1,
+ markers[zlecontext == ZLCON_LINE_CONT ? 2 : 1], NULL, NULL);
pmpt_attr = txtcurrentattrs;
free(lpromptbuf);
lpromptbuf = new_lprompt;
@@ -2030,7 +2031,7 @@ reexpandprompt(void)
if (looping != reexpanding)
continue;
- new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, markers[2], NULL, NULL);
+ new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, markers[3], NULL, NULL);
rpmpt_attr = txtcurrentattrs;
prompt_attr = mixattrs(pmpt_attr, pmpt_attr & TXT_ATTR_ALL, rpmpt_attr);
free(rpromptbuf);
@@ -2051,7 +2052,7 @@ resetprompt(UNUSED(char **args))
return redisplay(NULL);
}
-/* same bug called from outside zle */
+/* same but called from outside zle */
/**/
static void
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 53345f2a29..6bf3538932 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -76,7 +76,7 @@ doinsert(ZLE_STRING_T zstr, int len)
count = len * m;
#endif
/*
- * Ensure we replace a complete combining characterfor each
+ * Ensure we replace a complete combining character for each
* character we overwrite. Switch to inserting at first newline.
*/
for (i = count; pos < zlell && zleline[pos] != ZWC('\n') && i--; ) {
@@ -626,6 +626,7 @@ viputbefore(UNUSED(char **args))
kct = -1;
yankcs = zlecs;
pastebuf(&kbuf, n, 0);
+ free(kbuf.buf);
return 0;
} else if (zmod.flags & MOD_VIBUF)
kctbuf = &vibuf[zmod.vibuf];
@@ -662,6 +663,7 @@ viputafter(UNUSED(char **args))
kct = -1;
yankcs = zlecs;
pastebuf(&kbuf, n, 1);
+ free(kbuf.buf);
return 0;
} else if (zmod.flags & MOD_VIBUF)
kctbuf = &vibuf[zmod.vibuf];
@@ -684,8 +686,10 @@ putreplaceselection(UNUSED(char **args))
Cutbuffer putbuf;
int clear = 0;
int pos = 2;
+ int isvibuf;
startvichange(-1);
+ isvibuf = zmod.flags & MOD_VIBUF;
if (n < 0 || zmod.flags & MOD_NULL)
return 1;
if (zmod.flags & MOD_OSSEL) {
@@ -696,8 +700,9 @@ putreplaceselection(UNUSED(char **args))
prevbuf.buf = stringaszleline(pbuf, 0, &x, NULL, NULL);
prevbuf.len = x;
prevbuf.flags = 0;
+ clear = 1; /* stringaszleline returns permanent memory */
} else {
- putbuf = (zmod.flags & MOD_VIBUF) ? &vibuf[zmod.vibuf] : &cutbuf;
+ putbuf = isvibuf ? &vibuf[zmod.vibuf] : &cutbuf;
if (!putbuf->buf)
return 1;
memcpy(&prevbuf, putbuf, sizeof(prevbuf));
@@ -706,6 +711,14 @@ putreplaceselection(UNUSED(char **args))
if (zmod.vibuf == 35) {
putbuf->buf = 0;
clear = 1;
+ } else if (!isvibuf) {
+ /* when putbuf is pointing at cutbuf, we can't clear putbuf->buf
+ * because that's where we want to put the stuff, but valgrind will be
+ * quite sad if killregion reallocs it, so I think we need to copy it */
+ ZLE_STRING_T newbuf = (ZLE_STRING_T)zalloc(prevbuf.len * ZLE_CHAR_SIZE);
+ ZS_memcpy(newbuf, prevbuf.buf, prevbuf.len);
+ prevbuf.buf = newbuf;
+ clear = 1;
}
}
@@ -791,7 +804,7 @@ bracketedstring(void)
int next, timeout;
while (endesc[endpos]) {
- if (current + 1 >= psize)
+ if (current + 2 >= psize)
pbuf = zrealloc(pbuf, psize *= 2);
if ((next = getbyte(1L, &timeout, 1)) == EOF)
break;
diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
index 3bafff3f10..7f46786836 100644
--- a/Src/Zle/zle_move.c
+++ b/Src/Zle/zle_move.c
@@ -274,7 +274,7 @@ backwardmetafiedchar(char *start, char *endptr, convchar_t *retchr)
*/
#endif
if (endptr > start) {
- if (endptr > start - 1 && endptr[-2] == Meta)
+ if (endptr > start + 1 && endptr[-2] == Meta)
{
if (retchr)
*retchr = (convchar_t)(endptr[-1] ^ 32);
@@ -642,6 +642,8 @@ vimatchbracket(UNUSED(char **args))
DECCS();
else
INCCS();
+ if (zlecs < 0 && zlecs >= zlell)
+ break;
if (zleline[zlecs] == oth)
ct--;
else if (zleline[zlecs] == me)
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 31ba3bd561..6ac7d4f0af 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -753,6 +753,14 @@ unset_killring(Param pm, int exp)
/**/
static void
set_register(Param pm, char *value)
+{
+ set_register_buf(pm, value);
+ zsfree(value);
+}
+
+/**/
+static void
+set_register_buf(Param pm, char *value)
{
int n = 0;
int offset = -1;
@@ -771,8 +779,12 @@ set_register(Param pm, char *value)
}
vbuf = &vibuf[*pm->node.nam - offset];
+ if (vbuf->buf)
+ free(vbuf->buf);
if (*value)
vbuf->buf = stringaszleline(value, 0, &n, NULL, NULL);
+ else
+ vbuf->buf = NULL;
vbuf->len = n;
}
@@ -780,7 +792,7 @@ set_register(Param pm, char *value)
static void
unset_register(Param pm, UNUSED(int exp))
{
- set_register(pm, "");
+ set_register_buf(pm, "");
}
/**/
@@ -850,7 +862,7 @@ set_registers(Param pm, HashTable ht)
v.arr = NULL;
v.pm = (Param) hn;
- set_register(v.pm, getstrvalue(&v));
+ set_register_buf(v.pm, getstrvalue(&v));
}
if (ht != pm->u.hash)
deleteparamtable(ht);
@@ -948,20 +960,16 @@ get_context(UNUSED(Param pm))
switch (zlecontext) {
case ZLCON_LINE_CONT:
return "cont";
- break;
case ZLCON_SELECT:
return "select";
- break;
case ZLCON_VARED:
return "vared";
- break;
case ZLCON_LINE_START:
default:
return "start";
- break;
}
}
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 255c701f24..d5309f77c2 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -40,7 +40,7 @@
* nmw_ind is the next free element, i.e. nmwbuf[nmw_ind] will be the next
* element to be written (we never insert into omwbuf). We initialise
* nmw_ind to 1 to avoid the index stored in the character looking like a
- * NULL. This wastees a word but it's safer than messing with pointers.
+ * NULL. This wastes a word but it's safer than messing with pointers.
*
* The layout of the buffer is as a string of entries that consist of multiple
* elements of the allocated array with no boundary (the code keeps track of
@@ -492,12 +492,12 @@ set_region_highlight(UNUSED(Param pm), char **aval)
struct region_highlight *rhp;
len = aval ? arrlen(aval) : 0;
+ free_region_highlights_memos();
if (n_region_highlights != len + N_SPECIAL_HIGHLIGHTS) {
/* no null termination, but include special highlighting at start */
int newsize = len + N_SPECIAL_HIGHLIGHTS;
int diffsize = newsize - n_region_highlights;
- free_region_highlights_memos();
region_highlights = (struct region_highlight *)
zrealloc(region_highlights,
sizeof(struct region_highlight) * newsize);
@@ -688,7 +688,7 @@ static int more_start, /* more text before start of screen? */
static int
omw_size, /* allocated size of omwbuf */
nmw_size, /* allocated size of nmwbuf */
- nmw_ind; /* next insert point in nmw_ind */
+ nmw_ind; /* next insert point in nmwbuf */
#endif
/*
@@ -1491,7 +1491,7 @@ zrefresh(void)
*/
snextline(&rpms);
}
- zfree(outputline, outsz);
+ zfree(outputline, (outsz+2) * ZLE_CHAR_SIZE);
free(statusdup);
}
*rpms.s = zr_zr;
@@ -1556,7 +1556,7 @@ zrefresh(void)
* Ensure we don't start overwriting in the middle of a wide
* character.
*/
- while(rpms.sen > nbuf[rpms.tosln - 1] && rpms.sen->chr == WEOF) {
+ while(rpms.sen > nbuf[rpms.tosln] && rpms.sen->chr == WEOF) {
extra_ellipsis++;
rpms.sen--;
}
@@ -2452,7 +2452,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
for (t0 = 0; t0 < tmpll; t0++) {
unsigned ireg;
- zattr base_attr = mixattrs(default_attr, default_attr, prompt_attr);
+ zattr base_attr = mixattrs(default_attr, default_mask, prompt_attr);
zattr all_attr;
struct region_highlight *rhp;
/*
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index f71435b01d..94e67f8384 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -402,7 +402,7 @@ bin_zle_list(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
for (; *args && !ret; args++) {
HashNode hn = thingytab->getnode2(thingytab, *args);
- if (!(t = (Thingy) hn) ||
+ if (!(t = (Thingy) hn) || !t->widget ||
(!OPT_ISSET(ops,'a') && (t->widget->flags & WIDGET_INT)))
ret = 1;
else if (OPT_ISSET(ops,'L')) {
@@ -704,7 +704,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
{
Thingy t;
struct modifier modsave = zmod;
- int ret, saveflag = 0, setbindk = 0, setlbindk = 0, remetafy;
+ int ret = 1, saveflag = 0, setbindk = 0, setlbindk = 0, remetafy;
char *wname = *args++, *keymap_restore = NULL, *keymap_tmp;
if (!wname)
@@ -739,9 +739,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
flag = args[0][1] ? args[0]+1 : args[1];
if (flag == NULL || strcmp(flag, "nolast")) {
zwarnnam(name, "%s", "'nolast' expected after -f");
- if (remetafy)
- metafy_line();
- return 1;
+ goto cleanup_zle_call;
}
if (!args[0][1])
*++args = skip_this_arg;
@@ -752,9 +750,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
num = args[0][1] ? args[0]+1 : args[1];
if (!num) {
zwarnnam(name, "number expected after -%c", **args);
- if (remetafy)
- metafy_line();
- return 1;
+ goto cleanup_zle_call;
}
if (!args[0][1])
*++args = skip_this_arg;
@@ -771,17 +767,13 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
keymap_tmp = args[0][1] ? args[0]+1 : args[1];
if (!keymap_tmp) {
zwarnnam(name, "keymap expected after -%c", **args);
- if (remetafy)
- metafy_line();
- return 1;
+ goto cleanup_zle_call;
}
if (!args[0][1])
*++args = skip_this_arg;
keymap_restore = dupstring(curkeymapname);
if (selectkeymap(keymap_tmp, 0)) {
- if (remetafy)
- metafy_line();
- return 1;
+ goto cleanup_zle_call;
}
break;
case 'w':
@@ -789,9 +781,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
break;
default:
zwarnnam(name, "unknown option: %s", *args);
- if (remetafy)
- metafy_line();
- return 1;
+ goto cleanup_zle_call;
}
}
args++;
@@ -805,6 +795,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
setlbindk |= t->widget && (t->widget->flags & ZLE_NOLAST) == ZLE_NOLAST;
ret = execzlefunc(t, args, setbindk, setlbindk);
unrefthingy(t);
+cleanup_zle_call:
if (saveflag)
zmod = modsave;
if (keymap_restore)
@@ -1014,7 +1005,7 @@ bin_zle_transform(char *name, char **args, Options ops, UNUSED(char func))
}
/*******************/
-/* initialiasation */
+/* initialisation */
/*******************/
/**/
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 8f32c68e32..77fa5fbe43 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -2251,7 +2251,7 @@ inststrlen(char *str, int move, int len)
free(zlestr);
zsfree(instr);
if (move)
- zlecs += len;
+ zlecs += zlelen;
}
return len;
}
@@ -2884,6 +2884,7 @@ magicspace(char **args)
ZLE_STRING_T bangq;
ZLE_CHAR_T zlebangchar[1];
int ret;
+ int bangq_off;
#ifdef MULTIBYTE_SUPPORT
mbstate_t mbs;
#endif
@@ -2910,8 +2911,12 @@ magicspace(char **args)
break;
}
+ /* selfinsert can call spaceinline which can realloc zleline, we can't
+ * use the bangq pointer after that */
+ bangq_off = (bangq < zleline + zlell) ? (int)(bangq - zleline) : -1;
+
if (!(ret = selfinsert(args)) &&
- (!bangq || bangq + 2 > zleline + zlecs))
+ (bangq_off < 0 || bangq_off + 2 > zlecs))
doexpandhist();
return ret;
}
@@ -2929,7 +2934,7 @@ static int cmdwb, cmdwe;
/**/
static char *
-getcurcmd(void)
+getcurcmd(int trackpos)
{
int curlincmd;
char *s = NULL;
@@ -2957,6 +2962,17 @@ getcurcmd(void)
strinend();
inpop();
errflag &= ~ERRFLAG_ERROR;
+ if (s && trackpos) {
+ /* cmdwb and cmdwe are indices in zlemetaline, but we need indices
+ * into zleline, so do a little trick: use cmdwe as the length and
+ * cmdwb as the 'cursor position', this gives us both conversions
+ * in a single call to stringaszleline */
+ char *prefix = zalloc(cmdwe + 1);
+ memcpy(prefix, zlemetaline, cmdwe);
+ prefix[cmdwe] = '\0';
+ free(stringaszleline(prefix, cmdwb, &cmdwe, NULL, &cmdwb));
+ free(prefix);
+ }
unmetafy_line();
zcontext_restore();
@@ -2974,7 +2990,7 @@ processcmd(UNUSED(char **args))
int m = zmult, na = noaliases;
noaliases = 1;
- s = getcurcmd();
+ s = getcurcmd(0);
noaliases = na;
if (!s)
return 1;
@@ -3005,7 +3021,7 @@ expandcmdpath(UNUSED(char **args))
ZLE_STRING_T zlestr;
noaliases = 1;
- s = getcurcmd();
+ s = getcurcmd(1);
noaliases = na;
if (!s)
return 1;
@@ -3026,8 +3042,8 @@ expandcmdpath(UNUSED(char **args))
ZS_strncpy(zleline + zlecs, zlestr, strll);
free(zlestr);
zlecs = oldcs;
- if (zlecs >= cmdwe - 1)
- zlecs += cmdwe - cmdwb + strlen(str);
+ if (zlecs >= cmdwb)
+ zlecs += strll - (cmdwe - cmdwb);
if (zlecs > zlell)
zlecs = zlell;
return 0;
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 3d682ef2ff..4c60a5bb78 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -68,21 +68,24 @@ sizeline(int sz)
{
int cursz = (zlemetaline != NULL) ? metalinesz : linesz;
+ if (cursz >= sz)
+ return;
+
while (sz > cursz) {
if (cursz < 256)
cursz = 256;
else
cursz *= 4;
+ }
- if (zlemetaline != NULL) {
- /* One spare character for the NULL */
- zlemetaline = realloc(zlemetaline, cursz + 1);
- } else {
- /* One spare character for the NULL, one for the newline */
- zleline =
- (ZLE_STRING_T)realloc(zleline,
- (cursz + 2) * ZLE_CHAR_SIZE);
- }
+ if (zlemetaline != NULL) {
+ /* One spare character for the NULL */
+ zlemetaline = realloc(zlemetaline, cursz + 1);
+ } else {
+ /* One spare character for the NULL, one for the newline */
+ zleline =
+ (ZLE_STRING_T)realloc(zleline,
+ (cursz + 2) * ZLE_CHAR_SIZE);
}
if (zlemetaline != NULL)
@@ -367,7 +370,8 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outllp,
*
* Memory for the returned string is permanently allocated. *outsz may
* be longer than the *outll returned. Hence it should be freed with
- * zfree(outstr, *outsz) or free(outstr), not zfree(outstr, *outll).
+ * zfree(outstr, (*outsz + 2) * ZLE_CHAR_SIZE) or free(outstr),
+ * not zfree(outstr, *outll).
*/
/**/
@@ -572,6 +576,7 @@ free_region_highlights_memos(void)
rhp < region_highlights + n_region_highlights;
rhp++) {
zfree((char*) rhp->memo, 0);
+ rhp->memo = NULL;
}
}
@@ -701,8 +706,8 @@ zle_restore_positions(void)
oldrhp;
nreg++, oldrhp = oldrhp->next)
;
+ free_region_highlights_memos();
if (nreg + N_SPECIAL_HIGHLIGHTS != n_region_highlights) {
- free_region_highlights_memos();
n_region_highlights = nreg + N_SPECIAL_HIGHLIGHTS;
region_highlights = (struct region_highlight *)
zrealloc(region_highlights,
@@ -754,6 +759,7 @@ zle_free_positions(void)
oldrhp = oldpos->regions;
while (oldrhp) {
struct zle_region *nextrhp = oldrhp->next;
+ zsfree((char *)oldrhp->memo);
zfree(oldrhp, sizeof(*oldrhp));
oldrhp = nextrhp;
}
@@ -1108,7 +1114,7 @@ foredel(int ct, int flags)
if (flags & CUT_RAW) {
if (zlemetaline != NULL) {
shiftchars(zlemetacs, ct);
- } else if (flags & CUT_RAW) {
+ } else {
shiftchars(zlecs, ct);
CCRIGHT();
}
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 58115beb97..783b49fb26 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -361,7 +361,7 @@ viinsert(UNUSED(char **args))
/*
* Go to vi insert mode when we first start the line editor.
- * Iniialises some other stuff.
+ * Initialises some other stuff.
*/
/**/
@@ -837,11 +837,12 @@ viindent(UNUSED(char **args))
}
oldcs = zlecs;
/* add a tab to the beginning of each line within range */
- while (zlecs <= c2 + 1) {
+ while (zlecs <= c2) {
if (zleline[zlecs] == '\n') { /* leave blank lines alone */
++zlecs;
} else {
spaceinline(1);
+ c2++;
zleline[zlecs] = '\t';
zlecs = findeol() + 1;
}
@@ -874,8 +875,10 @@ viunindent(UNUSED(char **args))
oldcs = zlecs;
/* remove a tab from the beginning of each line within range */
while (zlecs < c2) {
- if (zleline[zlecs] == '\t')
+ if (zleline[zlecs] == '\t') {
foredel(1, 0);
+ c2--;
+ }
zlecs = findeol() + 1;
}
/* go back to the first line of the range */
@@ -1002,11 +1005,12 @@ viswapcase(UNUSED(char **args))
int
vicapslockpanic(UNUSED(char **args))
{
+ ZLE_INT_T ch;
clearlist = 1;
zbeep();
statusline = "press a lowercase key to continue";
zrefresh();
- while (!ZC_ilower(getfullchar(0)));
+ while (!ZC_ilower(ch = getfullchar(0)) && ch != ZLEEOF);
statusline = NULL;
return 0;
}
diff --git a/Src/Zle/zle_word.c b/Src/Zle/zle_word.c
index 89959b20c9..575bb628a1 100644
--- a/Src/Zle/zle_word.c
+++ b/Src/Zle/zle_word.c
@@ -356,7 +356,7 @@ vibackwardwordend(char **args)
zmult = n;
return ret;
}
- while (n-- && zlecs > 1) {
+ while (n-- && zlecs) {
int cc = wordclass(zleline[zlecs]);
DECCS();
while (zlecs) {
--
2.38.1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author