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

var: var.get() of an unset variable is != "" #229

Open
delthas opened this issue Dec 4, 2024 · 0 comments
Open

var: var.get() of an unset variable is != "" #229

delthas opened this issue Dec 4, 2024 · 0 comments

Comments

@delthas
Copy link

delthas commented Dec 4, 2024

Hi,

Consider the following VTC, testing behavior of unset and empty variables:

varnishtest "Test var.get() truthiness and equality to the empty string"

server s1 {
       rxreq
       txresp
} -start

varnish v1 -vcl+backend {
	import std;
	import var from "${vmod_builddir}/.libs/libvmod_var.so";

	sub vcl_deliver {
		var.set("empty", "");
		if (var.get("empty")) {
			set resp.http.empty-truthy = "true";
		} else {
			set resp.http.empty-truthy = "false";
		}
		if (var.get("empty") == "") {
			set resp.http.empty-empty = "true";
		} else {
			set resp.http.empty-empty = "false";
		}
		if (var.get("unset")) {
			set resp.http.unset-truthy = "true";
		} else {
			set resp.http.unset-truthy = "false";
		}
		if (var.get("unset") == "") {
			set resp.http.unset-empty = "true";
		} else {
			set resp.http.unset-empty = "false";
		}
	}
} -start

client c1 {
	txreq -url "/"
	rxresp
	// Empty is truthy: ("String types will evaluate to false if they are unset.")
	expect resp.http.empty-truthy == "true"
	// Empty is empty:
	expect resp.http.empty-empty == "true"
	// Unset is not truthy: ("String types will evaluate to false if they are unset.")
	expect resp.http.unset-truthy == "false"
	// Unset is empty: ("if (req.http.opthdr == "") {} does not distinguish if the header does not exist or if it is empty.")
	expect resp.http.unset-empty == "true"

	// The last test above fails, because `resp.http.unset-empty` is actually "false", because `var.get("unset") == ""` returns false.
} -run

var.get("unset") == "" of an unset variable returns false, which is unintuitive given the VCL reference documentation:

String types will evaluate to false if they are unset. This allows checks of the type if (req.http.opthdr) {} to test if a header exists, even if it is empty, whereas if (req.http.opthdr == "") {} does not distinguish if the header does not exist or if it is empty.

The reference suggets that var.get("unset") == "" should return true (does not distinguish if the header does not exist or if it is empty). But it actually returns false.

This means that a user of libvmod-var that wishes to check a variable for "not empty" shouldn't do var.get("foo") != "" but actually var.get("foo") && var.get("foo") != "".

I suppose this cannot easily be fixed without "breaking" the API. Should this be documented?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant