tracker issue : CF-3660491

select a category, or use search below
(searches all categories and all time range)

cfparam (and script param) improperly evaluates the default on each request

| View in Tracker

Status/Resolution/Reason: Closed/Deferred/HighRisk

Reporter/Name(from Bugbase): Steve Blades / Steve Blades (Steve Blades)

Created: 11/08/2013

Components: Language

Versions: 10.0

Failure Type:

Found In Build/Fixed In Build: Final /

Priority/Frequency: Major / All users will encounter

Locale/System: English / Platforms All

Vote Count: 1

Problem Description: When one used cfparam (or the scripted equivalent), the default value is evaluated on each instance, even if the variable already exists. This adds additional (and unnecessary) overhead to processing. For simple data types the effect is not extreme, but if you are trying to use a complex datatype, or an object instance, as the 'default', then it will slow down an application's overall performance.

Steps to Reproduce:

Expected Result:

param name="" default=CreateObject("component", "");

// This param should be like this 'under the covers'
if (!StructKeyExists(REQUEST, "foo") = CreateObject("component", "");

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	3660491

Deployment Phase:	Release Candidate

External Customer Info:
External Company:  
External Customer Name: CutterBl
External Customer Email:  
External Test Config: My Hardware and Environment details: Any



This can be extremely important within high traffic applications.
Comment by External U.
14018 | November 08, 2013 08:26:55 AM GMT
This has always been the case (rightly or wrongly). Expressions in tag attributes need to be evaluated before being passed to the underlying tag's implementation. <cfparam> doesn't process left-to-right, it processes "resolve CFML expressions in attribute values" -> pass results to tag. All tags work this way. So this is not just a matter of changing <cfparam>. param does the same thing for sideways-compat with <cfparam> If you don't want this behaviour: use if (structKeyExists()) etc -- Adam
Comment by External U.
14019 | December 10, 2013 11:06:15 AM GMT
-1 vote. It's working as designed / expected now. Should NOT be changed. -- Adam
Vote by External U.
14024 | December 10, 2013 11:06:53 AM GMT
Adam, I disagree. Though this may always have been the case, I do not think that it is the correct behavior. The param should say "Does this exist already? Is it valid? Then use it. If not, then create it in this image"
Comment by External U.
14020 | December 10, 2013 11:54:33 AM GMT
It does. The thing is the "this image" bit needs to be resolved before the tag is called. That's how CFML tags... *all of them*... work. Think of it like passing a value into a function. The args are resolved BEFORE the function code is called, so it doesn't matter if the function then conditionally uses the argument value... the expression to create the argument value has long since been executed. -- Adam
Comment by External U.
14021 | December 10, 2013 01:28:35 PM GMT
Though the behavior is wrong, CFParam is currently handled as any generic CF Tag and its behavior is similar, value for each key is evaluated and pushed to the tag's instance before it runs. It is a high risk fix and will consider it for the next release.
Comment by Chandan ..
14022 | January 17, 2014 09:12:10 AM GMT
I think the null-coalescing operator coming to CF11 will mitigate a lot of the issue here. -- Adam
Comment by External U.
14023 | January 17, 2014 09:19:14 AM GMT