Friday 27 December 2013

Glitch in ColdFusion's CFML parser

G'day:
This is not what I was meaning to write about today, but hey.

I'm on the second leg of my trip to Galway: Central Line › Piccadilly Line (which today is taking on some of the District Line stations too, just - I think - to make my journey even more shit) › sit around at LHR drinking Guinness (or waiting in the security queue, depending on how busy it is... it'll be busy, I reckon) › fly to Shannon › bus to Galway › another bus to the bit of Galway I actually want to go to. This'll all take about 7h. Bleah. I'm catching a bus today because the rental car rates were insane this weekend. Instead of the usual £50 for two days, Hertz wanted close to £300 for three days. I cannot afford that. So I'm busing (€20) to Galway, and catching a cab (€100) back on Mon. Anyway, the point being I've got a lot of time sitting around, so I'm "investigating".

Right... I don't want this to become to blogs what CFHour is to podcasts (50% waffle before it gets going), so... erm... CFML stuff...

I happened across this code (or a facsimile thereof... this is a pared down example), which was giving me gyp in Railo, but not in ColdFusion 10:

throw(type="TestException" message="Test message" detail="Description (test)");

Railo is erroring with:
Railo 4.1.2.005 Error (template)
MessageInvalid Syntax Closing [)] for function [throw] not found
StacktraceThe Error Occurred in
C:\webroots\railo-express-win32\webapps\www\shared\git\blogExamples\coldfusion\bugs\noCommas\throw.cfm: line 2 
1: <cfscript>
2: throw(type="TestException" message="Test message" detail="Description (test)");
3: </cfscript>

"Naughty Railo!" I thought, guessing it must be getting confused by the parentheses in the description value.

But then I took the parenthetical bit out and it was still erroring.

Huh?

Then I paid attention. What's wrong with that code? Can you spot it?

It's a function call, and... the argument name/value pairs are not comma-separated. Erm... how does that compile?

Sure enough, I popped the commas back in as would be good and proper, and Railo was happy again:

throw(type="TestException", message="Test message", detail="Description (test)");

How the hell was ColdFusion compiling that? I already knew that ColdFusion handles this and writeLog() and writeDump() strangely as statements using those functions don't need semi-colons at the end (remember in ColdFusion, statements need to be terminated with a semi-colon; not so in Railo). But this was a new bit of weirdness to me.

I tested whether ColdFusion would compile calls to writeLog() and writeDump() without commas too:

writedump(var=["tahi", "rua", "toru", "wha", "rima", "ono"] label="1-4" top=4);

writeLog(file="testNoCommas" text="Testing writeLog() with no commas");
logData = fileRead(server.coldfusion.rootDir & "/logs/testNoCommas.log");
writeOutput("<pre>#logData#</pre>");

And, yes, those ones don't need commas either.

The thing these functions have in common is that they accept named arguments, not just ordered ones (why Adobe only implemented this for three functions and not the rest is completely beyond me), so I guess they have a different parsing routine for that syntax. And that parser is either more forgiving (being charitable) or buggy (being, I think, more likely).

I'll raise this as a bug when I get back online [later: now online, and the bug ref is 3688232].

I do not recommend using this syntax variation (or omitting the semi-colons), as it's not by intent. And in the case of the missing commas: not cross-compatible with Railo. Railo might not be on your roadmap currently,  but one never knows, so it's perhaps best not to go out of yer way to leverage a parsing glitch and introduce incompatible code into your code base.

And now... back to what I was actually meaning to be doing. The Piccadilly Line - which doesn't seem to want trains to go to LHR/T1 today, for some reason - has been struggling today: what should be a 1.5h trip is going to be 2h before I'm done. I've managed to get within three stops of LHR now though... hopefully a train to where I want to go fronts up shortly. This is cutting into my Guinness-drinking time!

--
Adam

Post Script:

I'm now sitting at Wetherpoons just before the gates for Ireland flights. It took me three different Piccadilly Line trains to get to LHR, which was a bit of a 'mare (in a "first world problem" sort of way). However once off the train, it was a breeze through security: there was no queue, indeed there were more staff than passengers. No-one has any idea why LHR/T1 is so quiet today. I scurried down here to the pub to get my Guinness, sat down, took a deep draught from my pint glass and noticed... my flight's been delayed. Only by an hour and a half (it's less than an hour in the air, this flight), so I have time to relax and have... more than one pint.

Also, my dramas with getting back from Galway to Shannon Airport have been resolved. I cannot get all the way to the airport from Galway on Monday, but I can get to Shannon Town easily enough. And it's only a 4km bus / cab / walk to the airport from there. If it's not raining, I'll just walk.

Phew.

PPS: Waffle-to-content ratio in this article is about 35%. Not great. Sorry.