ColdFusion 9:int和type=“numeric";讨厌的虫子? [英] ColdFusion 9: int and type="numeric" nasty bug?
问题描述
我刚刚经历了一种违反任何逻辑并可能导致严重问题的行为,我想知道 这是否是一个错误,或者该行为是否已解决,以及规避该问题的最佳做法是什么?如果是bug,有补丁吗?
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
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')>
这里,type="numeric"
参数验证(可能基于与 isValid
相同的算法?)不会与 '1 一起抛出2'代码>.更糟糕的是,
cfqueryparam cfsqltype="cf_sql_integer"
似乎正在使用 int
来转换最终将成为 41276
的值.
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
.
换句话说,deleteSomething('1 2')
将删除 id 为 41276
的实体,而不是因为值为 1 2而引发异常code> 显然不是数字.
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.
现在,我想到的唯一解决方法是使用 isValid('integer', ...
或正则表达式执行附加参数验证,但这是一个真正的痛苦,此外,我从来不明白为什么他们没有实现 type="integer"
?
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"
?
显然,我也总是错误地假设 cfqueryparam type="cf_sql_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.
似乎即使 isvalid('integer', ...
也不可靠,正如我们在
中看到的那样为什么 isvalid("integer","1,5") = YES?
It seems that even isvalid('integer', ...
is also not reliable as we can see in
Why isvalid("integer","1,5") = YES?
我知道我可以为每个函数中的每个预期整数参数添加额外的参数验证,但是在我的情况下这需要修复一个巨大的代码库,而且它也很容易出错.在这种情况下,它还使内置参数验证完全无用.
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.
它并不能解决所有问题,但 CF11 增加了对 strictNumberValidation 应用级配置.
It doesn't solves all the problems, but CF11 added support for a strictNumberValidation application level configuration.
"从 ColdFusion 11 开始,此函数在更严格的基础.将此值设置为 false 会使 isValid 函数以旧的方式行事.此设置影响 cfargument、cfparam 和cfform 标记无论在哪里整数 &使用数字验证.基于此设置,验证也反映在这些标签中."
"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."
推荐答案
这是另一个问题的主题变体.查看此代码(或在 cflive.net 上运行):
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
在调用 int()
以及将其用作 createOdbcDate()
的输入时转换为 41276
代码>,我们得到:
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
所以 "1 2"
被解释为 "m d"
,隐含的年份是当年.
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.
这篇关于ColdFusion 9:int和type=“numeric";讨厌的虫子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!