Skip to content

Commit b0a9216

Browse files
committed
BUG/MEDIUM: samples: Fix handling of SMP_T_METH samples
Samples of type SMP_T_METH were not properly handled in smp_dup(), smp_is_safe() and smp_is_rw(). For "other" methods, for instance PATCH, a fallback was performed on the SMP_T_STR type. Only the buffer considered changed. "smp->data.u.meth.str" should be used for the SMP_T_METH samples while smp->data.u.str should be used for SMP_T_STR samples. However, in smp_dup(), the result was stored in wrong buffer, the string one instead of the method one. In smp_is_safe() and smp_is_rw(), the method buffer was not used at all. We now take care to use the right buffer. This patch must be backported to all stable versions.
1 parent 265be7e commit b0a9216

2 files changed

Lines changed: 18 additions & 15 deletions

File tree

include/haproxy/sample.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,26 @@ struct sample *smp_set_owner(struct sample *smp, struct proxy *px,
101101
static inline
102102
int smp_is_safe(struct sample *smp)
103103
{
104+
struct buffer *buf;
105+
104106
switch (smp->data.type) {
105107
case SMP_T_METH:
106108
if (smp->data.u.meth.meth != HTTP_METH_OTHER)
107109
return 1;
108110
__fallthrough;
109111

110112
case SMP_T_STR:
111-
if (!smp->data.u.str.size || smp->data.u.str.data >= smp->data.u.str.size)
113+
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
114+
if (!buf->size || buf->data >= buf->size)
112115
return 0;
113116

114-
if (smp->data.u.str.area[smp->data.u.str.data] == 0)
117+
if (buf->area[buf->data] == 0)
115118
return 1;
116119

117120
if (smp->flags & SMP_F_CONST)
118121
return 0;
119122

120-
smp->data.u.str.area[smp->data.u.str.data] = 0;
123+
buf->area[buf->data] = 0;
121124
return 1;
122125

123126
case SMP_T_BIN:
@@ -148,6 +151,8 @@ int smp_make_safe(struct sample *smp)
148151
static inline
149152
int smp_is_rw(struct sample *smp)
150153
{
154+
struct buffer *buf;
155+
151156
if (smp->flags & SMP_F_CONST)
152157
return 0;
153158

@@ -158,12 +163,12 @@ int smp_is_rw(struct sample *smp)
158163
__fallthrough;
159164

160165
case SMP_T_STR:
161-
if (!smp->data.u.str.size ||
162-
smp->data.u.str.data >= smp->data.u.str.size)
166+
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
167+
if (!buf->size || buf->data >= buf->size)
163168
return 0;
164169

165-
if (smp->data.u.str.area[smp->data.u.str.data] != 0)
166-
smp->data.u.str.area[smp->data.u.str.data] = 0;
170+
if (buf->area[buf->data] != 0)
171+
buf->area[buf->data] = 0;
167172
return 1;
168173

169174
case SMP_T_BIN:

src/sample.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ static int c_int2str(struct sample *smp)
885885
*/
886886
int smp_dup(struct sample *smp)
887887
{
888-
struct buffer *trash;
888+
struct buffer *trash, *buf;
889889

890890
switch (smp->data.type) {
891891
case SMP_T_BOOL:
@@ -902,19 +902,17 @@ int smp_dup(struct sample *smp)
902902
__fallthrough;
903903

904904
case SMP_T_STR:
905-
trash = get_trash_chunk_sz(smp->data.u.str.data+1);
905+
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
906+
trash = get_trash_chunk_sz(buf->data+1);
906907
if (!trash)
907908
return 0;
908-
trash->data = smp->data.type == SMP_T_STR ?
909-
smp->data.u.str.data : smp->data.u.meth.str.data;
909+
trash->data = buf->data;
910910
if (trash->data > trash->size - 1)
911911
trash->data = trash->size - 1;
912912

913-
memcpy(trash->area, smp->data.type == SMP_T_STR ?
914-
smp->data.u.str.area : smp->data.u.meth.str.area,
915-
trash->data);
913+
memcpy(trash->area, buf->area, trash->data);
916914
trash->area[trash->data] = 0;
917-
smp->data.u.str = *trash;
915+
*buf = *trash;
918916
break;
919917

920918
case SMP_T_BIN:

0 commit comments

Comments
 (0)