49601: don't create ambiguous history file entries for lines ending with a backslash

This commit is contained in:
Oliver Kiddle 2021-11-28 20:49:30 +01:00
parent 5fe498124d
commit 78958c08bf
3 changed files with 39 additions and 9 deletions

View File

@ -1,3 +1,8 @@
2021-11-28 Oliver Kiddle <opk@zsh.org>
* 49601: Src/hist.c, Test/W01history.ztst: don't create
ambiguous history file entries for lines ending with a backslash
2021-11-26 Paul Seyfert <Paul.Seyfert@sevensense.ch>
* github #83: Completion/Unix/Command/_git: _git-push,
@ -93,7 +98,7 @@
Completion/Base/Core/_description, Completion/Base/Core/_message,
Test/V13zformat.ztst: Add zformat -F option, similar to -f but
ternary expressions check for existence instead of doing math
evaluation. Make use it with the format style.
evaluation. Make use of it with the format style.
2021-11-07 Oliver Kiddle <opk@zsh.org>

View File

@ -2619,12 +2619,19 @@ readhistline(int start, char **bufp, int *bufsiz, FILE *in, int *readbytes)
}
}
else {
int spc;
buf[len - 1] = '\0';
if (len > 1 && buf[len - 2] == '\\') {
buf[--len - 1] = '\n';
if (!feof(in))
return readhistline(len, bufp, bufsiz, in, readbytes);
}
spc = len - 2;
while (spc >= 0 && buf[spc] == ' ')
spc--;
if (spc != len - 2 && buf[spc] == '\\')
buf[--len - 1] = '\0';
}
return len;
}
@ -2988,7 +2995,7 @@ savehistfile(char *fn, int err, int writeflags)
ret = 0;
for (; he && he->histnum <= xcurhist; he = down_histent(he)) {
int count_backslashes = 0;
int end_backslashes = 0;
if ((writeflags & HFILE_SKIPDUPS && he->node.flags & HIST_DUP)
|| (writeflags & HFILE_SKIPFOREIGN && he->node.flags & HIST_FOREIGN)
@ -3021,18 +3028,14 @@ savehistfile(char *fn, int err, int writeflags)
if (*t == '\n')
if ((ret = fputc('\\', out)) < 0)
break;
if (*t == '\\')
count_backslashes++;
else
count_backslashes = 0;
end_backslashes = (*t == '\\' || (end_backslashes && *t == ' '));
if ((ret = fputc(*t, out)) < 0)
break;
}
if (ret < 0)
break;
if (count_backslashes && (count_backslashes % 2 == 0))
if ((ret = fputc(' ', out)) < 0)
break;
if (end_backslashes)
ret = fputc(' ', out);
if (ret < 0 || (ret = fputc('\n', out)) < 0)
break;
}

View File

@ -88,3 +88,25 @@ F:Check that a history bug introduced by workers/34160 is working again.
0:Modifier :P
>/my/path/for/testing
>/my/path/for/testing
$ZTST_testdir/../Src/zsh -fgis <<<'
SAVEHIST=7
print -rs "one\\"
print -rs "two\\\\"
print -rs "three\\\\\\"
print -rs "four\\\\\\\\"
print -rs "five\\\\\\\\\\"
print -s "while false\ndo\ntrue\\\\\n && break\ndone"
print -s "echo one\\\\\ntwo"
fc -W hist
fc -p -R hist
fc -l
rm hist' 2>/dev/null
0:Lines ending in backslash saved and restored to history
> 1 one\
> 2 two\\
> 3 three\\\
> 4 four\\\\
> 5 five\\\\\
> 6 while false\ndo\ntrue\\n && break\ndone
> 7 echo one\\ntwo