12

Why does #isValid("integer","1,5")# output YES? I expected it to output NO like #isValid("integer","1.5")# does.

I'm going to validate with <CFIF isvalid("integer","1,5") AND isnumeric("1,5")> ...

Seybsen
  • 14,989
  • 4
  • 40
  • 73

4 Answers4

18

Adobe is aware of this, but...

State: Closed

Status: Withdrawn

Reason: AsDesigned

https://bugbase.adobe.com/index.cfm?event=bug&id=3169196

TBH I'm a little embarrassed to be using a language that can't even validate integer correctly.

UPDATE:

Guess what, it'll be addressed in CF12!

There is no doubt that this behavior is incorrect. It is obviously wrong and it should be corrected. However, it has been like this forever and making such a fundamental change has a great potential to break a lot of applications. We dont want to do that in this release. As Rakshith has already communicated, we plan to take up such changes in 'Dazzle' where we will correct the behavior without worrying about backward compatibility.

http://blog.adamcameron.me/2014/02/can-we-please-agree-that-adobe-is-not.html

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
Henry
  • 32,689
  • 19
  • 120
  • 221
  • 10
    I too am embarrassed - and blaming not fixing a cf8 bug for backwards compatibility reasons? Really? If the function is broken, people won't use it. Who's old code exactly are they trying to maintain? – Mike Causer Jul 18 '12 at 10:24
17

Just to expand on the answer here and explain what's actually going on.

See this related bug, a summary of the detail of which is that CF will interpret "m,n" (where m and n are digits) as a DATE if it possibly can. This is ludicrous: "m,n" is not a format that represents a date to anyone on the planet, so there is no reason for CF to ever interpret it this way.

Adobe copped-out of fixing this issue to, citing the same excuse that it would break backwards compat. Nonsense it would.

Anyway... because a date can be cast to an integer in CF, CF thinks "1,5" is a legit integer, because it's actually a date. How embrrassing it is - as a dedicated CF developer - to have to offer you than explanation. Sorry.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
  • 5
    Agreed. In a typeless language, it makes even *more* sense to have rock-solid type checking when you want/need it. – Sharondio Jul 18 '12 at 12:55
  • I bet Rupesh @ Adobe still uses IE6 – Mike Causer Jul 19 '12 at 00:08
  • Cf thinks the string '0,6' == '6,0'. I don't want to live on this planet anymore – Mike Causer Jul 19 '12 at 00:17
  • 1
    `'0,6' == '6,0'` TRUE... `'12,31' == '31,12'` TRUE... `'12,6' == '6,12'` FALSE... `'1,6' == '6,1'` FALSE... Oh god, why? – Mike Causer Jul 19 '12 at 01:33
  • 3
    I'm trying to gather some stats as to the community reaction to all this, which I will get to Adobe somehow. If poss, it'd be handy if you could have a look at this article that I knocked together (http://adamcameroncoldfusion.blogspot.co.uk/2012/07/according-to-06-60-and-both-are.html), and this survey (http://www.surveymonkey.com/s/JN5X8TS). – Adam Cameron Jul 19 '12 at 10:51
  • Found another bug... `'12a' + 0` == 0. `'12b' + 0` == throw "The value 12b cannot be converted to a number". `isNumeric( '12a' )` == false. What gives? – Mike Causer Aug 09 '12 at 12:15
  • If I had to guess I would sat 12a is being interpreted as 12am :-(. Not in front of a CF machine just now, so cannae test, sorry. – Adam Cameron Aug 10 '12 at 19:43
  • @AdamCameron What about this http://stackoverflow.com/questions/19140219/coldfusion-9-int-and-type-numeric-nasty-bug ? – plalx Oct 02 '13 at 15:27
10

If you want to make absolutely sure you have an Integer, you could use Java Integer methods.

<cfscript>
createObject("java","java.lang.Integer").parseInt("1,5");
</cfscript>

The parseInt() method throws when it is given anything that cannot be interpreted as an Integer. This includes "1,5".

Mike Causer
  • 8,196
  • 2
  • 43
  • 63
  • 1
    Nice! Thank you. But now I wonder if `isvalid("integer","1,5") AND isnumeric("1,5")` miss some cases which I did not consider where the input is not an integer. – Seybsen Jul 18 '12 at 10:46
  • Hmm, with an additional java object proxy and cftry/catch needed for checking if something's an integer? – Henry Jul 18 '12 at 16:45
  • Henry - yes, you'd need to wrap it with a try/catch. It's not a perfect solution by any means, but will ensure your value is an Integer. We tend to write java utility libraries for simple tasks like this and persist them in the application scope as createObject can get expensive. If you saw what was inside isValid() + isNumeric(), you probably would too :) – Mike Causer Jul 19 '12 at 00:06
  • 2
    I like `function isInteger(num) {return refind("^\d+$", num);}` better. :) – Henry Aug 02 '12 at 23:38
  • You could even leverage CF's duck typing everything to a string and use the java String matches. eg. `num.matches('\d+') ? num : 0;` which would default it to zero when not a sequence of numbers – Mike Causer Aug 09 '12 at 12:11
  • 1
    @Henry, nice one, I used the same with one minor addition, to allow for negative numbers too: `"^-?\d+$"` – duncan Sep 26 '13 at 10:50
  • `` returns true on integer value otherwise false – Abdul Rehman May 09 '16 at 11:37
  • Recommend adding some additional logic so that BigInts aren't considered valid Ints. `return refind("^-?\d+$", num) AND VAL(num) LTE 2147483647 AND VAL(num) GTE -2147483647` – James Moberg Dec 29 '16 at 23:51
1

Server side validation (only need the cfif logic, loop for example only)

<cfloop list="2.123,a,4" index="myVal">
    <cfif !isNumeric(myVal)> ...error code for not numeric<br />
    <cfelseif myVal neq int(myVal)> ...error code for not integer<br />
    <cfelse>is integer<br />
    </cfif>
</cfloop>

Tighter direct code:

<cfif !isNumeric(myVal) and myVal neq int(myVal)> ...error code for not integer<br />
</cfif>

You could write a cffunction as well

gordon
  • 1,152
  • 1
  • 12
  • 18