Christian Weisgerber <na...@mips.inka.de> wrote:

> This includes the list of remaining ports with %n warnings:
> 
> mail/exim
> net/climm

two left.

here is my brutish attempt to deal with exim, which has a set of
*printf-like functions which return pointer, and but discard the
length

in a few cases, %n is at the end, allowing use of strlen() to
recover the discarded length

in other cases, %n is embedded, and the operation must be split up.

I am unable (and unwilling) to run this in test.  Is there anyone who
can take this on?


--- ./exim-4.94.2/exim-4.94.2/src/transport.c.save      Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/transport.c   Sun Sep 19 16:47:03 2021
@@ -959,9 +959,9 @@
   if (tctx->options & topt_add_return_path)
     {
     int n;
-    uschar * s = string_sprintf("Return-path: <%.*s>\n%n",
-                          EXIM_EMAILADDR_MAX, return_path, &n);
-    if (!write_chunk(tctx, s, n)) goto bad;
+    uschar * s = string_sprintf("Return-path: <%.*s>\n",
+                          EXIM_EMAILADDR_MAX, return_path);
+    if (!write_chunk(tctx, s, strlen(s))) goto bad;
     }
 
   /* Add envelope-to: if requested */
--- ./exim-4.94.2/exim-4.94.2/src/rewrite.c.save        Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/rewrite.c     Sun Sep 19 16:52:49 2021
@@ -325,8 +325,9 @@
     else
       {
       subject = newparsed;
-      new = string_sprintf("%.*s%s%n%s",
-         yield_start, yield, subject, &end, yield + yield_end);
+      new = string_sprintf("%.*s%s%s",
+         yield_start, yield, subject, yield + yield_end);
+      end = strlen(new) - strlen(yield + yield_end);
       yield_end = end;
       yield = new;
       }
--- ./exim-4.94.2/exim-4.94.2/src/host.c.save   Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/host.c        Sun Sep 19 16:56:15 2021
@@ -2587,10 +2587,13 @@
   {
   gstring * g;
   uschar * temp_fully_qualified_name;
+  char *temp;
   int prefix_length;
 
-  g = string_fmt_append(NULL, "_%s._tcp.%n%.256s",
-       srv_service, &prefix_length, host->name);
+  prefix_length = asprintf(&temp, "_%s._tcp.:", srv_service);
+  g = string_fmt_append(NULL, "%s%.256s",
+       temp, host->name);
+  free(&temp);
   temp_fully_qualified_name = string_from_gstring(g);
   ind_type = T_SRV;
 
--- ./exim-4.94.2/exim-4.94.2/src/exim.c.save   Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/exim.c        Sun Sep 19 16:57:41 2021
@@ -4751,8 +4751,12 @@
         if (amp)
           {
           int loffset;
-          string_format(buffer, sizeof(buffer), "%.*s%n%s%s",
-            (int)(amp - name), name, &loffset, originator_login, amp + 1);
+          char *temp = NULL;
+
+          loffset = asprintf(&temp, "%.*s", (int)(amp - name), name);
+          string_format(buffer, sizeof(buffer), "%s%s%s", temp,
+            originator_login, amp + 1);
+          free(temp);
           buffer[loffset] = toupper(buffer[loffset]);
           name = buffer;
           }
--- ./exim-4.94.2/exim-4.94.2/src/spam.c.save   Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/spam.c        Sun Sep 19 16:58:21 2021
@@ -395,10 +395,10 @@
   {                            /* spamassassin variant */
   int n;
   uschar * s = string_sprintf(
-         "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n%n",
-         user_name, mbox_size, &n);
+         "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
+         user_name, mbox_size);
   /* send our request */
-  wrote = send(spamd_cctx.sock, s, n, 0);
+  wrote = send(spamd_cctx.sock, s, strlen(n), 0);
   }
 
 if (wrote == -1)
--- ./exim-4.94.2/exim-4.94.2/src/acl.c.save    Fri Apr 30 06:08:21 2021
+++ ./exim-4.94.2/exim-4.94.2/src/acl.c Sun Sep 19 17:07:15 2021
@@ -2907,9 +2907,11 @@
   HDEBUG(D_acl)
     {
     int lhswidth = 0;
-    debug_printf_indent("check %s%s %n",
-      (!conditions[cb->type].is_modifier && cb->u.negated)? "!":"",
-      conditions[cb->type].name, &lhswidth);
+    char *first = (!conditions[cb->type].is_modifier && cb->u.negated)? "!":"";
+    char *second = conditions[cb->type].name;
+
+    debug_printf_indent("check %s%s ", first, second);
+    lhswidth = sizeof("check ") + strlen(first) + strlen(second);
 
     if (cb->type == ACLC_SET)
       {

Reply via email to