赋值给原始值属性¶
ID: js/property-assignment-on-primitive
Kind: problem
Security severity:
Severity: error
Precision: high
Tags:
- correctness
- language-features
- external/cwe/cwe-704
Query suites:
- javascript-security-and-quality.qls
在 JavaScript 中,数字和字符串之类的原始值是不可变的。通常情况下,将值赋予原始值的属性没有任何效果,而尝试使用 Object.defineProperty
操作此类属性会导致运行时错误。
有一个例外:将值赋予在相应原型对象(如 Number.prototype
或 String.prototype
)上定义了 setter 的属性将调用 setter 函数。
建议¶
仔细检查要赋值的操作。一个常见的错误是尝试通过将字符串视为字符数组并为其元素赋值来更改字符串的内容。由于字符串在 JavaScript 中是不可变的,因此这不会有任何效果。相反,应该使用字符串连接来创建一个新的字符串。
依赖于原型对象上的 setter 的赋值可能按预期工作,但这种行为很微妙且难以理解,因此应避免。
示例¶
以下代码片段尝试通过修改字符串 s
的字符来将字符串 s
填充到可被 8 整除的长度
for (var i=s.length; i%8; ++i)
s[i] = ' ';
这种方法行不通,因为字符串在 JavaScript 中是不可变的。相反,应使用字符串连接来填充字符串
for (var i=s.length; i%8; ++i)
s += ' ';
参考资料¶
Ecma International, ECMAScript 2016 语言规范,第 12.15 节:赋值运算符。
Ecma International, ECMAScript 2016 语言规范,第 19.1.2.4 节:Object.defineProperty。
通用弱点枚举:CWE-704。