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