As part of our upgrade to CF9, we started doing regression testing on our local boxes. My co-worker Joseph Lamoree found and blogged about a flaw he found in CF9 that brought our app to a halt. Serious, no joke.
Here is the issue in some detail. If you want to take a look at a MXUnit Test Case, then head over to Joseph's blog on Posterous for more details as well.
I have two files, local.cfm and local.cfc.
Local.cfm has the following:
Local.cfc has the following:
When running this on CF8, I get the following output:
When running this on CF9, I get the following output:
First off, CF9 is killing firstName and lastName. It seems when setting local to a Struct return from a function to start off, those values are quickly killed.
Why is this a big issue? Well, in frameworks like Mach II, you can start with:
What we see is that we have to do a structAppend, appending local to the values we want from the function...
Seems to me that any cfset local = is being ignored more or less. That is why:
If you dump this, it behaves like the 2nd line never happened. It shows the value for local.x. But this way, any function call to set values to local also get ignored. I think if the programming ignored the structNew(), but "appended" values from other functions instead of ignoring, this would everyone happy.


Oct 30, 2009 at 1:02 PM This line: <cfset var local = getProperties() /> is ignored in CF9 adobe did this on purpose as to not break code such as <cfset var local = {} /> and ( which would have created locol.local ) I believe this is mentioned somewhere in the docs. local exists explicitly as a scope in all methods for the cfc.
I'd have to look hard to find where this is explicitly documented though but I know Adobe choose this as the best fit for compatibility.
Oct 30, 2009 at 1:20 PM Also for the syntax highlighter try use: <textarea class="cf" cols="60" name="code" rows="3"> rather then <pre /> and it should stop messing up the code.
Oct 30, 2009 at 2:21 PM Paul,
I think the matter is bigger than just local.local. Ignoring the setting of a variable named local to an empty struct is one thing, ignoring/removing values set to local is another. If we changed all our code to do a structAppend that would work, but it would be a lot of work. I'm hoping Adobe can do appends for us, instead of breaking code the way it is.
As for highlighting, yeah I'm going to upgrade the script to Syntax Highlighter 2.0. Too bad there isnt a MangoBlog plugin for this.
Oct 30, 2009 at 4:28 PM Did you try my Mango plugin for SyntaxHighlighter?
http://objectivebias.com/blog/entry/syntaxhighlighter-mango-plugin
Oct 30, 2009 at 4:43 PM Ok, I think the code looks better. Almost there.
@Tony,
Yeah, I had seen that plugin, unfortunately I wanted to support version 2.0 of syntaxhighlighter, which support not having to convert < > to ascii equivalents.
Oct 30, 2009 at 8:20 PM Sami,
While I see your point and I agree it will now break code I was just pointing out that Adobe choose to do this.
As local is now a scope not just a variable should this "new" way be correct and code be forced to change or should they make it backwards compatible. I'd also like to see the results of this test in Railo and OpenBD to see what the alternative engines do.
So just to be clear CF9 is not actually killing firstName and lastName it's actually not executing this line: <cfset var local = getProperties() />
Oct 30, 2009 at 9:08 PM Paul,
From what I remember, in a private mailing list, Adobe had said they had done everything to be compatible. Obviously, this turned out to be false.
As for "not executing"... that's the problem. If a server starts ignoring your code, you might as well not trust it.
Oct 31, 2009 at 2:05 AM You can't assign a struct directly to a scope or call StructNew() on a scope (the call will just be ignored, but perhaps it should have always thrown a runtime error instead?), and since "local" is now a scope it has to obey those rules. This is an unfortunate backwards compatibility issue but I don't think it would have been possible to avoid unless those two rules were changed, which then makes CF9 behave differently in regard to scopes than previous engines.
So the workaround for those two things are;
- if you want to clear a scope (as always, be careful when doing so) call StructClear()
- if you want to insert the keys of a struct into a scope call StructAppend()
Side note: Does the CF9 code scanner check for this issue? I'm sure they wouldn't have forgotten it, it's a fairly big thing to introduce a scope that will potentially break existing code.
Nov 1, 2009 at 10:21 PM This has come up in a few open source projects. Datafaucet was recently updated for this flaw, and I believe ColdDoc has the same issue as well. Anyone moving to CF 9 should check their code for var scoped structures named 'local'.
Nov 2, 2009 at 1:58 PM Everyone seems to have forgotten that
<cfset var local = something />
Is actually not stored in the local scope, I ran some serious tests in the debugger, and tried to explain this on my blog.
The point is that it is not at this point using the local scope, and the fact that it has a var keyword in front of it is telling ColdFusion that it is not the local scope.
The problem is that if you call a function on that same line to return a struct, it is not called. That is a bug and should be reported as such.
I think the major problem later in my tests also indicates the search order of the scopes as well.
And as far as Adobe saying well we know this will break some code is bullshit.
Adobe had a discussion on Dump(); and Abort(); as script but becuase it would break existing code they chose to give them a new name and the other as a statement rather than a function.
So if Adobe are to be listened to about backward compatability, why do they do one thing with one hand and the complete opposite with the other?
This local scope and variable local is a major issue that Adobe have taken the easy way out, it is a bug and that needs to be fixed because of the amount of applications that use it.
So far my applications still work, but that is because I actually use
<cfset var local = {} />
<cfset local.something = '' />
but there are applications that I have seen that have refactored in the manner that I have blogged about, this is deliberate by Adobe and shows that they are willing to release code that is not backward compatible, so why is this one an exception to the rule Adobe try to live by?
Nov 9, 2009 at 6:59 AM I posted your blog to my facebook group
Regards
Courtney
Nov 23, 2009 at 12:25 PM Just received word this bug has been fixed from Adobe. Will be available in Updater 1. Thanks folks for voting!
Dec 17, 2009 at 8:20 PM I am to submit a report on this niche your post has been very very helpfull
Regards