mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
BUG/MINOR: sample: Fix bytes converter if offset is bigger than sample length
When the bytes converter was improved to be able to use variables (915e48675
["MEDIUM: sample: Enhances converter "bytes" to take variable names as
arguments"]), the behavior of the sample slightly change. A failure is
reported if the given offset is bigger than the sample length. Before, a
empty binary sample was returned.
This patch fixes the converter to restore the original behavior. The
function was also refactored to properly handle failures by removing
SMP_F_MAY_CHANGE flag. Because the converter now handles variables, the
conversion to an integer may fail. In this case SMP_F_MAY_CHANGE flag must
be removed to be sure the caller will not retry.
This patch should fix the issue #2335. No backport needed except if commit
above is backported.
This commit is contained in:
parent
a06f6212c9
commit
33a1fc883a
48
src/sample.c
48
src/sample.c
@ -2724,28 +2724,29 @@ static int sample_conv_bytes(const struct arg *arg_p, struct sample *smp, void *
|
|||||||
|
|
||||||
// determine the start_idx and length of the output
|
// determine the start_idx and length of the output
|
||||||
smp_set_owner(&smp_arg0, smp->px, smp->sess, smp->strm, smp->opt);
|
smp_set_owner(&smp_arg0, smp->px, smp->sess, smp->strm, smp->opt);
|
||||||
if (!sample_conv_var2smp_sint(&arg_p[0], &smp_arg0)) {
|
if (!sample_conv_var2smp_sint(&arg_p[0], &smp_arg0) || smp_arg0.data.u.sint < 0) {
|
||||||
smp->data.u.str.data = 0;
|
/* invalid or negative value */
|
||||||
return 0;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (smp_arg0.data.u.sint < 0 || (smp_arg0.data.u.sint >= smp->data.u.str.data)) {
|
|
||||||
// empty output if the arg0 value is negative or >= the input length
|
if (smp_arg0.data.u.sint >= smp->data.u.str.data) {
|
||||||
smp->data.u.str.data = 0;
|
// arg0 >= the input length
|
||||||
return 0;
|
if (smp->opt & SMP_OPT_FINAL) {
|
||||||
|
// empty output value on final smp
|
||||||
|
smp->data.u.str.data = 0;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
goto wait;
|
||||||
}
|
}
|
||||||
start_idx = smp_arg0.data.u.sint;
|
start_idx = smp_arg0.data.u.sint;
|
||||||
|
|
||||||
// length comes from arg1 if present, otherwise it's the remaining length
|
// length comes from arg1 if present, otherwise it's the remaining length
|
||||||
|
length = smp->data.u.str.data - start_idx;
|
||||||
if (arg_p[1].type != ARGT_STOP) {
|
if (arg_p[1].type != ARGT_STOP) {
|
||||||
smp_set_owner(&smp_arg1, smp->px, smp->sess, smp->strm, smp->opt);
|
smp_set_owner(&smp_arg1, smp->px, smp->sess, smp->strm, smp->opt);
|
||||||
if (!sample_conv_var2smp_sint(&arg_p[1], &smp_arg1)) {
|
if (!sample_conv_var2smp_sint(&arg_p[1], &smp_arg1) || smp_arg1.data.u.sint < 0) {
|
||||||
smp->data.u.str.data = 0;
|
// invalid or negative value
|
||||||
return 0;
|
goto fail;
|
||||||
}
|
|
||||||
if (smp_arg1.data.u.sint < 0) {
|
|
||||||
// empty output if the arg1 value is negative
|
|
||||||
smp->data.u.str.data = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smp_arg1.data.u.sint > (smp->data.u.str.data - start_idx)) {
|
if (smp_arg1.data.u.sint > (smp->data.u.str.data - start_idx)) {
|
||||||
@ -2753,22 +2754,25 @@ static int sample_conv_bytes(const struct arg *arg_p, struct sample *smp, void *
|
|||||||
if (smp->opt & SMP_OPT_FINAL) {
|
if (smp->opt & SMP_OPT_FINAL) {
|
||||||
// truncate to remaining length
|
// truncate to remaining length
|
||||||
length = smp->data.u.str.data - start_idx;
|
length = smp->data.u.str.data - start_idx;
|
||||||
} else {
|
goto end;
|
||||||
smp->data.u.str.data = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
goto wait;
|
||||||
length = smp_arg1.data.u.sint;
|
|
||||||
}
|
}
|
||||||
} else {
|
length = smp_arg1.data.u.sint;
|
||||||
length = smp->data.u.str.data - start_idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the output using the start_idx and length
|
// update the output using the start_idx and length
|
||||||
smp->data.u.str.area += start_idx;
|
smp->data.u.str.area += start_idx;
|
||||||
smp->data.u.str.data = length;
|
smp->data.u.str.data = length;
|
||||||
|
|
||||||
|
end:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
smp->flags &= ~SMP_F_MAY_CHANGE;
|
||||||
|
wait:
|
||||||
|
smp->data.u.str.data = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sample_conv_field_check(struct arg *args, struct sample_conv *conv,
|
static int sample_conv_field_check(struct arg *args, struct sample_conv *conv,
|
||||||
|
Loading…
Reference in New Issue
Block a user