问题
I've just experienced a behaviour that defies any logic and could potentially lead to serious issues and was wondering if it was a bug or if the behaviour was itended and what are the best practices to circumvent the issue? If it's a bug, is there a patch?
Here's the two wierd behaviours that when put together are a threat to any system's data integrity.
int('1 2')
->41276
isValid('numeric', '1 2')
->true
Why? Well let's see...
<cffunction name="deleteSomething" access="public" returntype="void">
<cfargument name="somethingId" type="numeric" required="yes">
<cfquery datasource="#dsn()#">
DELETE
FROM Something
WHERE id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.somethingId#">;
</cfquery>
</cffunction>
<cfset deleteSomething('1 2')>
Here, the type="numeric"
arguments validation (which perhaps is based on the same algorithm as isValid
?) doesn't throw with '1 2'
. Even worse, cfqueryparam cfsqltype="cf_sql_integer"
seems to be using int
to convert the value which will end up being 41276
.
In other words, deleteSomething('1 2')
will delete the entity with id 41276
instead of throwing an exception since the value 1 2
is obviously not numeric.
Now, the only fix I thought of is to perform additionnal argument validation using isValid('integer', ...
or a regular expression, but that's a real pain and besides, I never understood why they haven't implemented type="integer"
?
Obviously, I also always made the false assumption that cfqueryparam type="cf_sql_integer"
would validate that the value passed is a valid integer.
EDIT:
It seems that even isvalid('integer', ...
is also not reliable as we can see in
Why isvalid("integer","1,5") = YES?
EDIT2:
I know that I could add additionnal arguments validation for every expected integer argument in every function, however that would require to fix a huge code base in my case and it's also very error-prone. It also makes the built-in argument validation completely useless in this case.
I would rather prefer a solution where I could create and apply an unofficial patch. Is that a realistic option? If so I would like to be pointed out in the right direction.
EDIT3: It doesn't solves all the problems, but CF11 added support for a strictNumberValidation application level configuration.
"Starting from ColdFusion 11, this function evaluates on a more strict basis. Setting this value to false makes the isValid function to behave in the older way. This setting effects cfargument, cfparam and cfform tags wherever integer & numeric validation is used. Based on this setting, the validation reflects in those tags as well."
回答1:
This is a variation on that theme from the other question. See this code (or run it on cflive.net):
<cfscript>
s = "1 2";
i = int(s);
v = isValid("numeric", s);
d = createOdbcDate(s);
writeDump([s,i,v,d]);
</cfscript>
s
converts to 41276
when calling int()
, and when using it as an input for createOdbcDate()
, we get:
January, 02 2013 00:00:00 +0000
So "1 2"
is being interpreted as "m d"
, with an implied year of the current year.
Which is utterly stupid. But there you go.
回答2:
You can use regular expressions to find out if there are any non numeric characters in a given form field:
reFind( "[^\d-]", "1 2")
That will match any character that is not a number, not a -
If you want to check only positive numbers, you can use
reFind( "[^\d]", "1 2")
If this returns true
, you do not have an integer.
来源:https://stackoverflow.com/questions/19140219/coldfusion-9-int-and-type-numeric-nasty-bug