隐式操作数转换¶
ID: js/implicit-operand-conversion
Kind: problem
Security severity:
Severity: warning
Precision: very-high
Tags:
- reliability
- readability
- external/cwe/cwe-704
Query suites:
- javascript-security-and-quality.qls
在 JavaScript 中,大多数运算符可以应用于任意类型的操作数;在运行时,操作数将被隐式转换为适当的类型。例如,表达式p in obj
检查对象obj
是否包含名称等于p
计算结果的字符串的属性。如果p
没有计算为字符串或o
没有计算为对象,则在进行检查之前会执行隐式转换。
但是,在许多情况下,这些隐式转换是由于输入错误或对运算符优先级规则的误解而造成的。即使转换是故意的,依赖它们也会使代码难以理解。
建议¶
仔细检查表达式,以查看操作数是否输入错误,如果错误,请更正它们。如果转换是故意的,请考虑使用显式转换来替换它们,以澄清代码的含义。
示例¶
以下代码旨在检查对象obj
是否不包含存储在变量member
中的名称的属性
function invk(obj, member) {
if (!member in obj)
throw new Error("No such member: " + member);
return obj[member]();
}
但是,此测试按原样无效:运算符!
的绑定优先级高于in
,因此它首先被应用。将!
应用于非空字符串会产生false
,因此in
运算符实际上最终检查obj
是否包含名为"false"
的属性。
要解决此问题,应引入括号,如下所示
function invk(obj, member) {
if (!(member in obj))
throw new Error("No such member: " + member);
return obj[member]();
}
作为隐式转换的故意使用示例,请考虑以下用于比较两个数字x
和y
的函数。如果x>y
,则返回1
,如果x<y
,则返回-1
,如果它们相等,则返回0
。
function cmp(x, y) {
return (x > y) - (x < y);
}
直接写出来会更清楚
function cmp(x, y) {
if (x > y)
return 1;
if (x < y)
return -1;
return 0;
}
至少,布尔比较结果应被显式转换为数字
function cmp(x, y) {
return +(x > y) - +(x < y);
}
参考¶
Ecma 国际,ECMAScript 语言定义,5.1 版,第 9 节。ECMA,2011 年。
通用弱点枚举:CWE-704.