vxp: Use strtod/strtoll consistently for number parsing for vsl (queries)

Fixes #4088
parent 41a1a42d
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
......@@ -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;
......
......@@ -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' ",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment