• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Strange Comparison Issue

New Here ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

Day 2 of testing CF 2021 and I'm puzzled by what seems to be another bug.  Consider the following:

 

<CFSet A='147.xxx.yyy.zzz'>
<CFOutput>
  #A#---<br>
  Left 4: #Left(A,4)#---<br>
  Left 4 eq: #iif(Left(A,4) eq '147.',DE('Yes'),DE('No'))#<br>
  Left 4 is: #iif(Left(A,4) is '147.',DE('Yes'),DE('No'))#<br>
  Left 4 equal: #iif(Left(A,4) equal '147.',DE('Yes'),DE('No'))#<br>
  Left 4 CFIf eq: <CFIf Left(A,4) eq '147.'>Yes<CFElse>No</CFIf><br>
  Mid dot: #iif(Mid(A,4,1) eq '.',DE('Yes'),DE('No'))#<br>
  Left 3 Compare: #iif(Left(A,3) eq '147',DE('Yes'),DE('No'))#<br>
  First Item in List: #iif(GetToken(A,1,'.') eq '147',DE('Yes'),DE('No'))#<br>
</CFOutput>

 

This outputs the following in CF 2021 (update 4):

 

147.xxx.yyy.zzz---
Left 4: 147.---
Left 4 eq: No
Left 4 is: No
Left 4 equal: No
Left 4 CFIf Compare: No
Mid dot: Yes
Left 3 Compare: Yes
First Item in List: Yes

 

But in CF 2016:

 

147.xxx.yyy.zzz---
Left 4: 147.---
Left 4 eq: Yes
Left 4 is: Yes
Left 4 equal: Yes
Left 4 CFIf eq: Yes
Mid dot: Yes
Left 3 Compare: Yes
First Item in List: Yes

 

Here's a CFFiddle of it .

 

Of course the solution is clear: just use GetToken and be done, but I don't want to have to review all the code before the upgrade to CF 2021.

 

Any thoughts?

 

Views

851

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

I use TryCF.com and it didn't like the use of the DE() function, so I rewrote it and used YesNoFormat() instead.

 

 

<cfset A = javacast("string", "147.xxx.yyy.zzz")>
<cfoutput><pre>
#A#---
Left 4: #Left(A,4)#---
Left 4 eq: #yesNoFormat(Left(A,4) eq "147.")#
Left 4 is: #yesNoFormat(Left(A,4) is "147.")#
Left 4 equal:  #yesNoFormat(Left(A,4) equal "147.")#
Left 4 CFIf eq: #yesNoFormat(Left(A,4) eq "147.")#
Mid dot: #yesNoFormat(Mid(A,4,1) eq ".")#
Left 3 Compare: #yesNoFormat(Left(A,3) eq "147")#
First Item in List: #yesNoFormat(GetToken(A,1,".") eq "147")#
</pre></cfoutput>

 

 

 

NOTE: Here's a gist in case this forum's ability to display a code preview ever becomes broken.
https://gist.github.com/JamoCA/876e577d3f69b516d0224b03f87f9c1d

 

Even when the original value is explicitely cast as a string (which I am required to do a lot), Adobe ColdFusion 2021 is still different than CF2016, CF2018 and Lucee 4.5 & 5. (NOTE: TryCF.com throws an error for the above code... not sure why.)

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

Using compare works, but it accepts 2 strings according to the spec. It's also true for an "is" comparison when explicitly casting "147." as a string.

Compare: #yesNoFormat(not compare(Left(A,4), "147."))#
Left 4 is/Cast: #yesNoFormat(Left(A,4) is javacast("string","147."))#

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 30, 2022 Jun 30, 2022

Copy link to clipboard

Copied

The code in my instance that's failing is actually not for a yes/no outcome, doing something like CFSet MyVar=MyVar&iif(failing equal test,DE('/somedir1'),DE('/somedir2')), but I was just trivializing the scenario.  Ultimately I believe it's the actual test that's bugged, which would present itself under many different scenarios (wherever an equal test is being performed, including YesNoFormat as you discovered.  Working around it is easy, but not knowing what the actual cause is and having to worry about 2mil+ lines of code is what worries me.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

My point regarding the usage of DE() was that it couldn't be used on TryCF.com due to security reasons.  Also, if all you want to do is output true/false, the YesNoFormat() function is easier to read and provides the same functionality.

I started porting some CFML to Lucee and have started using some ColdBox libraries in my ACF projects. I've been writing unit tests (using TestBox) and then running the tests on various versions of a CFML server (using CommandBox) to see what is different.  To deal with most ACF/Lucee/Java compatibility issues, I prefer to explicitely cast values to "string", "int" or use createDate/Time function so that CF doesn't have to guess the data type.

What is troubling is how completely backwards the results produced solely by CF2021 compared to all versions of other CFML processor.  It's not consistent.  (If there's a setting on the server that defaults to this behavior, it should probably be set opposite so that code not specifically written and tested in CF2021 will work as expected.) I recommend officially reporting this as a CF bug to see how they respond.  (If you do, share the bug ID and a link.)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

Filed bug.  CF-4214261 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

Thanks!  I've updated the GIST that I shared (it gets weirder), posted a comment in the bug tracker and shared on Twitter to get some input from other CFML community members.
https://twitter.com/gamesover/status/1542938151441666048

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

Thanks for following up with this James.  I'm not active at all in CF communities (Or Twitter, for that matter!) and appreciate the promotion, and I feel this bug definitely puts a hard stop on upgrading my clients' Coldfusion servers to 2021 until it's resolved, as there's no way to programatically search/replace for it in code or even find out where it applies.  I checked a couple of other bugs and noticed that Adobe provided a fix within a week or two for some of them, so I have my fingers crossed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

Guys, I can add something here. It's not "the solution", but it's a clue. One of the little-noticed changes in CF2021 was related to strict equality matching. The docs on it offer how if one WANTS to do a strict equality conditional test, there is a new === operators, which works in the fiddle even for your good ol' cfif, not just cfscript conditionals:

 

<CFIf Left(A,4) === '147.'>

 

 

And result WILL be true, while either eq (as you have it) or eq will be false. I'm not exactly sure I understand why this makes a difference, but perhaps someone else will connect a dot.

 

And of course, I realize you will not want to have to change your code to solve this. I mention this first more to help you (or anyone, or Adobe) perhaps connect the dot to what changed to make your test now fail. (It sure seems to have to do with the . in the number, so at least it's not "all" conditionals that will somehow just start activing wonky.)

 

And I would agree 100% that a change like this should have some sort of setting to allow you to revert the behavior, if you need it, whether that's a setting in the application.cfc/cfm or in the JVM. Let's see if someone might identify if one does exist.

 

Rather than add this comment to the tracker ticket (leading to cross-posting confusion, if people would reply to one and not the other), I will instead point there to this thread and mention briefly what I added here.

 

(BTW, here is one other place that Adobe discussed the new feature. It doesn't add much more on this feature--but some may be tickled to see the new cfscript savecontent capability also mentioned there.)


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

That's "CF2021/2018 only" syntax.  I prefer writing CFML that functions on CF2016.  (I can't even add TRY/CATCH to my test because using it it throws a parsing error when run on CF2016.)

Any thoughts regarding ACF2021 returns different results depending on whether a variable is used versus an inline value?

I understand the need for strict equality and I like that.  It's one of the primary versions that I explicitly cast values as you're never exactly sure what ColdFusion is identifying a string as under the hood.  The article doesn't mention "IS".  It mentions "EQ" and indicates that it the backward compatibility "equality operator was still comparing two objects by its values".

This behavior doesn't make any sense to me.  I would consider both values on the left to be the same regardless of whether one was staticly used while the other uses an assigned variable.

This isn't equal when using CF2021...
left("147.xxx", 4) is javacast("string", "147.")

But this is equal...
myVal = "147.xxx";
left(myVal, 4) is javacast("string", "147.")

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 01, 2022 Jul 01, 2022

Copy link to clipboard

Copied

James, first I was indeed talking about cf 2021 (only, not even 2018) since that's what Ross was dealing with. I saw your additional comments, and I appreciate your concern, but I was focused on Ross's original and primary problem.

 

And I agree, too (as I said) that even what I foumd both doesn't make sense and seems should be able to be controlled. I have no more to offer with regard to earlier cf versions. I realize it may surprise some to hear me say I don't have more to offer, but there are simply some cf topics where I don't have enough experience with them to even hazard a guess, and I'm OK acknowledging when that's so. 🙂 


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 02, 2022 Jul 02, 2022

Copy link to clipboard

Copied

Long story short: it is definitely a CF2021 bug. The bug has nothing to do with iif() or de(). 

 

It concerns just left(). The numeric nature of "147." seems to throw ColdFusion off the string scent.

 

Demo:

<cfset A="147.xxx.yyy.zzz">
<cfset B="abc.xxx.yyy.zzz">

<cfoutput>	
left(A,3) is "147":	 #left(A,3) is "147"#<br>
left(A,4) is "147.": #left(A,4) is "147."#<br><br>

left(B,3) is "abc":	 #left(B,3) is "abc"#<br>
left(B,4) is "abc.": #left(B,4) is "abc."#<br>
</cfoutput>

 

Output:

left(A,3) is "147": YES
left(A,4) is "147.": NO

left(B,3) is "abc": YES
left(B,4) is "abc.": YES

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 03, 2022 Jul 03, 2022

Copy link to clipboard

Copied

I consider compare(), mentioned by James Moberg, and its companion, compareNoCase(), to be the most hassle-free functions to use when comparing strings.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 03, 2022 Jul 03, 2022

Copy link to clipboard

Copied

There is a similar bug in the mid function. Ross N. has added a comment to this effect in the bug ticket.

 

Demo:

 

<cfset str1='147.xxx'>
<cfset str2='abc.xxx'>

<cfoutput>
str1 : "#str1#" <br>
mid(str1, 1, 4) : "#mid(str1, 1, 4)#" <br>
mid(str1, 1, 4) is "147." : #mid(str1, 1, 4) is "147."# <br><br>

str2 : "#str2#" <br>
mid(str2, 1, 4) : "#mid(str2, 1, 4)#" <br>
mid(str2, 1, 4) is "abc." : #mid(str2, 1, 4) is "abc."# 
</cfoutput>

 

 

Result:

str1 : "147.xxx"
mid(str1, 1, 4) : "147."
mid(str1, 1, 4) is "147." : NO

str2 : "abc.xxx"
mid(str2, 1, 4) : "abc."
mid(str2, 1, 4) is "abc." : YES

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 08, 2022 Jul 08, 2022

Copy link to clipboard

Copied

Adobe's Piyush K. has shared the following solution in the ticket CF-4214261 :

add the flag

-Dcoldfusion.number.allowdotsuffix=true

to CF2021's jvm.config 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 08, 2022 Jul 08, 2022

Copy link to clipboard

Copied

Piyush,

Please see the questions in the ticket you referenced.  If the issue raised here the only thing resolved by use of the flag?  Or will using the flag possibly affect other comparisons?

 

Thanks,

Ross.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 14, 2023 Feb 14, 2023

Copy link to clipboard

Copied

Just found this issue when testing before our official upgrade to CF2021, thanks for pointing it out.  While I appreciate that there's a JVM argument, I never saw a response from Adobe about if that would break anything internally.  I added a comment to the bug that was marked as duplicate:

I don't think it should be possible for === to be TRUE and == to be FALSE, === should be more strict than ==. This code demonstrates the problem:

<cfset ip = "50.5.3">

<cfoutput>

   #Left(ip,3) === "50."#

   #Left(ip,3) == "50."#

</cfoutput>

Results CF2021 u5: YES NO

Results CF2016 u15: YES YES

 

Is there a plan to fix this?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Feb 14, 2023 Feb 14, 2023

Copy link to clipboard

Copied

Are you specifically comparing the first value of an IP address using this method?  I recommend using listFirst(ip,".") eq 50 and avoid the use of "===". I prefer to write code that is readable, futureproof and cross-compatible with all CFML platforms & versions.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 14, 2023 Feb 14, 2023

Copy link to clipboard

Copied

LATEST

Agree, I changed the code and searched for other places this could happen, but I still think this is a bug that should be fixed by Adobe.  It just seems really wrong that === works and not == in this case, since === should be more strict by checking type and value.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation