Friday 19 February 2016

ColdFusion 2016: critical regression in scoping

G'day:
Thanks to Mingo Hagen for inspiring me today. He brought this to my attention on the CFML Slack channel (all the more reason to subscribe to that, btw... to catch stuff like this).

ColdFusion 2016 has introduced a serious regression bug when it comes to unscoped references in functions.

Update (2016-07-23)

See Wil's comment below. He's confirmed this is fixed in ColdFusion 2016, Update 2. Cheers for letting us know about this, Wil.
Here's the repro:

function foo(bar) {
    bar = "test";
    try {
        writeOutput("arguments scope");
        writeDump(var=[arguments.bar]);
    } catch (any e){
        writeDump({message=e.message});
    }
    try {
        writeOutput("local scope");
        writeDump(var=[local.bar]);
    } catch (any e){
        writeDump({message=e.message});
    }
    try {
        writeOutput("no scope");
        writeDump(var=[bar]);
    } catch (any e){
        writeDump({message=e.message});
    }
    try {
        writeOutput("variables scope");
        writeDump(var=[variables.bar]);
    } catch (any e){
        writeDump({message=e.message});
    }
}

writeOutput("Test with no arg passed:<br>");
foo();

writeOutput("<hr>Test with arg value passed:<br>");
foo("arg value");

The conceit here is that we are assigning an un-scoped variable a value within the function.

On previous versions of ColdFusion (and Lucee/Railo) we get this:



So CF successfully notices that the unscoped bar is a reference to bar argument, and assigns it appropriately. And the behaviour is uniform irrespective of whether we pass a value for the bar argument or not. This is correct.

On ColdFusion 2016, we get this instead:





Here ColdFusion isn't bothering to do a scope look-up to see if the unscoped variable already exists in a scope, it just goes "unscoped = variables scope". Which, in a function, is wrong.

This is a pretty serious bug. All the more reason to give ColdFusion 2016 a swerve at least for the time being (if not permanently, because it's just not worth the hassle given the lack of any real gain one would get from "upgrading" to it).

Mingo's not raised a ticket for this yet, but I'll cross-ref once he has. It's 4119653.

Righto.

--
Adam