[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