]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: sample: Fix bytes() when length it greater than remaining data
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 20 Jul 2026 16:05:14 +0000 (18:05 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 21 Jul 2026 05:29:50 +0000 (07:29 +0200)
For bytes() converter, when the length parameter is greater than the
remaining data, no truncation on length must be performed. However, in that
case, nothing was performed at all. The changes because of the offset
parameter was just ignored.

Now, when the length value is too large, the sample data are moved
accordingly to the offset value as expected.

The coresponding reg-test was updated to test this case with a non-zero
offset. In addition the documentation was fixed to properly match what the
converter do. It was wrongly updated when the support of variables was
introduced in 2.9.

This patch must be backported as far as 3.0.

doc/configuration.txt
reg-tests/converter/bytes.vtc
src/sample.c

index 1efb97d5a793128e8b4b95f0da48378bdff4fd1e..8fbfe76b16eb4b993c048d13d1d2241c119eab8a 100644 (file)
@@ -21319,8 +21319,7 @@ bytes(<offset>[,<length>])
   optionally truncated at the given length. <offset> and <length> can be numeric
   values or variable names. The converter returns an empty sample if either
   <offset> or <length> is invalid. Invalid <offset> means a negative value or a
-  value >= length of the input sample. Invalid <length> means a negative value
-  or, in some cases, a value bigger than the length of the input sample.
+  value >= length of the input sample. Invalid <length> means a negative value.
 
   Example:
       http-request set-var(txn.input) req.hdr(input) # let's say input is "012345"
index c4a4889fdc6699e0e70771c35453c616ec29b76c..96c369bff8e4b392a4a7b3530558eab5b0a49956 100644 (file)
@@ -37,6 +37,7 @@ haproxy h1 -conf {
                http-response set-header bytes_6      "%[var(txn.input),bytes(6)]"
                http-response set-header bytes_0_6    "%[var(txn.input),bytes(0,6)]"
                http-response set-header bytes_0_7    "%[var(txn.input),bytes(0,7)]"
+               http-response set-header bytes_2_7    "%[var(txn.input),bytes(2,7)]"
 
                http-response set-var(txn.var_start) int(0)
                http-response set-header bytes_var0    "%[var(txn.input),bytes(txn.var_start)]"
@@ -52,6 +53,10 @@ haproxy h1 -conf {
                http-response set-var(txn.var_length) int(7)
                http-response set-header bytes_var0_var7    "%[var(txn.input),bytes(txn.var_start,txn.var_length)]"
 
+               http-response set-var(txn.var_start) int(2)
+               http-response set-var(txn.var_length) int(7)
+               http-response set-header bytes_var2_var7    "%[var(txn.input),bytes(txn.var_start,txn.var_length)]"
+
                http-response set-var(txn.var_start) int(1)
                http-response set-var(txn.var_length) int(3)
                http-response set-header bytes_var1_3   "%[var(txn.input),bytes(txn.var_start,3)]"
@@ -87,11 +92,13 @@ client c1 -connect ${h1_fe_sock} {
 
        # since specified length is > input length, response contains the input till the end
        expect resp.http.bytes_0_7 == "012345"
+       expect resp.http.bytes_2_7 == "2345"
 
        expect resp.http.bytes_var0 == "012345"
        expect resp.http.bytes_var1_var3 == "123"
        expect resp.http.bytes_var99 == ""
        expect resp.http.bytes_var0_var7 == "012345"
+       expect resp.http.bytes_var2_var7 == "2345"
        expect resp.http.bytes_var1_3 == "123"
        expect resp.http.bytes_1_var3 == "123"
        expect resp.http.bytes_varminus1 == ""
index b3dbd5ebcea606dab62f9f939035afc612a93e9e..5230db4a27284f2652f0317cb5bc00aefbd05256 100644 (file)
@@ -2977,14 +2977,12 @@ static int sample_conv_bytes(const struct arg *arg_p, struct sample *smp, void *
 
                if (smp_arg1.data.u.sint > (smp->data.u.str.data - start_idx)) {
                        // arg1 value is greater than the remaining length
-                       if (smp->opt & SMP_OPT_FINAL) {
-                               // truncate to remaining length
-                               length = smp->data.u.str.data - start_idx;
-                               goto end;
-                       }
-                       goto wait;
+                       if (!(smp->opt & SMP_OPT_FINAL))
+                               goto wait;
+                       // keep all remaining data
                }
-               length = smp_arg1.data.u.sint;
+               else
+                       length = smp_arg1.data.u.sint;
        }
 
        // update the output using the start_idx and length