Hi Jarno, and thanks Lukas

On 07/16/2018 07:27 AM, Lukas Tribus wrote:
> Hello,
> 
> 
> 
> On Fri, 29 Jun 2018 at 07:15, Jarno Huuskonen <jarno.huusko...@uef.fi> wrote:
>>
>> Hi,
>>
>> On Thu, Jun 28, Jarno Huuskonen wrote:
>>> I think this is the commit that breaks map_regm in this case:
>>> b5997f740b21ebb197e10a0f2fe9dc13163e1772 (MAJOR: threads/map: Make
>>> acls/maps thread safe).
>>>
>>> If I revert this commit from pattern.c:pattern_exec_match
>>> then the map_regm \1 backref seems to work.
>>
>> I think I found what's replacing the \000 as first char:
>> in (map.c) sample_conv_map:
>>             /* In the regm case, merge the sample with the input. */
>>             if ((long)private == PAT_MATCH_REGM) {
>>                 str = get_trash_chunk();
>>                 str->len = exp_replace(str->str, str->size, 
>> smp->data.u.str.str,
>>                                        pat->data->u.str.str,
>>                                        (regmatch_t *)smp->ctx.a[0]);
>>
>> Before call to get_trash_chunk() smp->data.u.str.str is for example
>> 'distri.com' and after get_trash_chunk() smp->data.u.str.str
>> is '\000istri.com'.
>>
>> At the moment I don't have time to dig deeper, but hopefully this
>> helps a little bit.
> 
> Thanks for the detailed analysis, relaying to Emeric ...
> 
> 
> 
> Lukas
> 

Could you try the patch in attachment? i hope it will fix the issue

R,
Emeric
>From b6d8df3387a7ff9fe781d0315b0ee1de627679cf Mon Sep 17 00:00:00 2001
From: Emeric Brun <eb...@haproxy.com>
Date: Tue, 17 Jul 2018 09:47:07 -0400
Subject: [PATCH] BUG/MINOR: map: fix map_regm with backref

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.
---
 src/map.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/map.c b/src/map.c
index 0f1b754..3d8ec20 100644
--- a/src/map.c
+++ b/src/map.c
@@ -184,10 +184,27 @@ 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 chunk *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->len = smp->data.u.str.len;
+				if (tmptrash->len > (tmptrash->size-1))
+					tmptrash->len = tmptrash->size-1;
+
+				memcpy(tmptrash->str, smp->data.u.str.str, tmptrash->len);
+				tmptrash->str[tmptrash->len] = 0;
+
 				str = get_trash_chunk();
-				str->len = exp_replace(str->str, str->size, smp->data.u.str.str,
+				str->len = exp_replace(str->str, str->size, tmptrash->str,
 				                       pat->data->u.str.str,
 				                       (regmatch_t *)smp->ctx.a[0]);
+
+				free_trash_chunk(tmptrash);
 				if (str->len == -1)
 					return 0;
 				smp->data.u.str = *str;
-- 
2.7.4

Reply via email to