]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: samples: Fix handling of SMP_T_METH samples
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Apr 2026 19:00:00 +0000 (21:00 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Apr 2026 20:05:12 +0000 (22:05 +0200)
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.

include/haproxy/sample.h
src/sample.c

index d60d0077c3dffb49ac9f2b38234892b18da63529..96ae06757b475adcea3625014873f74b51b74ada 100644 (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:
index 42f211ad4af653f5bffb820026f32477142cf8d9..22172a33fe707746ba36aaa81e6b7431941e405e 100644 (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: