aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2021-03-02 12:58:50 -0700
committerTodd C. Miller <Todd.Miller@sudo.ws>2021-03-02 12:58:50 -0700
commitd54b703cae9c5e7d5cf0f251bc847d38a70170c4 (patch)
tree6f65d657e20ed0198cea2c49092ed77bd3b72d40
parentc0f4e97e4561ff42544e92512bbaf3d7d1f6a671 (diff)
downloadone-true-awk-d54b703cae9c5e7d5cf0f251bc847d38a70170c4.tar.gz
Fix size computation in replace_repeat() for special_case REPEAT_WITH_Q.
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. Reproducible with the following under valgrind: echo '#!/usr/bin/awk' | awk \ '/^#! ?\/.*\/[a-z]{0,2}awk/ {sub(/^#! ?\/.*\/[a-z]{0,2}awk/,"#! awk"); print}'
-rw-r--r--b.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/b.c b/b.c
index f889ee5..8042366 100644
--- a/b.c
+++ b/b.c
@@ -935,7 +935,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: () */
}
@@ -964,11 +964,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)