Thursday, 28 February 2013

Another serious struct-literal syntax balls-up in ColdFusion

G'day
Ray hit me up about this the other day, and I've only just been able to look at it now.  He's written a blog article about a bug someone mentioned to him, which they had raised on the bug tracker (3505517).

As far as the investigation had gone at the time, it seemed like a pretty edge-case sort of bug: if one has a CFC method call within a transaction block, and the method call used struct-literal notation for named argument values, then there was some execution duplication.

I've had a bit more of a look at it, and it's actually more far-reaching than we initially thought.


Here's a very pared-down repro case:

counter = 0;
    
if(true) {
    g();    // this statement is skipped
    f(arg1={key1="value 3"}); // only a problem with named args & struct-literal notation
}

function f(){
    writeDump({counter=++counter, arguments=arguments});
}

function g(){
    writeOutput("g() was executed");
}

This outputs:

struct
ARGUMENTS
struct
arg1
struct
KEY1value 3
COUNTER1
struct
ARGUMENTS
struct
arg1
struct
KEY1value 3
COUNTER2

HUH????

OK, things to note:
  1. I have tried this with transaction, try and if. They all do this. So it seems like all block-level statements cause this.
  2. The call to g() is skipped. This line can be any statement; it's skipped.
  3. Obviously the call to f() is duplicated.
What a mess.

[THE PENNY DROPS]

Oh! This is a nastier version of something I'd encountered before, and Brad Wood (he seems to be the star of my blog today!) repro-ed for me. It's already been raised as a bug: 3482734.

OK, well I've already discussed this once, so I'll shut-up. But I think it's good to have another variation of the repro case, and I think this version demonstrates it's even more serious than I had initially thought.

Good work to everyone who investigated this. Now, Adobe... Can you pls fix it? Cheers.

--
Adam