[master] 0dfa3b8c9 vxp: Use strtod/strtoll consistently for number parsing for vsl (queries)
Nils Goroll
nils.goroll at uplex.de
Mon Jun 3 15:05:06 UTC 2024
commit 0dfa3b8c95f67054989a0e9259069e2f2433497a
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Mon Jun 3 14:24:52 2024 +0200
vxp: Use strtod/strtoll consistently for number parsing for vsl (queries)
Fixes #4088
diff --git a/bin/varnishtest/tests/r03463.vtc b/bin/varnishtest/tests/r03463.vtc
index 3d14ea9d0..efaaa644d 100644
--- a/bin/varnishtest/tests/r03463.vtc
+++ b/bin/varnishtest/tests/r03463.vtc
@@ -1,11 +1,11 @@
-varnishtest "VSL query lenient int comparisons"
+varnishtest "VSL query lenient int #3463 and float precision comparisons #4088"
varnish v1 -vcl {
import std;
backend be none;
sub vcl_recv {
if (req.http.skip != "log") {
- std.log("float1: 123.456");
+ std.log("float1: 123.4567");
std.log("float2: 123.");
std.log("float3: .456");
std.log("float4: 123");
@@ -37,6 +37,12 @@ logexpect l5 -v v1 -q "VCL_Log:float5 != 42 or ReqHeader:skip eq log" {
fail clear
} -start
+#4088
+logexpect l6 -v v1 -q "VCL_Log:float1 > 123.456" {
+ expect 0 1001 Begin rxreq
+} -start
+
+
client c1 {
txreq
rxresp
@@ -50,3 +56,4 @@ logexpect l2 -wait
logexpect l3 -wait
logexpect l4 -wait
logexpect l5 -wait
+logexpect l6 -wait
diff --git a/lib/libvarnishapi/vsl_query.c b/lib/libvarnishapi/vsl_query.c
index adcb77957..61f9f325c 100644
--- a/lib/libvarnishapi/vsl_query.c
+++ b/lib/libvarnishapi/vsl_query.c
@@ -122,8 +122,9 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
const struct vex_rhs *rhs;
long long lhs_int = 0;
double lhs_float = 0.;
- const char *b, *e, *q;
+ const char *b, *e;
int i, dq;
+ char *q = NULL;
AN(vex);
AN(rec);
@@ -205,20 +206,24 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
if (*b == '\0')
/* Empty string doesn't match */
return (0);
+ errno = 0;
switch (rhs->type) {
case VEX_INT:
- lhs_int = (long long)SF_Parse_Number(&b, 0, &q);
- if (errno)
+ lhs_int = strtoll(b, &q, 0);
+ AN(q);
+ if (q != e && *q != '.')
return (0);
break;
case VEX_FLOAT:
- lhs_float = SF_Parse_Decimal(&b, 0, &q);
- if (errno)
+ lhs_float = strtod(b, &q);
+ if (q != e)
return (0);
break;
default:
WRONG("Wrong RHS type");
}
+ if (errno != 0)
+ return (0);
break;
default:
break;
diff --git a/lib/libvarnishapi/vxp_parse.c b/lib/libvarnishapi/vxp_parse.c
index 94896837a..bfd162fa8 100644
--- a/lib/libvarnishapi/vxp_parse.c
+++ b/lib/libvarnishapi/vxp_parse.c
@@ -208,24 +208,21 @@ vxp_expr_num(struct vxp *vxp, struct vex_rhs **prhs, unsigned vxid)
AN(vxp->t->dec);
ALLOC_OBJ(*prhs, VEX_RHS_MAGIC);
AN(*prhs);
+ endptr = NULL;
if (strchr(vxp->t->dec, '.')) {
(*prhs)->type = VEX_FLOAT;
- (*prhs)->val_float = VNUM(vxp->t->dec);
- if (isnan((*prhs)->val_float)) {
- VSB_cat(vxp->sb, "Floating point parse error ");
- vxp_ErrWhere(vxp, vxp->t, -1);
- return;
- }
+ (*prhs)->val_float = strtod(vxp->t->dec, &endptr);
} else {
(*prhs)->type = VEX_INT;
(*prhs)->val_int = strtoll(vxp->t->dec, &endptr, 0);
- while (isspace(*endptr))
- endptr++;
- if (*endptr != '\0') {
- VSB_cat(vxp->sb, "Integer parse error ");
- vxp_ErrWhere(vxp, vxp->t, -1);
- return;
- }
+ }
+ while (isspace(*endptr))
+ endptr++;
+ if (*endptr != '\0') {
+ VSB_printf(vxp->sb, "%s parse error ",
+ (*prhs)->type == VEX_FLOAT ? "Floating point" : "Integer");
+ vxp_ErrWhere(vxp, vxp->t, -1);
+ return;
}
if (vxid && (*prhs)->type != VEX_INT) {
VSB_printf(vxp->sb, "Expected integer got '%.*s' ",
More information about the varnish-commit
mailing list