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.
This commit is contained in:
Christopher Faulet 2026-04-09 21:00:00 +02:00
parent 265be7e8cb
commit b0a9216ca5
2 changed files with 18 additions and 15 deletions

View File

@ -101,6 +101,8 @@ struct sample *smp_set_owner(struct sample *smp, struct proxy *px,
static inline
int smp_is_safe(struct sample *smp)
{
struct buffer *buf;
switch (smp->data.type) {
case SMP_T_METH:
if (smp->data.u.meth.meth != HTTP_METH_OTHER)
@ -108,16 +110,17 @@ int smp_is_safe(struct sample *smp)
__fallthrough;
case SMP_T_STR:
if (!smp->data.u.str.size || smp->data.u.str.data >= smp->data.u.str.size)
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
if (!buf->size || buf->data >= buf->size)
return 0;
if (smp->data.u.str.area[smp->data.u.str.data] == 0)
if (buf->area[buf->data] == 0)
return 1;
if (smp->flags & SMP_F_CONST)
return 0;
smp->data.u.str.area[smp->data.u.str.data] = 0;
buf->area[buf->data] = 0;
return 1;
case SMP_T_BIN:
@ -148,6 +151,8 @@ int smp_make_safe(struct sample *smp)
static inline
int smp_is_rw(struct sample *smp)
{
struct buffer *buf;
if (smp->flags & SMP_F_CONST)
return 0;
@ -158,12 +163,12 @@ int smp_is_rw(struct sample *smp)
__fallthrough;
case SMP_T_STR:
if (!smp->data.u.str.size ||
smp->data.u.str.data >= smp->data.u.str.size)
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
if (!buf->size || buf->data >= buf->size)
return 0;
if (smp->data.u.str.area[smp->data.u.str.data] != 0)
smp->data.u.str.area[smp->data.u.str.data] = 0;
if (buf->area[buf->data] != 0)
buf->area[buf->data] = 0;
return 1;
case SMP_T_BIN:

View File

@ -885,7 +885,7 @@ static int c_int2str(struct sample *smp)
*/
int smp_dup(struct sample *smp)
{
struct buffer *trash;
struct buffer *trash, *buf;
switch (smp->data.type) {
case SMP_T_BOOL:
@ -902,19 +902,17 @@ int smp_dup(struct sample *smp)
__fallthrough;
case SMP_T_STR:
trash = get_trash_chunk_sz(smp->data.u.str.data+1);
buf = (smp->data.type == SMP_T_STR ? &smp->data.u.str : &smp->data.u.meth.str);
trash = get_trash_chunk_sz(buf->data+1);
if (!trash)
return 0;
trash->data = smp->data.type == SMP_T_STR ?
smp->data.u.str.data : smp->data.u.meth.str.data;
trash->data = buf->data;
if (trash->data > trash->size - 1)
trash->data = trash->size - 1;
memcpy(trash->area, smp->data.type == SMP_T_STR ?
smp->data.u.str.area : smp->data.u.meth.str.area,
trash->data);
memcpy(trash->area, buf->area, trash->data);
trash->area[trash->data] = 0;
smp->data.u.str = *trash;
*buf = *trash;
break;
case SMP_T_BIN: