Fix growable-string sprintf
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 15 Nov 2018 18:55:51 +0000 (18:55 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 15 Nov 2018 19:36:44 +0000 (19:36 +0000)
Broken-by d12746bc15

src/src/string.c
test/scripts/0000-Basic/0003

index d0b8db4ae52bfa834b834c03aed9536364c4438e..914030775ba660a06ef00c842498a96d8835fc23 100644 (file)
@@ -1358,7 +1358,11 @@ while (*fp)
     {
     /* Avoid string_copyn() due to COMPILE_UTILITY */
     if (g->ptr >= lim - 1)
     {
     /* Avoid string_copyn() due to COMPILE_UTILITY */
     if (g->ptr >= lim - 1)
-      if (extend) gstring_grow(g, g->ptr, 1); else return NULL;
+      {
+      if (!extend) return NULL;
+      gstring_grow(g, g->ptr, 1);
+      lim = g->size - 1;
+      }
     g->s[g->ptr++] = (uschar) *fp++;
     continue;
     }
     g->s[g->ptr++] = (uschar) *fp++;
     continue;
     }
@@ -1426,7 +1430,12 @@ while (*fp)
     case 'X':
       width = length > L_LONG ? 24 : 12;
       if (g->ptr >= lim - width)
     case 'X':
       width = length > L_LONG ? 24 : 12;
       if (g->ptr >= lim - width)
-       if (extend) gstring_grow(g, g->ptr, width); else return NULL;
+       {
+       if (!extend) return NULL;
+       gstring_grow(g, g->ptr, width);
+       lim = g->size - 1;
+       gp = CS g->s + g->ptr;
+       }
       strncpy(newformat, item_start, fp - item_start);
       newformat[fp - item_start] = 0;
 
       strncpy(newformat, item_start, fp - item_start);
       newformat[fp - item_start] = 0;
 
@@ -1451,7 +1460,12 @@ while (*fp)
       {
       void * ptr;
       if (g->ptr >= lim - 24)
       {
       void * ptr;
       if (g->ptr >= lim - 24)
-       if (extend) gstring_grow(g, g->ptr, 24); else return NULL;
+       {
+       if (!extend) return NULL;
+       gstring_grow(g, g->ptr, 24);
+       lim = g->size - 1;
+       gp = CS g->s + g->ptr;
+       }
       /* sprintf() saying "(nil)" for a null pointer seems unreliable.
       Handle it explicitly. */
       if ((ptr = va_arg(ap, void *)))
       /* sprintf() saying "(nil)" for a null pointer seems unreliable.
       Handle it explicitly. */
       if ((ptr = va_arg(ap, void *)))
@@ -1479,7 +1493,12 @@ while (*fp)
     case 'G':
       if (precision < 0) precision = 6;
       if (g->ptr >= lim - precision - 8)
     case 'G':
       if (precision < 0) precision = 6;
       if (g->ptr >= lim - precision - 8)
-       if (extend) gstring_grow(g, g->ptr, precision+8); else return NULL;
+       {
+       if (!extend) return NULL;
+       gstring_grow(g, g->ptr, precision+8);
+       lim = g->size - 1;
+       gp = CS g->s + g->ptr;
+       }
       strncpy(newformat, item_start, fp - item_start);
       newformat[fp-item_start] = 0;
       if (length == L_LONGDOUBLE)
       strncpy(newformat, item_start, fp - item_start);
       newformat[fp-item_start] = 0;
       if (length == L_LONGDOUBLE)
@@ -1492,13 +1511,21 @@ while (*fp)
 
     case '%':
       if (g->ptr >= lim - 1)
 
     case '%':
       if (g->ptr >= lim - 1)
-       if (extend) gstring_grow(g, g->ptr, 1); else return NULL;
+       {
+       if (!extend) return NULL;
+       gstring_grow(g, g->ptr, 1);
+       lim = g->size - 1;
+       }
       g->s[g->ptr++] = (uschar) '%';
       break;
 
     case 'c':
       if (g->ptr >= lim - 1)
       g->s[g->ptr++] = (uschar) '%';
       break;
 
     case 'c':
       if (g->ptr >= lim - 1)
-       if (extend) gstring_grow(g, g->ptr, 1); else return NULL;
+       {
+       if (!extend) return NULL;
+       gstring_grow(g, g->ptr, 1);
+       lim = g->size - 1;
+       }
       g->s[g->ptr++] = (uschar) va_arg(ap, int);
       break;
 
       g->s[g->ptr++] = (uschar) va_arg(ap, int);
       break;
 
@@ -1563,7 +1590,11 @@ while (*fp)
          }
        }
       else if (g->ptr >= lim - width)
          }
        }
       else if (g->ptr >= lim - width)
-       gstring_grow(g, g->ptr, width);
+       {
+       gstring_grow(g, g->ptr, width - (lim - g->ptr));
+       lim = g->size - 1;
+       gp = CS g->s + g->ptr;
+       }
 
       g->ptr += sprintf(gp, "%*.*s", width, precision, s);
       if (fp[-1] == 'S')
 
       g->ptr += sprintf(gp, "%*.*s", width, precision, s);
       if (fp[-1] == 'S')
index 58868bb67f949f21d37c82f61641e04590c67663..b3b3f89a31c258833c913b78f1215cae7c16cad9 100644 (file)
@@ -99,3 +99,6 @@ rset
 mail from:<BLOCKED@zz.xy>
 rcpt to:<x@test.ex>
 rset
 mail from:<BLOCKED@zz.xy>
 rcpt to:<x@test.ex>
 rset
+****
+#
+#