我刚刚经历过违反任何逻辑的行为,并可能导致严重的问题,并且想知道是否是一个错误,或者行为是否被认定以及绕过这个问题的最佳做法是什么?如果这是一个错误,是否有补丁?
这是两种奇怪的行为,当它们放在一起对任何系统的数据完整性构成威胁时。
int('1 2')
- > 41276
isValid('numeric', '1 2')
- > true
为什么呢?好吧,让我们看看......
<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
的值。
换句话说,deleteSomething('1 2')
将删除标识为41276
的实体,而不是抛出异常,因为值1 2
显然不是数字。
现在,我想到的唯一修复是使用isValid('integer', ...
或正则表达式执行额外的参数验证,但这是一个真正的痛苦,而且,我永远不明白为什么他们没有实现type="integer"
?
显然,我也总是假设cfqueryparam type="cf_sql_integer"
会验证传递的值是否为有效整数。
编辑:
似乎即使isvalid('integer', ...
也不可靠,我们可以在中看到
Why isvalid("integer","1,5") = YES?
EDIT2:
我知道我可以在每个函数中为每个预期的整数参数添加附加参数验证,但是这需要在我的情况下修复一个巨大的代码库,并且它也非常容易出错。在这种情况下,它还使内置参数验证完全无用。
我宁愿选择能够创建并应用非官方补丁的解决方案。这是一个现实的选择吗?如果是这样,我想指出正确的方向。
EDIT3:它没有解决所有问题,但CF11增加了对strictNumberValidation应用程序级配置的支持。
“从ColdFusion 11开始,此函数的评估更严格 基础。将此值设置为false会使isValid函数成为 表现得比较旧。此设置会影响cfargument,cfparam和 cfform标记整数&amp;使用数字验证。基于 此设置,验证也反映在这些标签中。“
答案 0 :(得分:2)
这是另一个问题的主题变体。请参阅此代码(或在cflive.net上运行):
<cfscript>
s = "1 2";
i = int(s);
v = isValid("numeric", s);
d = createOdbcDate(s);
writeDump([s,i,v,d]);
</cfscript>
在调用s
时, 41276
会转换为int()
,当我将其用作createOdbcDate()
的输入时,我们会得到:
January, 02 2013 00:00:00 +0000
所以"1 2"
被解释为"m d"
,其中隐含了当年的年份。
这完全是愚蠢的。但是你去了。
答案 1 :(得分:0)
您可以使用正则表达式来确定给定表单字段中是否存在任何非数字字符:
reFind( "[^\d-]", "1 2")
这将匹配任何不是数字的字符,而不是-
如果您只想检查正数,可以使用
reFind( "[^\d]", "1 2")
如果返回true
,则表示没有整数。