varnishtest "VMOD blob base64 decode() n chars"

varnish v1 -vcl {
	import blob;
	backend b { .host = "${bad_ip}"; }

	sub vcl_recv {
	  return(synth(200));
	}

	sub vcl_synth {
	    set req.http.foobarbazquux = "L0hlbGxvIHdvcmxkLw==";
	    set req.http.pangram
	      = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==";
	    set req.http.hobbes =
{"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="};
	    set req.http.hobbesnopad = regsuball(req.http.hobbes, "=", "");
	    set req.http.all =
{"AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz0000111122223333444455556666777788889999++++////"};
	    set req.http.allurl =
{"AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz0000111122223333444455556666777788889999----____"};

	    set resp.http.dec
	      = blob.encode(IDENTITY,
			    blob=blob.decode(BASE64, 8,
					     req.http.foobarbazquux));

	    set resp.http.deceq
	      = blob.encode(IDENTITY,
			    blob=blob.decode(BASE64, 20,
					     req.http.foobarbazquux));

	    set resp.http.declong
	      = blob.encode(IDENTITY,
			    blob=blob.decode(BASE64, 30,
					     req.http.foobarbazquux));

	    set resp.http.dec2
	      = blob.encode(IDENTITY,
			    blob=blob.decode(BASE64, 12, req.http.pangram));

	    set resp.http.b64dechobbes =
	      blob.encode(IDENTITY,
			  blob=blob.decode(BASE64, 24, req.http.hobbes));

	    set resp.http.b64decall =
	       blob.encode(HEX, blob=blob.decode(BASE64, 128, req.http.all));

	    set resp.http.urldechobbes =
	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, 180,
						     req.http.hobbes));

	    set resp.http.urldecall =
	      blob.encode(HEX, blob=blob.decode(BASE64URL, 256,
						req.http.allurl));

	    set resp.http.nopaddechobbes =
	      blob.encode(IDENTITY,
			      blob=blob.decode(BASE64URLNOPAD, 500,
					       req.http.hobbesnopad));

	    set resp.http.nopaddecall =
	      blob.encode(HEX, blob=blob.decode(BASE64URLNOPAD, 256,
						  req.http.allurl));

	    set resp.http.b64empty =
	      blob.encode(IDENTITY, blob=blob.decode(BASE64, 0, ""));
	    set resp.http.urlempty =
	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, 1, ""));
	    set resp.http.nopadempty =
		blob.encode(IDENTITY,
			    blob=blob.decode(BASE64URLNOPAD, 0, ""));
	    set resp.http.emptypieces =
	      blob.encode(IDENTITY,
	      blob=blob.decode(BASE64, 0, req.http.unset + "" + req.http.unset
					   + "" + req.http.unset + ""));

	    set resp.http.decenc
	      = blob.encode(BASE64,
			    blob=blob.decode(BASE64, 20,
					     req.http.foobarbazquux));

	    set resp.http.l = "L";
	    set resp.http.dec2pieces
	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 8,
				resp.http.l + "0hlbGxvIHdvcmxkLw=="));

	    set resp.http.pad = "==";
	    set resp.http.dec3pieces
	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 12,
				resp.http.l + "0hlbGxvIHdvcmxkLw"
				+ resp.http.pad));

	    set resp.http.mid1 = "GxvI";
	    set resp.http.mid2 = "dvcmx";
	    set resp.http.dec7pieces
	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 16,
				resp.http.l + "0hlb" + resp.http.mid1
				+ "H" + resp.http.mid2 + "kLw"
				+ resp.http.pad));

	    set resp.http.dec7param
	      = blob.encode(blob=blob.decode(encoded=resp.http.l
				+ "0hlb" + resp.http.mid1 + "H" + resp.http.mid2
				+ "kLw" + resp.http.pad, decoding=BASE64,
				length=20), encoding=IDENTITY);

	    set resp.http.decnopad = blob.encode(IDENTITY,
				     blob=blob.decode(BASE64URLNOPAD, 18,
						      "L0hlbGxvIHdvcmxkLw"));

	    set resp.http.decnopad2pieces
	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD, 19,
				resp.http.l + "0hlbGxvIHdvcmxkLw"));

	    set resp.http.decnopad6pieces
	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD, 18,
				resp.http.l + "0hlb" + resp.http.mid1
				+ "H" + resp.http.mid2 + "kLw"));

	    set resp.http.decnopadlong
	      = blob.encode(IDENTITY,
		blob=blob.decode(BASE64URLNOPAD, 60,
		"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
			       ));

	}
} -start

client c1 {
	txreq -url "/"
	rxresp
	expect resp.http.dec == "/Hello"
	expect resp.http.deceq == "/Hello world/"
	expect resp.http.declong == "/Hello world/"
	expect resp.http.dec2 == "The quick"
	expect resp.http.b64dechobbes == "Man is distinguish"
	expect resp.http.b64decall == "0000000410410820820c30c31041041451451861861c71c720820824924928a28a2cb2cb30c30c34d34d38e38e3cf3cf4104104514514924924d34d35145145555555965965d75d761861865965969a69a6db6db71c71c75d75d79e79e7df7df"
	expect resp.http.urldechobbes == "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a p"
	expect resp.http.urldecall == "0000000410410820820c30c31041041451451861861c71c720820824924928a28a2cb2cb30c30c34d34d38e38e3cf3cf4104104514514924924d34d35145145555555965965d75d761861865965969a69a6db6db71c71c75d75d79e79e7df7df8208208618618a28a28e38e39249249659659a69a69e79e7a28a28a69a69aaaaaaaebaebb2cb2cb6db6dbaebaebefbefc30c30c71c71cb2cb2cf3cf3d34d34d75d75db6db6df7df7e38e38e79e79ebaebaefbefbf3cf3cf7df7dfbefbeffffff"
	expect resp.http.nopaddechobbes == "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."
	expect resp.http.nopaddecall == "0000000410410820820c30c31041041451451861861c71c720820824924928a28a2cb2cb30c30c34d34d38e38e3cf3cf4104104514514924924d34d35145145555555965965d75d761861865965969a69a6db6db71c71c75d75d79e79e7df7df8208208618618a28a28e38e39249249659659a69a69e79e7a28a28a69a69aaaaaaaebaebb2cb2cb6db6dbaebaebefbefc30c30c71c71cb2cb2cf3cf3d34d34d75d75db6db6df7df7e38e38e79e79ebaebaefbefbf3cf3cf7df7dfbefbeffffff"
	expect resp.http.b64empty == ""
	expect resp.http.urlempty == ""
	expect resp.http.nopadempty == ""
	expect resp.http.emptypieces == ""
	expect resp.http.decenc == "L0hlbGxvIHdvcmxkLw=="
	expect resp.http.dec2pieces == "/Hello"
	expect resp.http.dec3pieces == "/Hello wo"
	expect resp.http.dec7pieces == "/Hello world"
	expect resp.http.dec7param == "/Hello world/"
	expect resp.http.decnopad == "/Hello world/"
	expect resp.http.decnopad2pieces == "/Hello world/"
	expect resp.http.decnopad6pieces == "/Hello world/"
	expect resp.http.decnopadlong == "The quick brown fox jumps over the lazy dog"
} -run

# Decode failures

server s1 -repeat 3 {
	rxreq
	txresp
} -start

varnish v1 -vcl+backend {
	import blob;

	sub vcl_deliver {
	  set req.http.foo = "AAA=";
	  if (req.url == "/base64") {
		set resp.http.bad64 = blob.encode(IDENTITY,
		    blob=blob.decode(BASE64, 8, "-_-_" + req.http.foo));
	  }
	  elsif (req.url == "/base64url") {
		set resp.http.badurl = blob.encode(IDENTITY,
		    blob=blob.decode(BASE64URL, 8, "+/+/" + req.http.foo));
	  }
	  elsif (req.url == "/base64urlnopad") {
		set resp.http.badpad = blob.encode(IDENTITY,
		    blob=blob.decode(BASE64URLNOPAD, 8,
				     "TWFu" + req.http.foo));
	  }
	}
}

client c1 {
	txreq -url /base64
	rxresp
	expect resp.status == 503
	expect resp.reason == "VCL failed"
	expect resp.http.bad64 == <undef>
} -run

logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
	expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "-_-_"$}
} -start

logexpect l1 -wait

client c1 {
	txreq -url /base64url
	rxresp
	expect resp.status == 503
	expect resp.reason == "VCL failed"
	expect resp.http.badurl == <undef>
} -run

logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
	expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "././"$}
} -start

logexpect l1 -wait

client c1 {
	txreq -url /base64urlnopad
	rxresp
	expect resp.status == 503
	expect resp.reason == "VCL failed"
	expect resp.http.badpad == <undef>
} -run

logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
	expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "TWFu"$}
} -start

logexpect l1 -wait
