about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@zsh.org>2024-03-02 09:22:43 -0800
committerBart Schaefer <schaefer@zsh.org>2024-03-02 09:22:43 -0800
commit4fb96cc639f8f04a84dd488e61caacdecf11d65e (patch)
tree27bcd1923b20e94adf064adf428e6fc3deab2cc1
parent13f73d84d3a69085df148e7cfe03ed6448a1238b (diff)
downloadzsh-4fb96cc639f8f04a84dd488e61caacdecf11d65e.tar.gz
zsh-4fb96cc639f8f04a84dd488e61caacdecf11d65e.tar.xz
zsh-4fb96cc639f8f04a84dd488e61caacdecf11d65e.zip
52612: %l replacment of zwarning() does literal string output
-rw-r--r--ChangeLog6
-rw-r--r--Src/parse.c9
-rw-r--r--Src/subst.c4
-rw-r--r--Src/utils.c22
4 files changed, 25 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 31e90dfd3..df90e441a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-03-02  Bart Schaefer  <schaefer@zsh.org>
+
+	* 52612: Src/parse.c, Src/subst.c, Src/utils.c: change the %l
+	replacment of zwarning() et al. to do literal string output;
+	change previous uses to %s and use new %l for ${var?$error}
+
 2024-03-01  Bart Schaefer  <schaefer@zsh.org>
 
 	* 52645: Src/builtin.c: unset through a nameref keep up-scope
diff --git a/Src/parse.c b/Src/parse.c
index 821812c78..40eb0ee0b 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -2730,11 +2730,10 @@ yyerror(int noerr)
 	if (!t || !t[t0] || t[t0] == '\n')
 	    break;
     if (!(histdone & HISTFLAG_NOEXEC) && !(errflag & ERRFLAG_INT)) {
-	if (t0 == 20)
-	    zwarn("parse error near `%l...'", t, 20);
-	else if (t0)
-	    zwarn("parse error near `%l'", t, t0);
-	else
+	if (t0) {
+	    t = metafy(t, t0, META_STATIC);
+	    zwarn("parse error near `%s%s'", t, t0 == 20 ? "..." : "");
+	} else
 	    zwarn("parse error");
     }
     if (!noerr && noerrs != 2)
diff --git a/Src/subst.c b/Src/subst.c
index 650c09de2..49f7336bb 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3271,8 +3271,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
                 if (isset(EXECOPT)) {
                     *idend = '\0';
 		    if (*s){
+			int l;
 			singsub(&s);
-			zerr("%s: %s", idbeg, s);
+			s = unmetafy(s, &l);
+			zerr("%s: %l", idbeg, s, l);
 		    } else
 			zerr("%s: %s", idbeg, "parameter not set");
                     /*
diff --git a/Src/utils.c b/Src/utils.c
index 0fda92709..c8831c85e 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -122,14 +122,20 @@ set_widearray(char *mb_array, Widechar_array wca)
    (implemented by zerrmsg()):
 
    Code	Argument types		Prints
-   %s	const char *		C string (null terminated)
-   %l	const char *, int	C string of given length (null not required)
+   %s	const char *		C string (metafied, null terminated)
+     	                 	(output "nice")
+   %l	const char *, int	C string of given length (not metafied)
+     	                 	(output raw)
    %L	long			decimal value
    %d	int			decimal value
    %z	zlong			decimal value
    %%	(none)			literal '%'
    %c	int			character at that codepoint
-   %e	int			strerror() message (argument is typically 'errno')
+   %e	int			strerror() message (argument usually 'errno')
+     	                 	(output raw)
+
+   For %s and %l, the caller is responsible for assuring end-of-string
+   is not in the middle of a metafy pair (%s) or a multibyte character.
  */
 
 static void
@@ -310,14 +316,9 @@ zerrmsg(FILE *file, const char *fmt, va_list ap)
 		nicezputs(str, file);
 		break;
 	    case 'l': {
-		char *s;
 		str = va_arg(ap, const char *);
 		num = va_arg(ap, int);
-		num = metalen(str, num);
-		s = zhalloc(num + 1);
-		memcpy(s, str, num);
-		s[num] = '\0';
-		nicezputs(s, file);
+		fwrite(str, num, 1, file);
 		break;
 	    }
 	    case 'L':
@@ -715,7 +716,8 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
  */
 
 /**/
-mod_export int is_wcs_nicechar(wchar_t c)
+mod_export int
+is_wcs_nicechar(wchar_t c)
 {
     if (!WC_ISPRINT(c) && (c < 0x80 || !isset(PRINTEIGHTBIT))) {
 	if (c == 0x7f || c == L'\n' || c == L'\t' || c < 0x20)