[master] 2d39b0790 Collect VCL_DURATION type conversion in a single function and restrict acceptable whitespace to SP and TAB.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Jan 29 09:43:08 UTC 2019
commit 2d39b0790f523ef7e894bea38e26f0406b269a1b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Jan 29 08:56:34 2019 +0000
Collect VCL_DURATION type conversion in a single function and restrict
acceptable whitespace to SP and TAB.
Part of fix for #2882
diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc
index 1d1637f8c..a53bcc579 100644
--- a/bin/varnishtest/tests/v00016.vtc
+++ b/bin/varnishtest/tests/v00016.vtc
@@ -30,7 +30,7 @@ varnish v1 -errvcl {include not followed by string constant.} {
{ } ( ) * + - / % > < = ; ! & . | ~ ,
}
-varnish v1 -errvcl {Unknown time unit 'k'. Legal are 'ms', 's', 'm', 'h', 'd', 'w' and 'y'} {
+varnish v1 -errvcl {Unknown duration unit 'k'} {
backend b { .host = "127.0.0.1"; }
sub vcl_backend_response { set beresp.ttl = 1. k; }
}
diff --git a/include/vnum.h b/include/vnum.h
index 266f156f5..ae8a8e1f2 100644
--- a/include/vnum.h
+++ b/include/vnum.h
@@ -31,5 +31,9 @@
/* from libvarnish/vnum.c */
double VNUM(const char *p);
double VNUMpfx(const char *p, const char **e);
+vtim_dur VNUM_duration_unit(vtim_dur r, const char *b, const char *e);
vtim_dur VNUM_duration(const char *p);
const char *VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel);
+
+#define VNUM_LEGAL_DURATION \
+ "Legal duration units are 'ms', 's', 'm', 'h', 'd', 'w' and 'y'"
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index 271b13c43..026955a5e 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -51,7 +51,7 @@ binheap_CFLAGS = -DTEST_DRIVER
vnum_c_test_SOURCES = vnum.c vas.c
vnum_c_test_CFLAGS = -DNUM_C_TEST -include config.h
-vnum_c_test_LDADD = ${LIBM}
+vnum_c_test_LDADD = ${LIBM} libvarnish.a
vjsn_test_SOURCES = vjsn.c
vjsn_test_CFLAGS = -DVJSN_TEST @SAN_CFLAGS@
diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c
index 59e804ec8..99a81a8f5 100644
--- a/lib/libvarnish/vnum.c
+++ b/lib/libvarnish/vnum.c
@@ -30,14 +30,15 @@
#include "config.h"
-#include <ctype.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "vdef.h"
+#include "vct.h"
#include "vnum.h"
#include "vas.h"
@@ -61,14 +62,14 @@ VNUMpfx(const char *p, const char **t)
AN(p);
AN(t);
*t = NULL;
- while (isspace(*p))
+ while (vct_issp(*p))
p++;
if (*p == '-' || *p == '+')
ms = (*p++ == '-' ? -1.0 : 1.0);
for (; *p != '\0'; p++) {
- if (isdigit(*p)) {
+ if (vct_isdigit(*p)) {
m = m * 10. + *p - '0';
e = ne;
if (e)
@@ -84,12 +85,12 @@ VNUMpfx(const char *p, const char **t)
p++;
if (*p == '-' || *p == '+')
es = (*p++ == '-' ? -1.0 : 1.0);
- if (!isdigit(*p))
+ if (!vct_isdigit(*p))
return (nan(""));
- for (; isdigit(*p); p++)
+ for (; vct_isdigit(*p); p++)
ee = ee * 10. + *p - '0';
}
- while (isspace(*p))
+ while (vct_issp(*p))
p++;
if (*p != '\0')
*t = p;
@@ -111,31 +112,25 @@ VNUM(const char *p)
/**********************************************************************/
vtim_dur
-VNUM_duration(const char *p)
+VNUM_duration_unit(vtim_dur r, const char *b, const char *e)
{
- const char *t;
- vtim_dur r;
double sc = 1.0;
- if (p == NULL)
- return (nan(""));
-
- r = VNUMpfx(p, &t);
+ if (e == NULL)
+ e = strchr(b, '\0');
- if (isnan(r) || t == NULL)
+ while (b < e && vct_issp(*b))
+ b++;
+ if (b == e)
return (nan(""));
- while (isspace(*t))
- t++;
-
- // keep in sync with vcc_expr.c vcc_TimeUnit()
- switch (*t++) {
+ switch (*b++) {
case 's':
break;
case 'm':
- if (*t == 's') {
+ if (b < e && *b == 's') {
sc = 1e-3;
- t++;
+ b++;
} else
sc = 60.0;
break;
@@ -155,15 +150,32 @@ VNUM_duration(const char *p)
return (nan(""));
}
- while (isspace(*t))
- t++;
+ while (b < e && vct_issp(*b))
+ b++;
- if (*t != '\0')
+ if (b < e)
return (nan(""));
return (r * sc);
}
+vtim_dur
+VNUM_duration(const char *p)
+{
+ const char *t;
+ vtim_dur r;
+
+ if (p == NULL)
+ return (nan(""));
+
+ r = VNUMpfx(p, &t);
+
+ if (isnan(r) || t == NULL)
+ return (nan(""));
+
+ return (VNUM_duration_unit(r, t, NULL));
+}
+
/**********************************************************************/
const char *
diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am
index a2dd76bbc..a94efee04 100644
--- a/lib/libvarnishapi/Makefile.am
+++ b/lib/libvarnishapi/Makefile.am
@@ -20,6 +20,7 @@ libvarnishapi_la_SOURCES = \
../../include/vcs_version.h \
../libvarnish/version.c \
../libvarnish/vcli_proto.c \
+ ../libvarnish/vct.c \
../libvarnish/vfil.c \
../libvarnish/vfl.c \
../libvarnish/vin.c \
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 3a98c76e0..4e7e94c05 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -334,7 +334,7 @@ void Resolve_Sockaddr(struct vcc *tl, const char *host, const char *defport,
const struct token *t_err, const char *errid);
void Emit_UDS_Path(struct vcc *tl, const struct token *t_path,
const char *errid);
-double vcc_TimeUnit(struct vcc *);
+double vcc_DurationUnit(struct vcc *);
void vcc_ByteVal(struct vcc *, double *);
void vcc_Duration(struct vcc *tl, double *);
unsigned vcc_UintVal(struct vcc *tl);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 00b6ca700..1c1f659ad 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -838,7 +838,7 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
vcc_NextToken(tl);
if (tl->t->tok == ID) {
e1 = vcc_mk_expr(DURATION, "(%s%.*s) * %g",
- sign, PF(t), vcc_TimeUnit(tl));
+ sign, PF(t), vcc_DurationUnit(tl));
ERRCHK(tl);
} else if (fmt == REAL || t->tok == FNUM) {
e1 = vcc_mk_expr(REAL, "%s%.*s", sign, PF(t));
diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c
index f03762b34..abe4f69b5 100644
--- a/lib/libvcc/vcc_utils.c
+++ b/lib/libvcc/vcc_utils.c
@@ -40,6 +40,7 @@
#include "vcc_compile.h"
#include "vre.h"
+#include "vnum.h"
#include "vsa.h"
#include "vss.h"
#include "vtcp.h"
@@ -296,39 +297,25 @@ Emit_UDS_Path(struct vcc *tl, const struct token *t_path, const char *errid)
}
/*--------------------------------------------------------------------
- * Recognize and convert units of time, return seconds.
+ * Recognize and convert units of duration, return seconds.
*/
double
-vcc_TimeUnit(struct vcc *tl)
+vcc_DurationUnit(struct vcc *tl)
{
- double sc = 1.0;
+ double sc;
assert(tl->t->tok == ID);
- if (vcc_IdIs(tl->t, "ms"))
- sc = 1e-3;
- else if (vcc_IdIs(tl->t, "s"))
- sc = 1.0;
- else if (vcc_IdIs(tl->t, "m"))
- sc = 60.0;
- else if (vcc_IdIs(tl->t, "h"))
- sc = 60.0 * 60.0;
- else if (vcc_IdIs(tl->t, "d"))
- sc = 60.0 * 60.0 * 24.0;
- else if (vcc_IdIs(tl->t, "w"))
- sc = 60.0 * 60.0 * 24.0 * 7.0;
- else if (vcc_IdIs(tl->t, "y"))
- sc = 60.0 * 60.0 * 24.0 * 365.0;
- else {
- VSB_printf(tl->sb, "Unknown time unit ");
- vcc_ErrToken(tl, tl->t);
- VSB_printf(tl->sb,
- ". Legal are 'ms', 's', 'm', 'h', 'd', 'w' and 'y'\n");
- vcc_ErrWhere(tl, tl->t);
- return (1.0);
+ sc = VNUM_duration_unit(1.0, tl->t->b, tl->t->e);
+ if (!isnan(sc)) {
+ vcc_NextToken(tl);
+ return (sc);
}
- vcc_NextToken(tl);
- return (sc);
+ VSB_printf(tl->sb, "Unknown duration unit ");
+ vcc_ErrToken(tl, tl->t);
+ VSB_printf(tl->sb, "\n%s\n", VNUM_LEGAL_DURATION);
+ vcc_ErrWhere(tl, tl->t);
+ return (1.0);
}
/*--------------------------------------------------------------------
@@ -374,7 +361,7 @@ vcc_Duration(struct vcc *tl, double *d)
v = vcc_DoubleVal(tl);
ERRCHK(tl);
ExpectErr(tl, ID);
- sc = vcc_TimeUnit(tl);
+ sc = vcc_DurationUnit(tl);
*d = v * sc;
}
diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c
index ba10fa513..05c17495b 100644
--- a/lib/libvmod_std/vmod_std_conversions.c
+++ b/lib/libvmod_std/vmod_std_conversions.c
@@ -47,10 +47,10 @@
VCL_DURATION v_matchproto_(td_std_duration)
vmod_duration(VRT_CTX, VCL_STRING p, VCL_DURATION d)
{
- double r = VNUM_duration(p);
-
- (void) ctx;
+ double r;
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ r = VNUM_duration(p);
return (isnan(r) ? d : r);
}
More information about the varnish-commit
mailing list