From 35465406cdae9cd4a15e7f6699e657b5d09bf7bd Mon Sep 17 00:00:00 2001
From: Chet Ramey <chet.ramey@case.edu>
Date: Fri, 2 Feb 2024 14:39:50 -0500
Subject: [PATCH] fix for cd when curent directory doesn't exist; fix wait -n
 in posix mode to delete any job that it returns; fix some variables where
 readonly can be circumvented; fix some overflows in printf

Conflict:only the modified content of builtins/printf.def is rounded.
Reference:https://git.savannah.gnu.org/cgit/bash.git/commit/?id=35465406cdae9cd4a15e7f6699e657b5d09bf7bd
---
 builtins/printf.def | 122 +++++++++++++++++++++++---------------------
 1 file changed, 65 insertions(+), 57 deletions(-)

diff --git a/builtins/printf.def b/builtins/printf.def
index 84658c3..96801e4 100644
--- a/builtins/printf.def
+++ b/builtins/printf.def
@@ -1,7 +1,7 @@
 This file is printf.def, from which is created printf.c.
 It implements the builtin "printf" in Bash.
 
-Copyright (C) 1997-2021 Free Software Foundation, Inc.
+Copyright (C) 1997-2024 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -109,6 +109,50 @@ $END
 extern int errno;
 #endif
 
+/* We free the buffer used by mklong() if it's `too big'. */
+#define PRETURN(value) \
+  do \
+    { \
+      QUIT; \
+      retval = value; \
+      if (conv_bufsize > 4096 ) \
+	{ \
+	  free (conv_buf); \
+	  conv_bufsize = 0; \
+	  conv_buf = 0; \
+	} \
+      if (vflag) \
+	{ \
+	  SHELL_VAR *v; \
+	  v = builtin_bind_variable  (vname, vbuf, 0); \
+	  stupidly_hack_special_variables (vname); \
+	  if (v == 0 || readonly_p (v) || noassign_p (v)) \
+	    retval = EXECUTION_FAILURE; \
+	  if (vbsize > 4096) \
+	    { \
+	      free (vbuf); \
+	      vbsize = 0; \
+	      vbuf = 0; \
+	    } \
+	  else if (vbuf) \
+	    vbuf[0] = 0; \
+	} \
+      else \
+	{ \
+	  if (ferror (stdout) == 0) \
+	    fflush (stdout); \
+	  QUIT; \
+	  if (ferror (stdout)) \
+	    { \
+	      sh_wrerror (); \
+	      clearerr (stdout); \
+	      retval = EXECUTION_FAILURE; \
+	    } \
+	} \
+      return (retval); \
+    } \
+  while (0)
+
 #define PC(c) \
   do { \
     char b[2]; \
@@ -124,7 +168,9 @@ extern int errno;
 #define PF(f, func) \
   do { \
     int nw; \
-    clearerr (stdout); \
+    if (vflag == 0) \
+      clearerr (stdout); \
+    errno = 0; \
     if (have_fieldwidth && have_precision) \
       nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
     else if (have_fieldwidth) \
@@ -133,56 +179,17 @@ extern int errno;
       nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \
     else \
       nw = vflag ? vbprintf (f, func) : printf (f, func); \
-    tw += nw; \
-    QUIT; \
-    if (ferror (stdout)) \
+    if (nw < 0 || ferror (stdout)) \
       { \
-	sh_wrerror (); \
-	clearerr (stdout); \
-	return (EXECUTION_FAILURE); \
+	QUIT; \
+	if (vflag) \
+	  builtin_error ("%s", strerror (errno)); \
+	PRETURN (EXECUTION_FAILURE); \
       } \
+    tw += nw; \
+    QUIT; \
   } while (0)
 
-/* We free the buffer used by mklong() if it's `too big'. */
-#define PRETURN(value) \
-  do \
-    { \
-      QUIT; \
-      if (vflag) \
-	{ \
-	  SHELL_VAR *v; \
-	  v = builtin_bind_variable  (vname, vbuf, bindflags); \
-	  stupidly_hack_special_variables (vname); \
-	  if (v == 0 || readonly_p (v) || noassign_p (v)) \
-	    return (EXECUTION_FAILURE); \
-	} \
-      if (conv_bufsize > 4096 ) \
-	{ \
-	  free (conv_buf); \
-	  conv_bufsize = 0; \
-	  conv_buf = 0; \
-	} \
-      if (vbsize > 4096) \
-	{ \
-	  free (vbuf); \
-	  vbsize = 0; \
-	  vbuf = 0; \
-	} \
-      else if (vbuf) \
-	vbuf[0] = 0; \
-      if (ferror (stdout) == 0) \
-	fflush (stdout); \
-      QUIT; \
-      if (ferror (stdout)) \
-	{ \
-	  sh_wrerror (); \
-	  clearerr (stdout); \
-	  return (EXECUTION_FAILURE); \
-	} \
-      return (value); \
-    } \
-  while (0)
-
 #define SKIP1 "#'-+ 0"
 #define LENMODS "hjlLtz"
 
@@ -238,7 +245,7 @@ static int vflag = 0;
 static int bindflags = 0;
 static char *vbuf, *vname;
 static size_t vbsize;
-static int vblen;
+static size_t vblen;
 
 static intmax_t tw;
 
@@ -315,6 +322,7 @@ printf_builtin (list)
       return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
     }
 
+  /* If the format string is empty after preprocessing, return immediately. */
   if (list->word->word == 0 || list->word->word[0] == '\0')
     return (EXECUTION_SUCCESS);
 
@@ -324,10 +332,6 @@ printf_builtin (list)
 
   garglist = orig_arglist = list->next;
 
-  /* If the format string is empty after preprocessing, return immediately. */
-  if (format == 0 || *format == 0)
-    return (EXECUTION_SUCCESS);
-
   /* Basic algorithm is to scan the format string for conversion
      specifications -- once one is found, find out if the field
      width or precision is a '*'; if it is, gather up value.  Note,
@@ -735,7 +739,7 @@ printf_builtin (list)
 	  modstart[1] = nextch;
 	}
 
-      if (ferror (stdout))
+      if (vflag == 0 && ferror (stdout))
 	{
 	  /* PRETURN will print error message. */
 	  PRETURN (EXECUTION_FAILURE);
@@ -867,7 +871,7 @@ printstr (fmt, string, len, fieldwidth, precision)
   for (; padlen < 0; padlen++)
     PC (' ');
 
-  return (ferror (stdout) ? -1 : 0);
+  return ((vflag == 0 && ferror (stdout)) ? -1 : 0);
 }
   
 /* Convert STRING by expanding the escape sequences specified by the
@@ -1085,7 +1089,7 @@ vbadd (buf, blen)
 
 #ifdef DEBUG
   if  (strlen (vbuf) != vblen)
-    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+    internal_error  ("printf:vbadd: vblen (%zu) != strlen (vbuf) (%zu)", vblen, strlen (vbuf));
 #endif
 
   return vbuf;
@@ -1107,6 +1111,8 @@ vbprintf (format, va_alist)
   SH_VA_START (args, format);
   blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
   va_end (args);
+  if (blen < 0)
+    return (blen);
 
   nlen = vblen + blen + 1;
   if (nlen >= vbsize)
@@ -1116,6 +1122,8 @@ vbprintf (format, va_alist)
       SH_VA_START (args, format);
       blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
       va_end (args);
+      if (blen < 0)
+	return (blen);
     }
 
   vblen += blen;
@@ -1123,7 +1131,7 @@ vbprintf (format, va_alist)
 
 #ifdef DEBUG
   if  (strlen (vbuf) != vblen)
-    internal_error  ("printf:vbprintf: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+    internal_error  ("printf:vbprintf: vblen (%zu) != strlen (vbuf) (%zu)", vblen, strlen (vbuf));
 #endif
   
   return (blen);
-- 
2.33.0

