falco icon indicating copy to clipboard operation
falco copied to clipboard

[BUG] The [not set] value is being output as a string in v1.3.0

Open bungoume opened this issue 1 year ago • 3 comments

Describe the problem When concatenating the not_set value with a string, it outputs the value '[not set]'. This value shouldn't be outputted originally.

Expected behavior

// @scope: recv
// @suite: print not_set as empty
sub test_recv {
    declare local var.NOTSET STRING;
    declare local var.message STRING;

    set var.message = var.NOTSET;
    assert.equal(var.message, "");

    set var.message = "output:" var.NOTSET;
    assert.equal(var.message, "output:");
}

This should pass, but in falco v1.3.0, it results in the following error.

    Assertion Error: Assertion error: expect=output:, actual=output:[not set]
    Actual Value: output:[not set]

    10|     set var.message = "output:" var.NOTSET;
    11|     assert.equal(var.message, "output:");
    12| }

Additional context I have prepared various test cases related to 'empty'. https://github.com/bungoume/falco-vcl-empty-test/blob/main/tests/empty.test.vcl

bungoume avatar Dec 25 '23 12:12 bungoume

Blocking this problem by VCL behavior https://fiddle.fastly.dev/fiddle/e9852716

ysugimoto avatar Dec 25 '23 13:12 ysugimoto

https://developer.fastly.com/reference/vcl/types/string/

Various functions and operators treat unset strings differently; some render them as the empty string, and some as "(null)". This handling is a property of the function (or operator), rather than a property of the STRING type. A not set value is converted to an empty string when assigned to a STRING variable

This is quite difficult...

Here is the test and understanding based on my own fiddle test results. https://fiddle.fastly.dev/fiddle/116ac5ce

sub test_recv {
    declare local var.NOTSET STRING;
    declare local var.message STRING;

    set req.http.MESSAGE = var.NOTSET;  # Looks like same process as `unset req.http.MESSAGE;`
    assert.is_notset(req.http.MESSAGE);

    set var.message = var.NOTSET;  # auto convert empty string
    assert.equal(var.message, "");

    set req.http.MESSAGE = "var:" var.NOTSET;  # render as `(null)`
    assert.equal(req.http.MESSAGE, "var:(null)");

    set var.message = "var:" var.NOTSET;  # render as ``(empty string)
    assert.equal(var.message, "var:");
}

bungoume avatar Dec 25 '23 15:12 bungoume

Understood, we will try to follow VCL's behavior.

ysugimoto avatar Dec 25 '23 16:12 ysugimoto