Fix size computation in replace_repeat() for special_case REPEAT_WITH_Q.
authormillert <millert@openbsd.org>
Tue, 2 Mar 2021 20:41:42 +0000 (20:41 +0000)
committermillert <millert@openbsd.org>
Tue, 2 Mar 2021 20:41:42 +0000 (20:41 +0000)
This resulted in the NUL terminator being written to the end of the
buffer which was not the same as the end of the string.  That in
turn caused garbage bytes from malloc() to be processed.  Also
change the NUL termination to be less error prone by writing the
NUL immediately after the last byte copied.  OK sthen@

usr.bin/awk/b.c

index 1c272cd..53418e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: b.c,v 1.35 2020/12/09 20:00:11 millert Exp $  */
+/*     $OpenBSD: b.c,v 1.36 2021/03/02 20:41:42 millert Exp $  */
 /****************************************************************
 Copyright (C) Lucent Technologies 1997
 All Rights Reserved
@@ -942,7 +942,7 @@ replace_repeat(const uschar *reptok, int reptoklen, const uschar *atom,
        if (special_case == REPEAT_PLUS_APPENDED) {
                size++;         /* for the final + */
        } else if (special_case == REPEAT_WITH_Q) {
-               size += init_q + (atomlen+1)* n_q_reps;
+               size += init_q + (atomlen+1)* (n_q_reps-init_q);
        } else if (special_case == REPEAT_ZERO) {
                size += 2;      /* just a null ERE: () */
        }
@@ -971,11 +971,8 @@ replace_repeat(const uschar *reptok, int reptoklen, const uschar *atom,
                }
        }
        memcpy(&buf[j], reptok+reptoklen, suffix_length);
-       if (special_case == REPEAT_ZERO) {
-               buf[j+suffix_length] = '\0';
-       } else {
-               buf[size] = '\0';
-       }
+       j += suffix_length;
+       buf[j] = '\0';
        /* free old basestr */
        if (firstbasestr != basestr) {
                if (basestr)