constification
[exim.git] / src / src / expand.c
index f32425b3f8bc8fb959ca971f1beb8e6674be97d9..4dc13ff4847b731411eef6cf4502082543e2baf2 100644 (file)
@@ -1301,7 +1301,6 @@ static uschar *
 expand_getcertele(uschar * field, uschar * certvar)
 {
 var_entry * vp;
-certfield * cp;
 
 if (!(vp = find_var_ent(certvar)))
   {
@@ -1323,9 +1322,9 @@ if (!*(void **)vp->value)
 if (*field >= '0' && *field <= '9')
   return tls_cert_ext_by_oid(*(void **)vp->value, field, 0);
 
-for(cp = certfields;
-    cp < certfields + nelem(certfields);
-    cp++)
+for (certfield * cp = certfields;
+     cp < certfields + nelem(certfields);
+     cp++)
   if (Ustrncmp(cp->name, field, cp->namelen) == 0)
     {
     uschar * modifier = *(field += cp->namelen) == ','
@@ -1561,10 +1560,9 @@ find_header(uschar *name, int *newsize, unsigned flags, uschar *charset)
 BOOL found = !name;
 int len = name ? Ustrlen(name) : 0;
 BOOL comma = FALSE;
-header_line * h;
 gstring * g = NULL;
 
-for (h = header_list; h; h = h->next)
+for (header_line * h = header_list; h; h = h->next)
   if (h->type != htype_old && h->text)  /* NULL => Received: placeholder */
     if (!name || (len <= h->slen && strncmpic(name, h->text, len) == 0))
       {
@@ -1705,11 +1703,10 @@ fn_recipients(void)
 {
 uschar * s;
 gstring * g = NULL;
-int i;
 
 if (!f.enable_dollar_recipients) return NULL;
 
-for (i = 0; i < recipients_count; i++)
+for (int i = 0; i < recipients_count; i++)
   {
   s = recipients_list[i].address;
   g = string_append2_listele_n(g, US", ", s, Ustrlen(s));
@@ -1957,7 +1954,7 @@ switch (vp->type)
   case vtype_pspace:
     {
     int inodes;
-    sprintf(CS var_buffer, "%d",
+    sprintf(CS var_buffer, PR_EXIM_ARITH,
       receive_statvfs(val == (void *)TRUE, &inodes));
     }
   return var_buffer;
@@ -2028,11 +2025,10 @@ static int
 read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
   BOOL check_end, uschar *name, BOOL *resetok)
 {
-int i;
 const uschar *s = *sptr;
 
 while (isspace(*s)) s++;
-for (i = 0; i < n; i++)
+for (int i = 0; i < n; i++)
   {
   if (*s != '{')
     {
@@ -2174,7 +2170,7 @@ BOOL testfor = TRUE;
 BOOL tempcond, combined_cond;
 BOOL *subcondptr;
 BOOL sub2_honour_dollar = TRUE;
-int i, rc, cond_type, roffset;
+int rc, cond_type, roffset;
 int_eximarith_t num[2];
 struct stat statbuf;
 uschar name[256];
@@ -2524,7 +2520,7 @@ switch(cond_type)
   case ECOND_STR_GE:
   case ECOND_STR_GEI:
 
-  for (i = 0; i < 2; i++)
+  for (int i = 0; i < 2; i++)
     {
     /* Sometimes, we don't expand substrings; too many insecure configurations
     created using match_address{}{} and friends, where the second param
@@ -2741,16 +2737,15 @@ switch(cond_type)
 
       if (sublen == 24)
         {
-        uschar *coded = b64encode(digest, 16);
+        uschar *coded = b64encode(CUS digest, 16);
         DEBUG(D_auth) debug_printf("crypteq: using MD5+B64 hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+5);
         tempcond = (Ustrcmp(coded, sub[1]+5) == 0);
         }
       else if (sublen == 32)
         {
-        int i;
         uschar coded[36];
-        for (i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
+        for (int i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
         coded[32] = 0;
         DEBUG(D_auth) debug_printf("crypteq: using MD5+hex hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+5);
@@ -2779,16 +2774,15 @@ switch(cond_type)
 
       if (sublen == 28)
         {
-        uschar *coded = b64encode(digest, 20);
+        uschar *coded = b64encode(CUS digest, 20);
         DEBUG(D_auth) debug_printf("crypteq: using SHA1+B64 hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+6);
         tempcond = (Ustrcmp(coded, sub[1]+6) == 0);
         }
       else if (sublen == 40)
         {
-        int i;
         uschar coded[44];
-        for (i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
+        for (int i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
         coded[40] = 0;
         DEBUG(D_auth) debug_printf("crypteq: using SHA1+hex hashing\n"
           "  subject=%s\n  crypted=%s\n", coded, sub[1]+6);
@@ -3145,8 +3139,7 @@ Returns:                the value of expand max to save
 static int
 save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
 {
-int i;
-for (i = 0; i <= expand_nmax; i++)
+for (int i = 0; i <= expand_nmax; i++)
   {
   save_expand_nstring[i] = expand_nstring[i];
   save_expand_nlength[i] = expand_nlength[i];
@@ -3174,9 +3167,8 @@ static void
 restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
   int *save_expand_nlength)
 {
-int i;
 expand_nmax = save_expand_nmax;
-for (i = 0; i <= expand_nmax; i++)
+for (int i = 0; i <= expand_nmax; i++)
   {
   expand_nstring[i] = save_expand_nstring[i];
   expand_nlength[i] = save_expand_nlength[i];
@@ -3465,7 +3457,6 @@ prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp)
 {
 gstring * hash_source;
 uschar * p;
-int i;
 hctx h;
 uschar innerhash[20];
 uschar finalhash[20];
@@ -3490,7 +3481,7 @@ DEBUG(D_expand)
 memset(innerkey, 0x36, 64);
 memset(outerkey, 0x5c, 64);
 
-for (i = 0; i < Ustrlen(key); i++)
+for (int i = 0; i < Ustrlen(key); i++)
   {
   innerkey[i] ^= key[i];
   outerkey[i] ^= key[i];
@@ -3505,7 +3496,7 @@ chash_mid(HMAC_SHA1, &h, outerkey);
 chash_end(HMAC_SHA1, &h, innerhash, 20, finalhash);
 
 p = finalhash_hex;
-for (i = 0; i < 3; i++)
+for (int i = 0; i < 3; i++)
   {
   *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
   *p++ = hex_digits[finalhash[i] & 0x0f];
@@ -3558,11 +3549,12 @@ static gstring *
 cat_file_tls(void * tls_ctx, gstring * yield, uschar * eol)
 {
 int rc;
-uschar * s;
 uschar buffer[1024];
 
+/*XXX could we read direct into a pre-grown string? */
+
 while ((rc = tls_read(tls_ctx, buffer, sizeof(buffer))) > 0)
-  for (s = buffer; rc--; s++)
+  for (uschar * s = buffer; rc--; s++)
     yield = eol && *s == '\n'
       ? string_cat(yield, eol) : string_catn(yield, s, 1);
 
@@ -4814,7 +4806,7 @@ while (*s != 0)
           (void)sscanf(CS now,"%u",&inow);
           (void)sscanf(CS daystamp,"%u",&iexpire);
 
-          /* When "iexpire" is < 7, a "flip" has occured.
+          /* When "iexpire" is < 7, a "flip" has occurred.
              Adjust "inow" accordingly. */
           if ( (iexpire < 7) && (inow >= 993) ) inow = 0;
 
@@ -5021,6 +5013,7 @@ while (*s != 0)
             port = ntohs(service_info->s_port);
             }
 
+         /*XXX we trust that the request is idempotent.  Hmm. */
          fd = ip_connectedsocket(SOCK_STREAM, server_name, port, port,
                  timeout, &host, &expand_string_message,
                  do_tls ? NULL : &reqstr);
@@ -5051,9 +5044,9 @@ while (*s != 0)
          server_name = US sockun.sun_path;
 
           sigalrm_seen = FALSE;
-          alarm(timeout);
+          ALARM(timeout);
           rc = connect(fd, (struct sockaddr *)(&sockun), sizeof(sockun));
-          alarm(0);
+          ALARM_CLR(0);
           if (sigalrm_seen)
             {
             expand_string_message = US "socket connect timed out";
@@ -5126,13 +5119,13 @@ while (*s != 0)
        if (!tls_ctx)
          fp = fdopen(fd, "rb");
         sigalrm_seen = FALSE;
-        alarm(timeout);
+        ALARM(timeout);
         yield =
 #ifdef SUPPORT_TLS
          tls_ctx ? cat_file_tls(tls_ctx, yield, sub_arg[3]) :
 #endif
                    cat_file(fp, yield, sub_arg[3]);
-        alarm(0);
+        ALARM_CLR(0);
 
 #ifdef SUPPORT_TLS
        if (tls_ctx)
@@ -5265,9 +5258,9 @@ while (*s != 0)
        resetok = FALSE;
         f = fdopen(fd_out, "rb");
         sigalrm_seen = FALSE;
-        alarm(60);
+        ALARM(60);
        lookup_value = string_from_gstring(cat_file(f, NULL, NULL));
-        alarm(0);
+        ALARM_CLR(0);
         (void)fclose(f);
 
         /* Wait for the process to finish, applying the timeout, and inspect its
@@ -5351,7 +5344,6 @@ while (*s != 0)
     case EITEM_NHASH:
     case EITEM_SUBSTR:
       {
-      int i;
       int len;
       uschar *ret;
       int val[2] = { 0, -1 };
@@ -5384,9 +5376,8 @@ while (*s != 0)
           }
         }
 
-      for (i = 0; i < 2; i++)
+      for (int i = 0; i < 2; i++) if (sub[i])
         {
-        if (sub[i] == NULL) continue;
         val[i] = (int)Ustrtol(sub[i], &ret, 10);
         if (*ret != 0 || (i != 0 && val[i] < 0))
           {
@@ -5424,7 +5415,7 @@ while (*s != 0)
       md5 md5_base;
       hctx sha1_ctx;
       void *use_base;
-      int type, i;
+      int type;
       int hashlen;      /* Number of octets for the hash algorithm's output */
       int hashblocklen; /* Number of octets the hash algorithm processes */
       uschar *keyptr, *p;
@@ -5486,7 +5477,7 @@ while (*s != 0)
        memset(innerkey, 0x36, hashblocklen);
        memset(outerkey, 0x5c, hashblocklen);
 
-       for (i = 0; i < keylen; i++)
+       for (int i = 0; i < keylen; i++)
          {
          innerkey[i] ^= keyptr[i];
          outerkey[i] ^= keyptr[i];
@@ -5505,7 +5496,7 @@ while (*s != 0)
        /* Encode the final hash as a hex string */
 
        p = finalhash_hex;
-       for (i = 0; i < hashlen; i++)
+       for (int i = 0; i < hashlen; i++)
          {
          *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
          *p++ = hex_digits[finalhash[i] & 0x0f];
@@ -5567,7 +5558,6 @@ while (*s != 0)
         int ovector[3*(EXPAND_MAXN+1)];
         int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra,
           PCRE_EOPT | emptyopt, ovector, nelem(ovector));
-        int nn;
         uschar *insert;
 
         /* No match - if we previously set PCRE_NOTEMPTY after a null match, this
@@ -5593,7 +5583,7 @@ while (*s != 0)
 
         if (n == 0) n = EXPAND_MAXN + 1;
         expand_nmax = 0;
-        for (nn = 0; nn < n*2; nn += 2)
+        for (int nn = 0; nn < n*2; nn += 2)
           {
           expand_nstring[expand_nmax] = subject + ovector[nn];
           expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
@@ -5637,8 +5627,6 @@ while (*s != 0)
 
     case EITEM_EXTRACT:
       {
-      int i;
-      int j;
       int field_number = 1;
       BOOL field_number_set = FALSE;
       uschar *save_lookup_value = lookup_value;
@@ -5652,9 +5640,8 @@ while (*s != 0)
       /* Check for a format-variant specifier */
 
       if (*s != '{')                                   /*}*/
-       {
-       if (Ustrncmp(s, "json", 4) == 0) {fmt = extract_json; s += 4;}
-       }
+       if (Ustrncmp(s, "json", 4) == 0)
+         {fmt = extract_json; s += 4;}
 
       /* While skipping we cannot rely on the data for expansions being
       available (eg. $item) hence cannot decide on numeric vs. keyed.
@@ -5662,7 +5649,7 @@ while (*s != 0)
 
       if (skipping)
        {
-        for (j = 5; j > 0 && *s == '{'; j--)                   /*'}'*/
+        for (int j = 5; j > 0 && *s == '{'; j--)               /*'}'*/
          {
           if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))
            goto EXPAND_FAILED;                                 /*'{'*/
@@ -5687,7 +5674,7 @@ while (*s != 0)
          }
        }
 
-      else for (i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
+      else for (int i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
         {
        while (isspace(*s)) s++;
         if (*s == '{')                                                 /*'}'*/
@@ -5857,7 +5844,6 @@ while (*s != 0)
 
     case EITEM_LISTEXTRACT:
       {
-      int i;
       int field_number = 1;
       uschar *save_lookup_value = lookup_value;
       uschar *sub[2];
@@ -5866,10 +5852,10 @@ while (*s != 0)
 
       /* Read the field & list arguments */
 
-      for (i = 0; i < 2; i++)
+      for (int i = 0; i < 2; i++)
         {
         while (isspace(*s)) s++;
-        if (*s != '{')                                 /*}*/
+        if (*s != '{')                                 /*'}'*/
          {
          expand_string_message = string_sprintf(
            "missing '{' for arg %d of listextract", i+1);
@@ -6443,8 +6429,7 @@ while (*s != 0)
       /* Look up the dynamically loaded object handle in the tree. If it isn't
       found, dlopen() the file and put the handle in the tree for next time. */
 
-      t = tree_search(dlobj_anchor, argv[0]);
-      if (t == NULL)
+      if (!(t = tree_search(dlobj_anchor, argv[0])))
         {
         void *handle = dlopen(CS argv[0], RTLD_LAZY);
         if (handle == NULL)
@@ -6673,7 +6658,6 @@ while (*s != 0)
 
       case EOP_BASE62D:
         {
-        uschar buf[16];
         uschar *tt = sub;
         unsigned long int n = 0;
         while (*tt != 0)
@@ -6688,8 +6672,7 @@ while (*s != 0)
             }
           n = n * BASE_62 + (t - base62_chars);
           }
-        (void)sprintf(CS buf, "%ld", n);
-        yield = string_cat(yield, buf);
+        yield = string_fmt_append(yield, "%ld", n);
         continue;
         }
 
@@ -6737,12 +6720,10 @@ while (*s != 0)
          {
          md5 base;
          uschar digest[16];
-         int j;
-         char st[33];
          md5_start(&base);
          md5_end(&base, sub, Ustrlen(sub), digest);
-         for(j = 0; j < 16; j++) sprintf(st+2*j, "%02x", digest[j]);
-         yield = string_cat(yield, US st);
+         for (int j = 0; j < 16; j++)
+           yield = string_fmt_append(yield, "%02x", digest[j]);
          }
         continue;
 
@@ -6758,12 +6739,10 @@ while (*s != 0)
          {
          hctx h;
          uschar digest[20];
-         int j;
-         char st[41];
          sha1_start(&h);
          sha1_end(&h, sub, Ustrlen(sub), digest);
-         for(j = 0; j < 20; j++) sprintf(st+2*j, "%02X", digest[j]);
-         yield = string_catn(yield, US st, 40);
+         for (int j = 0; j < 20; j++)
+           yield = string_fmt_append(yield, "%02X", digest[j]);
          }
         continue;
 
@@ -6778,7 +6757,6 @@ while (*s != 0)
          {
          hctx h;
          blob b;
-         char st[3];
 
          if (!exim_sha_init(&h, HASH_SHA2_256))
            {
@@ -6788,10 +6766,7 @@ while (*s != 0)
          exim_sha_update(&h, sub, Ustrlen(sub));
          exim_sha_finish(&h, &b);
          while (b.len-- > 0)
-           {
-           sprintf(st, "%02X", *b.data++);
-           yield = string_catn(yield, US st, 2);
-           }
+           yield = string_fmt_append(yield, "%02X", *b.data++);
          }
 #else
          expand_string_message = US"sha256 only supported with TLS";
@@ -6803,7 +6778,6 @@ while (*s != 0)
        {
        hctx h;
        blob b;
-       char st[3];
        hashmethod m = !arg ? HASH_SHA3_256
          : Ustrcmp(arg, "224") == 0 ? HASH_SHA3_224
          : Ustrcmp(arg, "256") == 0 ? HASH_SHA3_256
@@ -6820,10 +6794,7 @@ while (*s != 0)
        exim_sha_update(&h, sub, Ustrlen(sub));
        exim_sha_finish(&h, &b);
        while (b.len-- > 0)
-         {
-         sprintf(st, "%02X", *b.data++);
-         yield = string_catn(yield, US st, 2);
-         }
+         yield = string_fmt_append(yield, "%02X", *b.data++);
        }
         continue;
 #else
@@ -6841,7 +6812,7 @@ while (*s != 0)
         uschar *out = sub;
         uschar *enc;
 
-        for (enc = sub; *enc != 0; enc++)
+        for (enc = sub; *enc; enc++)
           {
           if (!isxdigit(*enc))
             {
@@ -6864,9 +6835,7 @@ while (*s != 0)
           if (isdigit(c)) c -= '0';
           else c = toupper(c) - 'A' + 10;
           if (b == -1)
-            {
             b = c << 4;
-            }
           else
             {
             *out++ = b | c;
@@ -6874,7 +6843,7 @@ while (*s != 0)
             }
           }
 
-        enc = b64encode(sub, out - sub);
+        enc = b64encode(CUS sub, out - sub);
         yield = string_cat(yield, enc);
         continue;
         }
@@ -6887,7 +6856,7 @@ while (*s != 0)
         while (*(++t) != 0)
           {
           if (*t < 0x21 || 0x7E < *t)
-            yield = string_catn(yield, string_sprintf("\\x%02x", *t), 4);
+            yield = string_fmt_append(yield, "\\x%02x", *t);
          else
            yield = string_catn(yield, t, 1);
           }
@@ -6900,12 +6869,10 @@ while (*s != 0)
         {
        int cnt = 0;
        int sep = 0;
-       uschar * cp;
        uschar buffer[256];
 
        while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
-       cp = string_sprintf("%d", cnt);
-        yield = string_cat(yield, cp);
+       yield = string_fmt_append(yield, "%d", cnt);
         continue;
         }
 
@@ -7271,9 +7238,9 @@ while (*s != 0)
       case EOP_RFC2047:
         {
         uschar buffer[2048];
-       const uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
-          buffer, sizeof(buffer), FALSE);
-        yield = string_cat(yield, string);
+        yield = string_cat(yield,
+                           parse_quote_2047(sub, Ustrlen(sub), headers_charset,
+                             buffer, sizeof(buffer), FALSE));
         continue;
         }
 
@@ -7474,13 +7441,12 @@ while (*s != 0)
 
       case EOP_ESCAPE8BIT:
        {
-       const uschar * s = sub;
        uschar c;
 
-       for (s = sub; (c = *s); s++)
+       for (const uschar * s = sub; (c = *s); s++)
          yield = c < 127 && c != '\\'
            ? string_catn(yield, s, 1)
-           : string_catn(yield, string_sprintf("\\%03o", c), 4);
+           : string_fmt_append(yield, "\\%03o", c);
        continue;
        }
 
@@ -7492,19 +7458,18 @@ while (*s != 0)
         uschar *save_sub = sub;
         uschar *error = NULL;
         int_eximarith_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
-        if (error != NULL)
+        if (error)
           {
           expand_string_message = string_sprintf("error in expression "
             "evaluation: %s (after processing \"%.*s\")", error,
            (int)(sub-save_sub), save_sub);
           goto EXPAND_FAILED;
           }
-        sprintf(CS var_buffer, PR_EXIM_ARITH, n);
-        yield = string_cat(yield, var_buffer);
+        yield = string_fmt_append(yield, PR_EXIM_ARITH, n);
         continue;
         }
 
-      /* Handle time period formating */
+      /* Handle time period formatting */
 
       case EOP_TIME_EVAL:
         {
@@ -7515,8 +7480,7 @@ while (*s != 0)
             "Exim time interval in \"%s\" operator", sub, name);
           goto EXPAND_FAILED;
           }
-        sprintf(CS var_buffer, "%d", n);
-        yield = string_cat(yield, var_buffer);
+        yield = string_fmt_append(yield, "%d", n);
         continue;
         }
 
@@ -7543,9 +7507,9 @@ while (*s != 0)
 #ifdef SUPPORT_TLS
        uschar * s = vp && *(void **)vp->value
          ? tls_cert_der_b64(*(void **)vp->value)
-         : b64encode(sub, Ustrlen(sub));
+         : b64encode(CUS sub, Ustrlen(sub));
 #else
-       uschar * s = b64encode(sub, Ustrlen(sub));
+       uschar * s = b64encode(CUS sub, Ustrlen(sub));
 #endif
        yield = string_cat(yield, s);
        continue;
@@ -7568,12 +7532,8 @@ while (*s != 0)
       /* strlen returns the length of the string */
 
       case EOP_STRLEN:
-        {
-        uschar buff[24];
-        (void)sprintf(CS buff, "%d", Ustrlen(sub));
-        yield = string_cat(yield, buff);
+        yield = string_fmt_append(yield, "%d", Ustrlen(sub));
         continue;
-        }
 
       /* length_n or l_n takes just the first n characters or the whole string,
       whichever is the shorter;
@@ -7606,7 +7566,7 @@ while (*s != 0)
         int len;
         uschar *ret;
 
-        if (arg == NULL)
+        if (!arg)
           {
           expand_string_message = string_sprintf("missing values after %s",
             name);
@@ -7670,14 +7630,12 @@ while (*s != 0)
 
       case EOP_STAT:
         {
-        uschar *s;
         uschar smode[12];
         uschar **modetable[3];
-        int i;
         mode_t mode;
         struct stat st;
 
-        if ((expand_forbid & RDO_EXISTS) != 0)
+        if (expand_forbid & RDO_EXISTS)
           {
           expand_string_message = US"Use of the stat() expansion is not permitted";
           goto EXPAND_FAILED;
@@ -7704,20 +7662,20 @@ while (*s != 0)
         modetable[1] = ((mode & 02000) == 0)? mtable_normal : mtable_setid;
         modetable[2] = ((mode & 04000) == 0)? mtable_normal : mtable_setid;
 
-        for (i = 0; i < 3; i++)
+        for (int i = 0; i < 3; i++)
           {
           memcpy(CS(smode + 7 - i*3), CS(modetable[i][mode & 7]), 3);
           mode >>= 3;
           }
 
         smode[10] = 0;
-        s = string_sprintf("mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
+        yield = string_fmt_append(yield,
+         "mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
           "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
           (long)(st.st_mode & 077777), smode, (long)st.st_ino,
           (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
           (long)st.st_gid, st.st_size, (long)st.st_atime,
           (long)st.st_mtime, (long)st.st_ctime);
-        yield = string_cat(yield, s);
         continue;
         }
 
@@ -7725,14 +7683,11 @@ while (*s != 0)
 
       case EOP_RANDINT:
         {
-        int_eximarith_t max;
-        uschar *s;
+        int_eximarith_t max = expanded_string_integer(sub, TRUE);
 
-        max = expanded_string_integer(sub, TRUE);
-        if (expand_string_message != NULL)
+        if (expand_string_message)
           goto EXPAND_FAILED;
-        s = string_sprintf("%d", vaguely_random_number((int)max));
-        yield = string_cat(yield, s);
+        yield = string_fmt_append(yield, "%d", vaguely_random_number((int)max));
         continue;
         }
 
@@ -7758,9 +7713,9 @@ while (*s != 0)
       /* Unknown operator */
 
       default:
-      expand_string_message =
-        string_sprintf("unknown expansion operator \"%s\"", name);
-      goto EXPAND_FAILED;
+       expand_string_message =
+         string_sprintf("unknown expansion operator \"%s\"", name);
+       goto EXPAND_FAILED;
       }
     }
 
@@ -8237,23 +8192,21 @@ assert_no_variables(void * ptr, int len, const char * filename, int linenumber)
 {
 err_ctx e = { .region_start = ptr, .region_end = US ptr + len,
              .var_name = NULL, .var_data = NULL };
-int i;
-var_entry * v;
 
 /* check acl_ variables */
 tree_walk(acl_var_c, assert_variable_notin, &e);
 tree_walk(acl_var_m, assert_variable_notin, &e);
 
 /* check auth<n> variables */
-for (i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
+for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
   assert_variable_notin(US"auth<n>", auth_vars[i], &e);
 
 /* check regex<n> variables */
-for (i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
+for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
   assert_variable_notin(US"regex<n>", regex_vars[i], &e);
 
 /* check known-name variables */
-for (v = var_table; v < var_table + var_table_size; v++)
+for (var_entry * v = var_table; v < var_table + var_table_size; v++)
   if (v->type == vtype_stringptr)
     assert_variable_notin(US v->name, *(USS v->value), &e);
 
@@ -8290,9 +8243,8 @@ BOOL yield = n >= 0;
 if (n == 0) n = EXPAND_MAXN + 1;
 if (yield)
   {
-  int nn;
-  expand_nmax = (setup < 0)? 0 : setup + 1;
-  for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2)
+  expand_nmax = setup < 0 ? 0 : setup + 1;
+  for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
     {
     expand_nstring[expand_nmax] = subject + ovector[nn];
     expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
@@ -8305,7 +8257,6 @@ return yield;
 
 int main(int argc, uschar **argv)
 {
-int i;
 uschar buffer[1024];
 
 debug_selector = D_v;
@@ -8313,7 +8264,7 @@ debug_file = stderr;
 debug_fd = fileno(debug_file);
 big_buffer = malloc(big_buffer_size);
 
-for (i = 1; i < argc; i++)
+for (int i = 1; i < argc; i++)
   {
   if (argv[i][0] == '+')
     {