]> diplodocus.org Git - nmh/blobdiff - sbr/fmt_scan.c
Corrected comment: whom(1) does not use context_foil().
[nmh] / sbr / fmt_scan.c
index 67f0a03e8b8921600440d7678e5e3d380ea9cbcc..f9aee54b0d2bd866f23bb4075424c58ee025722e 100644 (file)
@@ -247,9 +247,9 @@ static void
 cpstripped (charstring_t dest, size_t max, char *str)
 {
     static bool deja_vu;
-    static char *oddchar;
+    static char oddchar[MB_LEN_MAX * 2];
     static size_t oddlen;
-    static char *spacechar;
+    static char spacechar[MB_LEN_MAX * 2];
     static size_t spacelen;
     char *end;
     bool squash;
@@ -259,19 +259,12 @@ cpstripped (charstring_t dest, size_t max, char *str)
     int w;
 
     if (!deja_vu) {
-        size_t two;
-
         deja_vu = true;
 
-        two = MB_CUR_MAX * 2; /* Varies at run-time. */
-
-        oddchar = mh_xmalloc(two);
-        oddlen = wcstombs(oddchar, L"?", two);
+        oddlen = wcstombs(oddchar, L"?", sizeof oddchar);
         assert(oddlen > 0);
-
         assert(wcwidth(L' ') == 1); /* Need to pad in ones. */
-        spacechar = mh_xmalloc(two);
-        spacelen = wcstombs(spacechar, L" ", two);
+        spacelen = wcstombs(spacechar, L" ", sizeof spacechar);
         assert(spacelen > 0);
     }
 
@@ -413,7 +406,10 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
          struct fmt_callbacks *callbacks)
 {
     char *sp;
-    char *savestr, *str;
+    /* If str points to part of buffer[] or buffer2[] then it must only
+     * ever point at their first element as otherwise undefined
+     * behaviour from overlapping strncpy(3)s can result. */
+    char *str, *savestr;
     char buffer[NMH_BUFSIZ], buffer2[NMH_BUFSIZ];
     int i, c;
     bool rjust;
@@ -757,6 +753,7 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
                            *xp-- = '\0';
                    if (rjust && i > 0 && (int) strlen(str) > i)
                        str += strlen(str) - i;
+                    str = memmove(buffer, str, strlen(str) + 1);
            }
            break;
 
@@ -791,15 +788,18 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
            value *= fmt->f_value;
            break;
        case FT_LV_DIVIDE_L:
-           if (fmt->f_value)
-               value /= fmt->f_value;
-           else
+            if (fmt->f_value == 0 || (fmt->f_value == -1 && value == INT_MIN)) {
+                // FIXME: Tell the user, and probably stop.
                value = 0;
+            } else {
+                value /= fmt->f_value;
+            }
            break;
        case FT_LV_MODULO_L:
            if (fmt->f_value)
                value %= fmt->f_value;
            else
+                // FIXME: Tell the user, and probably stop.
                value = 0;
            break;
        case FT_SAVESTR:
@@ -946,6 +946,7 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
                            else
                                break;
                    }
+                    str = memmove(buffer, str, strlen(str) + 1);
                } else if (!(str = get_x400_friendly (mn->m_mbox,
                                buffer, sizeof(buffer)))) {
        unfriendly:
@@ -1147,7 +1148,11 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
                               comp->c_mn will be run through
                               FT_LS_ADDR, which will strip off any
                               pers name. */
-                           free (comp->c_text);
+                           /* NB: We remove the call to free() here
+                              because it interferes with the buffer
+                              management in scansbr.c.  Revisit this
+                              when we clean up memory handling */
+                           /* free (comp->c_text); */
                            comp->c_text = str = strdup (mn->m_text);
                            comp->c_mn = mn;
                        }