tracker issue : CF-3993581

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

In CF11 (not 9) , structKeyExists() returns false when cfdump shows true. Which is it?

| View in Tracker

Status/Resolution/Reason: Closed/Won't Fix/

Reporter/Name(from Bugbase): Stephen Johnson / Stephen Johnson (Stephen Johnson)

Created: 05/22/2015

Components: Language

Versions: 11.0

Failure Type:

Found In Build/Fixed In Build: CF11_Final /

Priority/Frequency: Normal / All users will encounter

Locale/System: English / Win 2012 Server x64

Vote Count: 3

Problem Description: In CF11 and, I suspect, CF10, structKeyExists() returns false for a structkey generated via the deserializeJSON() function. CFDUMP, on the other, shows the key. The behavior occurs on structkeys where the corresponding value is null.

In bug fix 3043777, a bug fix corrected a problem where null values where incorrectly replaced with the string 'null' or so I interpret. Bug 3505249 also references this issue. While I agree that null going to 'null' was the wrong behavior there now seems to be the above side effect in CF11.

Steps to Reproduce:

I've attached the sandbox code. Please run in CF9 and CF11. Results will differ.

Actual Result:

StructKeys returned from deserializeJSON() with null values are not picked up as existing when structKeyExists() is applied to the resulting struct. CFDUMP, on the other hand, shows the key.

Expected Result:

In the example I provided, it depends on whether the deserialized JSON key truly is a key. Regardless of null being the value, I think it is. In any case, there needs to be consistency between CFDUMP and structKeyExists(). Right now there is not.

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

Watson Bug ID:	3993581

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



Server Details  

Server Product  ColdFusion  

Version  11,0,03,292480  

Edition  Developer    

Operating System  Windows Server 2012    

OS Version  6.2    

Adobe Driver Version  5.1.3 (Build 000094)

Attachments:

  1. May 23, 2015 00:00:00: 1_DeserializeJSONCF11.cfm

Comments:

Also note that when null is replaced with an empty string in the JSON, structKey come back to life. structKeyExists() returns true.
Comment by External U.
7329 | May 22, 2015 03:43:03 PM GMT
Putting on my Java hat here, my guess is that a struct key assigned to null is nothing more than a reference that doesn't point to anything. When it gets assigned a pointer in memory it suddenly comes alive. If that's the case, cfdump shouldn't see it as alive until it references an object. Either that, or deserializeJSON should throw an exception when null is passed as an explicit value.
Comment by External U.
7330 | May 22, 2015 03:59:26 PM GMT
So it seems that this has fallen into a black hole? 2 weeks and no response on a core run time issue?
Comment by External U.
7331 | June 04, 2015 02:13:06 PM GMT
Languor in dealing with nulls properly continues to confound the ColdFusion development community. If you deal with nulls properly, many of these issues go away!
Vote by External U.
7341 | June 16, 2016 08:43:00 AM GMT
structKeyExists() returns false for keys having NULL values because they currently have no useful values stored in them. While on the other hand CFDump/StructKeyArray/StructKeyList list those keys as well which have NULL values because, they can later be populated with some value by any function.
Comment by Nikhil S.
7332 | August 01, 2016 05:16:50 AM GMT
Nikhil, I don't think I agree with the premise of "structKeyExists() returns false for keys having NULL values because they currently have no useful values stored in them". The function's name implies it merely checks whether the key itself exists, not the nature of the value stored with the key. The workaround of having to run ListFind(StructKeyList(), "key") to see if the key exists in the list combined with StructKeyExists(myStruct, "key") returning false is an ugly hack. StructKeyExists() should just return true for *ANY* key that actually exists, regardless of whether it has a value assigned or not. IsNull(myStruct.key) is also broken, but I would expect it to return true for struct key's that have no value assigned.
Comment by External U.
7333 | August 03, 2016 12:58:17 PM GMT
Adobe's treatment of null, in general, is significantly broken and has been forever. That said, I'm in favor of fixing null once and for all, breaking backwards compatibility. Else the marketing ought to be 'CF2016... same wrong-think as ever!' structKeyExists() is improperly named if it doesn't return true if a key (not a value) does actually exist. The value is irrelevant - the key *does* exist. There are, frankly, too many good reasons to fix null, and only one excuse not to fix null... 'it'll break backwards compatibility'. Uh, yeah... and *that* my friends, is a good thing in this case. My 2 cents on the matter ;)
Comment by External U.
7334 | August 03, 2016 05:12:58 PM GMT
Voting primarily because this appears to be a regression in behavior. That said, also voting to fix null and break backwards compat.
Vote by External U.
7342 | August 03, 2016 05:14:10 PM GMT
I agree that there is a difference in behavior of cfdump/StructKeyList() and structKeyExists() and by name(structKeyExists) suggests that it should return true if the key exists even if the value is null. But this behavior of structKeyExists has been there since forever. Try this code on CF9: <cfscript> function returnnull() { } str = structNew(); str.exists = "exists"; str.doesntexist = returnnull(); writeOutput(structKeyExists(str, "doesntexist")); </cfscript> The result will be: NO but if you dump it, you will see the key. Even in blogs you will see people using structKeyExists in that manner since starting. Now coming to this particular bug where user has said that it used to work in CF9, reason for that is change in behavior of deSerialization. Earlier on deserializeJson we were converting null value to String null which is why structKeyExists returned Yes as it's value was String. But to counter that argument I will say that in same scenario try isDefined and isNull on that key. isDefined will give you Yes(in CF9) whereas it should give you No. After fixing in CF10, it started giving No. isNull will give you NO(in CF9) whereas it should give you Yes. After fixing in CF10, it started giving Yes. So should we change these behavior too? All in all, user's behavior is broken here because of change in deserializeJson behavior, in normal situation of null value structKeyExists is still behaving the same way. So as I said in starting, whether that's right behavior or not, it's been like this since ever. We should not fix this. @QE: can you please reverify my findings.
Comment by Milan C.
7335 | August 19, 2016 07:07:40 AM GMT
I noticed a user suggested to correct the behavior of NULL in ColdFusion altogether. If I am not wrong there are separate bugs to support NULL. And that's a part of bigger discussion and decision. This bug is merely based on StructKeyExists behavior in case of deserialization of struct with null values. So taking decision accordingly.
Comment by Milan C.
7336 | August 19, 2016 07:13:14 AM GMT
Sigh. "it's been like this since ever" is *not* a valid reason to *not* address the fact that structKeyExists() should have nothing to do with the *value* assigned to that key. Yes, there are blog posts demonstrating the behavior as it has been 'since ever'. jQuery, Node, Bootstrap, .NET, even Java itself all have blog posts about behaviors as they stood at the time of release that have since been changed, modified, made better. Modern developers understand that things change between versions of a language - and that the reasons they change is to make the language more usable. Why is it, then, that the Adobe CF dev team seem to be the only people on the planet who think leaving poorly designed crap in the language because 'it's been like this since ever' is a valid argument. It's not. It's lazy. Period.
Comment by External U.
7337 | August 19, 2016 08:43:20 AM GMT
A HUUUGGGGEEEEEE +1 to what Denard said below.
Comment by External U.
7338 | August 19, 2016 02:10:01 PM GMT
@Denard: Your point is valid. My first reaction to this bug was to just fix it. It is dumb for a structkeyexists function to check the value to determine if a key exists or not. We had a detailed discussion here to understand the impact of fixing this behavior now. It all came down to how we *do not* null in ColdFusion. Consider an application that is accepting JSON object from the client side with a null value assigned to one of the keys - which, as you can probably imagine, will be quite common a scenario to encounter. When this object is deserialized on the CF side, the struct continues to have a key with a value null. If there is existing code that is banking on structkeyexists to return false under this scenario, then I am sure you will agree that the logic of this application will go for a toss if we change the behavior of structkeyexists. The issue bubbles up to something larger than structkeyexists - it is ColdFusion's ability to deal with a null as null and not anything else. If the value is null, the value is plain null and it has got nothing to do with the key- this is clearly the right behavior and we understand it. Since this whole issue is bubbling up to the null support as a whole, all such scenarios and fixes will be made as a part of introducing null support for CF next. That will be right time for us to break this behavior and let our developers know that the change in behavior is because the key exists with the value being null. I completely understand the frustration here. We really want to fix this issue right. We will be tracking this issue via other bugs/enhancements that have been logged for adding null support in the next version of ColdFusion.
Comment by Rakshith N.
7339 | August 25, 2016 02:19:27 AM GMT
Closing this bug. The reasoning for the same has been provided by Rakshith in his note dated 25-Aug-16.
Comment by Vamseekrishna N.
7340 | September 09, 2016 03:30:19 AM GMT