Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad documentation about boolean value of strings #2846

Closed
CarloCannas opened this issue Nov 28, 2018 · 5 comments
Closed

Bad documentation about boolean value of strings #2846

CarloCannas opened this issue Nov 28, 2018 · 5 comments

Comments

@CarloCannas
Copy link
Contributor

Currently the documentation states:

String types will evaluate to false if they are empty

To me this means: empty strings (i.e. "") are casted to false in boolean context, which is not the actual behaviour.

A simple VTC showing this:

varnishtest "Truthy values"

server s1 {}

varnish v1 -vcl+backend {
        import std ;

        sub vcl_recv {
                if (!(
                        req.http.testa+req.http.testb && # two unset headers concatenated evaluate to true
                        "" &&                            # an empty string evaluates to true
                        !req.http.test &&                # an unset header evaluates to false
                        req.http.empty                   # an header set to an empty string evaluates to true
                )){
                        return (fail);
                }
                return (synth(200));
        }
} -start

client c1 {
        txreq -hdr "Empty: "
        rxresp
        expect resp.status == 200
} -run

I assume this is the intended behaviour, but the documentation is unclear/wrong.

I think that paragraph should be reworded to make clear that any string in a boolean context evaluate to true, even if empty, and that unset values evaluates to false.

I'm not sure if unset value is the right wording, what I mean with that is headers which have never been set or which have been unset.

@Dridi
Copy link
Member

Dridi commented Nov 28, 2018

I think we should really keep the current behavior for the if (req.http.empty) case for backwards compatibility reasons and because that allows us currently to tell whether at least one header field is present for a given name.

I'm in favor of a docfix, not against the idea of a VCL 4.2 where empty strings become falsy as long as we have a vmodless syntax to detect set headers.

@nigoroll
Copy link
Member

my vote goes to docfix like:

String types will evaluate to false if they are unset (NULL)

@Francois-v3
Copy link

Francois-v3 commented Nov 28, 2018 via email

@fgsch
Copy link
Member

fgsch commented Dec 2, 2018

There are 2 problems here:

  • A documentation issue
  • A bug in the code such as req.http.nonexistent0 + req.http.nonexistent1 return an empty string and not NULL.

Fixing the former is straight forward. For the latter I believe the diff below should do it but it might be difficult to implement as it might break existing installations:

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 0c28ba29e..7b2a09745 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -284,7 +284,7 @@ VRT_String(struct ws *ws, const char *h, const char *p, va_list ap)
 		if (q == vrt_magic_string_end) {
 			va_end(aq);
 			WS_Release(ws, 0);
-			return ("");
+			return (NULL);
 		}
 		do
 			p = va_arg(aq, const char *);
@@ -334,7 +334,7 @@ VRT_CollectString(VRT_CTX, const char *p, ...)
 	va_start(ap, p);
 	b = VRT_String(ctx->ws, NULL, p, ap);
 	va_end(ap);
-	if (b == NULL)
+	if (b == NULL && WS_Overflowed(ctx->ws))
 		VRT_fail(ctx, "Workspace overflow");
 	return (b);
 }

fgsch added a commit that referenced this issue Dec 2, 2018
Partially addresses #2846. I've avoided mentioning NULL on purpose as
it's not really meaningful nor accessible from VCL. ymmv.
@bsdphk
Copy link
Contributor

bsdphk commented Dec 3, 2018

Bugwash conclusion:

Docfix.

Our treatment of NULL is similar to how Python deals with unset values (None).

NULL + NULL returning "" is consistent with our "everything can be turned into a string" rule for VCL.

@bsdphk bsdphk closed this as completed in 7e9a318 Jan 14, 2019
Dridi pushed a commit that referenced this issue Feb 8, 2019
Partially addresses #2846. I've avoided mentioning NULL on purpose as
it's not really meaningful nor accessible from VCL. ymmv.
Dridi pushed a commit that referenced this issue Jun 27, 2019
hermunn pushed a commit to hermunn/varnish-cache that referenced this issue Nov 3, 2020
Partially addresses varnishcache#2846. I've avoided mentioning NULL on purpose as
it's not really meaningful nor accessible from VCL. ymmv.
hermunn pushed a commit to hermunn/varnish-cache that referenced this issue Nov 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants