Mailing List Archive

[master] d5bbb1a92 vsl: Tolerate float LHS with int RHS in queries
commit d5bbb1a92322232591f48cc491dc7d266cdcfa11
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date: Wed Jan 13 12:00:48 2021 +0100

vsl: Tolerate float LHS with int RHS in queries

Only if strtoll(3) stumbled upon a VNUM special character.

Fixes #3463

diff --git a/bin/varnishtest/tests/r03463.vtc b/bin/varnishtest/tests/r03463.vtc
new file mode 100644
index 000000000..9d0818e7f
--- /dev/null
+++ b/bin/varnishtest/tests/r03463.vtc
@@ -0,0 +1,52 @@
+varnishtest "VSL query lenient int comparisons"
+
+varnish v1 -vcl {
+ import std;
+ backend be none;
+ sub vcl_recv {
+ if (req.http.skip != "log") {
+ std.log("float1: 123.456");
+ std.log("float2: 123.");
+ std.log("float3: .456");
+ std.log("float4: 12.3e1");
+ std.log("float5: e1");
+ }
+ return (synth(200));
+ }
+} -start
+
+logexpect l1 -v v1 -q "VCL_Log:float1 >= 123" {
+ expect 0 1001 Begin rxreq
+} -start
+
+logexpect l2 -v v1 -q "VCL_Log:float2 <= 123" {
+ expect 0 1001 Begin rxreq
+} -start
+
+logexpect l3 -v v1 -q "VCL_Log:float3 == 0" {
+ expect 0 1001 Begin rxreq
+} -start
+
+logexpect l4 -v v1 -q "VCL_Log:float4 == 123" {
+ expect 0 1001 Begin rxreq
+} -start
+
+logexpect l5 -v v1 -q "VCL_Log:float5 != 42 or ReqHeader:skip eq log" {
+ fail add 1001 Begin rxreq
+ expect * 1002 Begin rxreq
+ fail clear
+} -start
+
+client c1 {
+ txreq
+ rxresp
+
+ txreq -hdr "skip: log"
+ rxresp
+} -run
+
+logexpect l1 -wait
+logexpect l2 -wait
+logexpect l3 -wait
+logexpect l4 -wait
+logexpect l5 -wait
diff --git a/doc/sphinx/reference/vsl-query.rst b/doc/sphinx/reference/vsl-query.rst
index 71534a4b0..6cfff6100 100644
--- a/doc/sphinx/reference/vsl-query.rst
+++ b/doc/sphinx/reference/vsl-query.rst
@@ -246,13 +246,15 @@ The following types of operands are available:

A number without any fractional part, valid for the numerical
comparison operators. The integer type is used when the operand does
- not contain any period (.) characters.
+ not contain any period (.) nor exponent (e) characters. However if
+ the record evaluates as a float, only its integral part is used for
+ the comparison.

* Float

A number with a fractional part, valid for the numerical comparison
operators. The float type is used when the operand does contain a
- period (.) character.
+ period (.) or exponent (e) character.

* String

@@ -329,7 +331,8 @@ QUERY EXPRESSION EXAMPLES
HISTORY
=======

-This document was written by Martin Blix Grydeland.
+This document was initially written by Martin Blix Grydeland and amended
+by others.


COPYRIGHT
diff --git a/lib/libvarnishapi/vsl_query.c b/lib/libvarnishapi/vsl_query.c
index eb08bf18a..b214a38da 100644
--- a/lib/libvarnishapi/vsl_query.c
+++ b/lib/libvarnishapi/vsl_query.c
@@ -122,7 +122,7 @@ 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, *q, *t;
char *p;
int i, dq;

@@ -209,6 +209,16 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
switch (rhs->type) {
case VEX_INT:
lhs_int = strtoll(b, &p, 0);
+ if (*p == '.' || *p == 'e') {
+ t = ""; /* assume valid float */
+ lhs_float = VNUMpfx(b, &q);
+ if (isnan(lhs_float))
+ return (0);
+ if (q != NULL)
+ t = (q > p) ? q - 1 : q;
+ p = TRUST_ME(t);
+ lhs_int = trunc(lhs_float);
+ }
if (*p != '\0' && !isspace(*p))
return (0); /* Can't parse - no match */
break;
_______________________________________________
varnish-commit mailing list
varnish-commit@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit