about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2021-11-28 20:49:30 +0100
committerOliver Kiddle <opk@zsh.org>2021-11-28 20:49:30 +0100
commit78958c08bfdb37d2eafaf14a33b93229b1fa9e31 (patch)
tree7dbb26574f0a738ad7920fd1cc3e0b8e134b965d
parent5fe498124d6469fadded7b9ad9eb64649b93f2de (diff)
downloadzsh-78958c08bfdb37d2eafaf14a33b93229b1fa9e31.tar.gz
zsh-78958c08bfdb37d2eafaf14a33b93229b1fa9e31.tar.xz
zsh-78958c08bfdb37d2eafaf14a33b93229b1fa9e31.zip
49601: don't create ambiguous history file entries for lines ending with a backslash
-rw-r--r--ChangeLog7
-rw-r--r--Src/hist.c19
-rw-r--r--Test/W01history.ztst22
3 files changed, 39 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 843ca23d6..a05322d0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
diff --git a/Src/hist.c b/Src/hist.c
index ea727d1f8..d4557d424 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -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;
 	}
diff --git a/Test/W01history.ztst b/Test/W01history.ztst
index 0b2f60d1e..1d3f3cf6f 100644
--- a/Test/W01history.ztst
+++ b/Test/W01history.ztst
@@ -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