[master] d1799b8 VMOD blob: use a DEFAULT value for the case ENUM.
Geoff Simmons
geoff at uplex.de
Thu Sep 14 16:52:04 UTC 2017
commit d1799b8fee3d3d615229404b2ff131548dd561e2
Author: Geoff Simmons <geoff at uplex.de>
Date: Thu Sep 14 17:42:23 2017 +0200
VMOD blob: use a DEFAULT value for the case ENUM.
DEFAULT is interpreted as LOWER for the HEX and URL encodings, and
is the only legal value for all other encodings.
diff --git a/bin/varnishtest/tests/m00033.vtc b/bin/varnishtest/tests/m00033.vtc
index e4d963c..02d896d 100644
--- a/bin/varnishtest/tests/m00033.vtc
+++ b/bin/varnishtest/tests/m00033.vtc
@@ -54,13 +54,9 @@ varnish v1 -vcl {
blob.encode(IDENTITY,
blob=blob.decode(HEX, encoded="666f6f00626172"));
- set resp.http.lc =
- blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY,
- encoded="Don't care"));
-
- set resp.http.uc =
- blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY,
- encoded="Don't care"));
+ set resp.http.pos =
+ blob.encode(IDENTITY, DEFAULT, blob.decode(IDENTITY,
+ encoded="foobar"));
}
} -start
@@ -76,6 +72,52 @@ client c1 {
expect resp.http.param == "The quick brown fox jumps over the lazy dog"
expect resp.http.paramlist == "/The quick brown fox jumps over the lazy dog/"
expect resp.http.truncated == "foo"
- expect resp.http.lc == "Don't care"
- expect resp.http.uc == "Don't care"
+ expect resp.http.pos == "foobar"
} -run
+
+# Require case=DEFAULT
+
+server s1 -repeat 2 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import blob;
+
+ sub vcl_deliver {
+ if (req.url == "/lc") {
+ set resp.http.lc =
+ blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY,
+ encoded="foobar"));
+ }
+ elsif (req.url == "/uc") {
+ set resp.http.uc =
+ blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY,
+ encoded="foobar"));
+ }
+ }
+}
+
+client c1 {
+ txreq -url "/lc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.lc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/uc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.uc == <undef>
+} -run
+
+logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding IDENTITY$"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding IDENTITY$"
+} -start
+
+logexpect l1 -wait
diff --git a/bin/varnishtest/tests/m00037.vtc b/bin/varnishtest/tests/m00037.vtc
index 3209394..e545f1c 100644
--- a/bin/varnishtest/tests/m00037.vtc
+++ b/bin/varnishtest/tests/m00037.vtc
@@ -21,13 +21,9 @@ varnish v1 -vcl {
blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
req.http.pangram));
- set resp.http.b64lc =
- blob.encode(BASE64, LOWER, blob.decode(IDENTITY, encoded=
- req.http.pangram));
-
- set resp.http.b64uc =
- blob.encode(BASE64, UPPER, blob.decode(IDENTITY, encoded=
- req.http.pangram));
+ set resp.http.b64pos =
+ blob.encode(BASE64, DEFAULT, blob.decode(IDENTITY, encoded=
+ req.http.pangram));
set resp.http.b64hobbes =
blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
@@ -41,12 +37,8 @@ varnish v1 -vcl {
blob.encode(BASE64URL,
blob=blob.decode(IDENTITY, encoded=req.http.pangram));
- set resp.http.b64urllc =
- blob.encode(BASE64URL, LOWER,
- blob.decode(IDENTITY, encoded=req.http.pangram));
-
- set resp.http.b64urluc =
- blob.encode(BASE64URL, UPPER,
+ set resp.http.b64urlpos =
+ blob.encode(BASE64URL, DEFAULT,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urlhobbes =
@@ -61,12 +53,8 @@ varnish v1 -vcl {
blob.encode(BASE64URLNOPAD,
blob=blob.decode(IDENTITY, encoded=req.http.pangram));
- set resp.http.b64urlnopadlc =
- blob.encode(BASE64URLNOPAD, LOWER,
- blob.decode(IDENTITY, encoded=req.http.pangram));
-
- set resp.http.b64urlnopaduc =
- blob.encode(BASE64URLNOPAD, UPPER,
+ set resp.http.b64urlnopadpos =
+ blob.encode(BASE64URLNOPAD, DEFAULT,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64nopadhobbes =
@@ -87,15 +75,15 @@ varnish v1 -vcl {
set resp.http.b64param =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
- encoding=BASE64, case=LOWER);
+ encoding=BASE64, case=DEFAULT);
set resp.http.b64urlparam =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
- encoding=BASE64URL, case=UPPER);
+ encoding=BASE64URL, case=DEFAULT);
set resp.http.b64urlnopadparam =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
- encoding=BASE64URLNOPAD, case=LOWER);
+ encoding=BASE64URLNOPAD, case=DEFAULT);
set resp.http.b64xcode =
blob.transcode(IDENTITY, BASE64,
@@ -115,18 +103,15 @@ client c1 {
txreq -url "/"
rxresp
expect resp.http.b64 == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
- expect resp.http.b64lc == resp.http.b64
- expect resp.http.b64uc == resp.http.b64
+ expect resp.http.b64pos == resp.http.b64
expect resp.http.b64hobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
expect resp.http.b64all == "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA=="
expect resp.http.b64url == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
- expect resp.http.b64urllc == resp.http.b64url
- expect resp.http.b64urluc == resp.http.b64url
+ expect resp.http.b64urlpos == resp.http.b64url
expect resp.http.b64urlhobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
expect resp.http.b64urlall == "__79_Pv6-fj39vX08_Lx8O_u7ezr6uno5-bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL--vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI-OjYyLiomIh4aFhIOCgYB_fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA=="
expect resp.http.b64urlnopad == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
- expect resp.http.b64urlnopadlc == resp.http.b64urlnopad
- expect resp.http.b64urlnopaduc == resp.http.b64urlnopad
+ expect resp.http.b64urlnopadpos == resp.http.b64urlnopad
expect resp.http.b64nopadhobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4"
expect resp.http.b64nopadall == "__79_Pv6-fj39vX08_Lx8O_u7ezr6uno5-bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL--vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI-OjYyLiomIh4aFhIOCgYB_fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA"
expect resp.http.b64empty == ""
@@ -339,3 +324,102 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "././"$}
expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "TWFu"$}
} -run
+
+# Require case=DEFAULT
+
+server s1 -repeat 6 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import blob;
+
+ sub vcl_deliver {
+ if (req.url == "/b64lc") {
+ set resp.http.b64lc =
+ blob.encode(BASE64, LOWER, blob.decode(IDENTITY, encoded=""));
+ }
+ elsif (req.url == "/b64uc") {
+ set resp.http.b64uc =
+ blob.encode(BASE64, UPPER, blob.decode(IDENTITY, encoded=""));
+ }
+ elsif (req.url == "/b64urllc") {
+ set resp.http.b64urllc =
+ blob.encode(BASE64URL, LOWER, blob.decode(IDENTITY, encoded=""));
+ }
+ elsif (req.url == "/b64urluc") {
+ set resp.http.b64urluc =
+ blob.encode(BASE64URL, UPPER, blob.decode(IDENTITY, encoded=""));
+ }
+ elsif (req.url == "/b64urlnopadlc") {
+ set resp.http.b64urlnopadlc =
+ blob.encode(BASE64URLNOPAD, LOWER, blob.decode(IDENTITY,
+ encoded=""));
+ }
+ elsif (req.url == "/b64urlnopaduc") {
+ set resp.http.b64urlnopaduc =
+ blob.encode(BASE64URLNOPAD, UPPER, blob.decode(IDENTITY,
+ encoded=""));
+ }
+ }
+}
+
+client c1 {
+ txreq -url "/b64lc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64lc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64uc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64uc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urllc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urllc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urluc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urluc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urlnopadlc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urlnopadlc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urlnopaduc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urlnopaduc == <undef>
+} -run
+
+logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64"
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URL"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URL"
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URLNOPAD"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URLNOPAD"
+} -start
+
+logexpect l1 -wait
diff --git a/bin/varnishtest/tests/m00043.vtc b/bin/varnishtest/tests/m00043.vtc
index 7521255..9062314 100644
--- a/bin/varnishtest/tests/m00043.vtc
+++ b/bin/varnishtest/tests/m00043.vtc
@@ -1,9 +1,8 @@
varnishtest "VMOD blob blob object interface"
-server s1 {} -start
-
-varnish v1 -arg "-i serverid" -vcl+backend {
+varnish v1 -arg "-i serverid" -vcl {
import blob;
+ backend b { .host = "${bad_ip}"; }
sub vcl_init {
new id = blob.blob(IDENTITY,
@@ -93,8 +92,9 @@ client c1 {
# run twice to test retrieving cached encodings
client c1 -run
-varnish v1 -vcl+backend {
+varnish v1 -vcl {
import blob;
+ backend b { .host = "${bad_ip}"; }
sub vcl_init {
new idempty = blob.blob(IDENTITY, "");
@@ -165,8 +165,9 @@ client c1 {
# run twice to test retrieving cached encodings
client c1 -run
-varnish v1 -vcl+backend {
+varnish v1 -vcl {
import blob;
+ backend b { .host = "${bad_ip}"; }
sub vcl_init {
new b64 = blob.blob(BASE64, "L0hlbGxvIHdvcmxkLw==");
@@ -254,8 +255,9 @@ client c2 {
# run twice
client c2 -run
-varnish v1 -vcl+backend {
+varnish v1 -vcl {
import blob;
+ backend b { .host = "${bad_ip}"; }
sub vcl_init {
new id = blob.blob(IDENTITY,
@@ -332,6 +334,125 @@ client c3 -run
varnish v1 -cliok "vcl.discard vcl1"
varnish v1 -cliok "vcl.discard vcl2"
+# Require case=DEFAULT in the .encode() method where necessary
+
+server s1 -repeat 8 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import blob;
+
+ sub vcl_init {
+ new b = blob.blob(IDENTITY, "");
+ }
+
+ sub vcl_deliver {
+ if (req.url == "/idlc") {
+ set resp.http.idlc = b.encode(IDENTITY, LOWER);
+ }
+ elsif (req.url == "/iduc") {
+ set resp.http.iduc = b.encode(IDENTITY, UPPER);
+ }
+ if (req.url == "/b64lc") {
+ set resp.http.b64lc = b.encode(BASE64, LOWER);
+ }
+ elsif (req.url == "/b64uc") {
+ set resp.http.b64uc = b.encode(BASE64, UPPER);
+ }
+ elsif (req.url == "/b64urllc") {
+ set resp.http.b64urllc = b.encode(BASE64URL, LOWER);
+ }
+ elsif (req.url == "/b64urluc") {
+ set resp.http.b64urluc = b.encode(BASE64URL, UPPER);
+ }
+ elsif (req.url == "/b64urlnopadlc") {
+ set resp.http.b64urlnopadlc = b.encode(BASE64URLNOPAD, LOWER);
+ }
+ elsif (req.url == "/b64urlnopaduc") {
+ set resp.http.b64urlnopaduc = b.encode(BASE64URLNOPAD, UPPER);
+ }
+ }
+}
+
+client c1 {
+ txreq -url "/idlc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.idlc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/iduc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.iduc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64lc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64lc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64uc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64uc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urllc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urllc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urluc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urluc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urlnopadlc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urlnopadlc == <undef>
+} -run
+
+client c1 {
+ txreq -url "/b64urlnopaduc"
+ rxresp
+ expect resp.status == 503
+ expect resp.reason == "VCL failed"
+ expect resp.http.b64urlnopaduc == <undef>
+} -run
+
+logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding IDENTITY$"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding IDENTITY$"
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64$"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64$"
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URL$"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URL$"
+ expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URLNOPAD$"
+ expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URLNOPAD$"
+} -start
+
+logexpect l1 -wait
+
varnish v1 -errvcl {vmod blob error: cannot create blob err, illegal encoding beginning with "g"} {
import blob;
backend b { .host="${bad_ip}"; }
diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc
index 96dea4e..3b90d3a 100644
--- a/lib/libvmod_blob/vmod.vcc
+++ b/lib/libvmod_blob/vmod.vcc
@@ -94,16 +94,19 @@ Empty strings are decoded into a "null blob" (of length 0),
and conversely a null blob is encoded as the empty string.
For encodings with ``HEX`` or ``URL``, you may also specify a ``case``
-ENUM with one of the values ``LOWER`` or ``UPPER`` to produce a string
-with lower- or uppercase hex digits (in ``[a-f]`` or ``[A-F]``),
-respectively. The default value for ``case`` is ``LOWER``.
+ENUM with one of the values ``LOWER``, ``UPPER`` or ``DEFAULT`` to
+produce a string with lower- or uppercase hex digits (in ``[a-f]`` or
+``[A-F]``). The default value for ``case`` is ``DEFAULT``, which for
+``HEX`` and ``URL`` means the same as ``LOWER``.
The ``case`` ENUM is not relevant for decodings; ``HEX`` or ``URL``
strings to be decoded as BLOBs may have hex digits in either case, or
-in mixed case. The ``case`` ENUM is also ignored for all other
-encodings. You cannot, for example, produce an uppercase string by
-using the IDENTITY scheme with ``case=UPPER``. To change the case of a
-string, use the ``toupper`` or ``tolower`` functions from
+in mixed case.
+
+The ``case`` ENUM MUST be set to ``DEFAULT`` for the other encodings
+(BASE64* and IDENTITY). You cannot, for example, produce an uppercase
+string by using the IDENTITY scheme with ``case=UPPER``. To change the
+case of a string, use the ``toupper`` or ``tolower`` functions from
:ref:`vmod_std(3)`.
IDENTITY
@@ -133,7 +136,7 @@ be written as::
set resp.http.Trunced-Foo2
= blob.encode(blob=blob.decode(HEX, encoded="666f6f00626172"));
-The ``case`` ENUM is ignored for ``IDENTITY`` encodings.
+The ``case`` ENUM MUST be set to ``DEFAULT`` for ``IDENTITY`` encodings.
BASE64*
-------
@@ -155,16 +158,17 @@ The ``BASE64URLNOPAD`` encoding uses the same alphabet as
``BASE6URL``, but leaves out the padding. Thus the length of an
encoding with this scheme is not necessarily a mutltiple of four.
-The ``case`` ENUM is ignored for for all of the ``BASE64*`` encodings.
+The ``case`` ENUM MUST be set to ``DEFAULT`` for for all of the
+``BASE64*`` encodings.
HEX
---
The ``HEX`` encoding scheme converts hex strings into blobs and vice
versa. For encodings, you may use the ``case`` ENUM to specify upper-
-or lowercase hex digits ``A`` through ``f`` (default ``LOWER``). A
-prefix such as ``0x`` is not used for an encoding and is illegal for a
-decoding.
+or lowercase hex digits ``A`` through ``f`` (default ``DEFAULT``,
+which means the same as ``LOWER``). A prefix such as ``0x`` is not
+used for an encoding and is illegal for a decoding.
If a hex string to be decoded has an odd number of digits, it is
decoded as if a ``0`` is prepended to it; that is, the first digit is
@@ -214,13 +218,15 @@ Example::
$Function STRING encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} encoding="IDENTITY",
- ENUM {LOWER, UPPER} case="LOWER", BLOB blob)
+ ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT", BLOB blob)
Returns a string representation of the BLOB ``blob`` as specifed by
``encoding``. ``case`` determines the case of hex digits for the
``HEX`` and ``URL`` encodings, and is ignored for the other encodings.
-``encoding`` defaults to IDENTITY, and ``case`` defaults to LOWER.
+``encoding`` defaults to IDENTITY, and ``case`` defaults to DEFAULT.
+DEFAULT is interpreted as LOWER for the HEX and URL encodings, and is
+the required value for the other encodings.
Example::
@@ -242,8 +248,8 @@ $Function STRING transcode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} decoding="IDENTITY",
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} encoding="IDENTITY",
- ENUM {LOWER, UPPER} case="LOWER", INT length=0,
- STRING_LIST encoded)
+ ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT",
+ INT length=0, STRING_LIST encoded)
Translates from one encoding to another, by first decoding the string
``encoded`` according to the scheme ``decoding``, and then returning
@@ -256,7 +262,8 @@ As with ``decode()``: If ``length`` > 0, only decode the first
entire string. The default value of ``length`` is 0.
``decoding`` and ``encoding`` default to IDENTITY, and ``case``
-defaults to LOWER.
+defaults to DEFAULT. DEFAULT is interpreted as LOWER for the HEX and
+URL encodings, and is the required value for the other encodings.
Example::
@@ -343,12 +350,12 @@ Example::
$Method STRING .encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX,
URL} encoding="IDENTITY",
- ENUM {LOWER, UPPER} case="LOWER")
+ ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT")
Returns an encoding of BLOB created by the constructor, according to
the scheme ``encoding``. ``case`` determines the case of hex digits
-for the ``HEX`` and ``URL`` encodings, and is ignored for other
-encodings.
+for the ``HEX`` and ``URL`` encodings, and MUST be set to ``DEFAULT``
+for the other encodings.
Example::
@@ -378,10 +385,11 @@ not known until runtime.
ERRORS
======
-The encoders, decoders and ``sub()`` may fail if there is
-insufficient space to create the new blob or string. Decoders may also
-fail if the encoded string is an illegal format for the decoding
-scheme.
+The encoders, decoders and ``sub()`` may fail if there is insufficient
+space to create the new blob or string. Decoders may also fail if the
+encoded string is an illegal format for the decoding scheme. Encoders
+will fail for the ``IDENTITY`` and ``BASE64*`` encoding schemes if the
+``case`` ENUM is not set to ``DEFAULT``.
If any of the VMOD's methods, functions or constructor fail, then VCL
failure is invoked, just as if ``return(fail)`` had been called in the
diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c
index 7ded3a8..7e58db1 100644
--- a/lib/libvmod_blob/vmod_blob.c
+++ b/lib/libvmod_blob/vmod_blob.c
@@ -159,6 +159,9 @@ static inline enum case_e
parse_case(VCL_ENUM case_s)
{
switch(*case_s) {
+ case 'D':
+ AZ(strcmp(case_s + 1, "EFAULT"));
+ return DEFAULT;
case 'L':
AZ(strcmp(case_s + 1, "OWER"));
return LOWER;
@@ -170,6 +173,25 @@ parse_case(VCL_ENUM case_s)
}
}
+static inline int
+encodes_hex(enum encoding enc)
+{
+ return (enc == HEX || enc == URL);
+}
+
+/* Require case DEFAULT for all encodings besides HEX and URL. */
+
+static inline int
+check_enc_case(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, enum encoding enc,
+ enum case_e kase)
+{
+ if (!encodes_hex(enc) && kase != DEFAULT) {
+ VERR(ctx, "case %s is illegal with encoding %s", case_s, encs);
+ return 0;
+ }
+ return 1;
+}
+
/* Objects */
VCL_VOID __match_proto__(td_blob_blob__init)
@@ -250,8 +272,12 @@ vmod_blob_encode(VRT_CTX, struct vmod_blob_blob *b, VCL_ENUM encs,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(b, VMOD_BLOB_MAGIC);
+ if (!check_enc_case(ctx, encs, case_s, enc, kase))
+ return NULL;
if (b->blob.len == 0)
return "";
+ if (kase == DEFAULT)
+ kase = LOWER;
if (b->encoding[enc][kase] == NULL) {
AZ(pthread_mutex_lock(&b->lock));
@@ -396,7 +422,6 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b)
struct wb_s wb;
ssize_t len;
- CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AENC(enc);
if (b == NULL)
@@ -429,13 +454,11 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, VCL_BLOB b)
{
enum encoding enc = parse_encoding(encs);
enum case_e kase = parse_case(case_s);
- return encode(ctx, enc, kase, b);
-}
-static inline int
-encodes_hex(enum encoding enc)
-{
- return (enc == HEX || enc == URL);
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ if (!check_enc_case(ctx, encs, case_s, enc, kase))
+ return NULL;
+ return encode(ctx, enc, kase, b);
}
VCL_STRING __match_proto__(td_blob_transcode)
@@ -455,6 +478,9 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
AENC(dec);
AENC(enc);
+ if (!check_enc_case(ctx, encs, case_s, enc, kase))
+ return NULL;
+
/*
* Allocate space for the decoded blob on the stack
* ignoring the limitation imposed by n
diff --git a/lib/libvmod_blob/vmod_blob.h b/lib/libvmod_blob/vmod_blob.h
index 9cc1d45..04663e5 100644
--- a/lib/libvmod_blob/vmod_blob.h
+++ b/lib/libvmod_blob/vmod_blob.h
@@ -34,9 +34,14 @@
#define AENC(enc) assert((enc) > _INVALID && (enc) < __MAX_ENCODING)
+/*
+ * The enums MUST appear in this order, since LOWER and UPPER are used to
+ * index the array of cached encodings for the blob object.
+ */
enum case_e {
LOWER,
UPPER,
+ DEFAULT,
};
/*
More information about the varnish-commit
mailing list