]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: map: fix map_regm with backref
authorEmeric Brun <ebrun@haproxy.com>
Tue, 17 Jul 2018 13:47:07 +0000 (09:47 -0400)
committerWilly Tarreau <w@1wt.eu>
Thu, 16 Aug 2018 17:44:04 +0000 (19:44 +0200)
Due to a cascade of get_trash_chunk calls the sample is
corrupted when we want to read it.

The fix consist to use a temporary chunk to copy the sample
value and use it.

[wt: for 1.8 and older, a backport was successfully tested here :
 https://www.mail-archive.com/haproxy@formilux.org/msg30694.html]

src/map.c

index 5c107355efc0ae0b9f431f17c66d4a6a5360fbed..d2df22e21212e0ce02577217e06cc86587fd2386 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -185,11 +185,26 @@ static int sample_conv_map(const struct arg *arg_p, struct sample *smp, void *pr
                if (pat->data) {
                        /* In the regm case, merge the sample with the input. */
                        if ((long)private == PAT_MATCH_REGM) {
+                               struct buffer *tmptrash;
+
+                               /* Copy the content of the sample because it could
+                                  be scratched by incoming get_trash_chunk */
+                               tmptrash = alloc_trash_chunk();
+                               if (!tmptrash)
+                                       return 0;
+
+                               tmptrash->data = smp->data.u.str.data;
+                               if (tmptrash->data > (tmptrash->size-1))
+                                       tmptrash->data = tmptrash->size-1;
+
+                               memcpy(tmptrash->area, smp->data.u.str.area, tmptrash->data);
+                               tmptrash->area[tmptrash->data] = 0;
+
                                str = get_trash_chunk();
                                str->data = exp_replace(str->area, str->size,
-                                                      smp->data.u.str.area,
-                                                      pat->data->u.str.area,
-                                                      (regmatch_t *)smp->ctx.a[0]);
+                                                       tmptrash->area,
+                                                       pat->data->u.str.area,
+                                                       (regmatch_t *)smp->ctx.a[0]);
                                if (str->data == -1)
                                        return 0;
                                smp->data.u.str = *str;