Suspicious type coercion should be avoided
- BAD_TYPE_COERCION
- Error
- Medium
- cwe
This rule applies when suspicious type coercion occurs.
JavaScript utilizes implicit type conversion widely, so a programmer needs to check type conversion with caution.
The following is suspicious implicit type conversion for X:
X is converted to string.
- X + string (X is undefined or symbol.)
X is converted to number.
- X + undefined/null/boolean/number/symbol (X is undefined, null, or symbol.)
- X @ <All types> (X is undefined/null/non-numeric string/symbol/object. @ means -, *, /, %, **.)
- X @ Y (X is undefined/null/boolean/non-numeric string/symbol except for the case where X and Y are both strings. @ means <, <=, >, >=.)
- X @ number (X is object. @ means <, <=, >, >=.)
- X & <All types> (X is undefined/null/boolean/non-numeric string/symbol/object.)
- X | boolean (X is boolean.)
- X | Y (X is symbol.)
- X @ Y (X is boolean and Y is number/string/object. Or X is non-numeric string and Y is boolean/number. Or X is object and Y is boolean/number. @ means ==, !=.)
- @ X (X is non-numeric string. @ means +, -.)
X is converted to boolean. (X is a primitive wrapper object.)
- if (X) …
- X && …
- X || …
- X ? … : …
- !X
For your reference, JavaScript converts a type like the following:
undefined
is converted to string: "undefined"undefined
is converted to number:NaN
null
is converted to string: "null"null
is converted to number: 0- boolean is converted to number: false is 0, true is 1.
- Empty string is converted to number: 0
- Neither empty nor numeric string is converted to number:
NaN
Symbol
is converted to string or number: aTypeError
exception is thrown.- Primitive wrapper object is converted to boolean: true
Noncompliant Code Example
View with compliant examples side by sidefunction example1() {
var cssString = "";
var backPosition;
if (animatedBackground.length === 3) {
cssString += "backgroundPosition: " + backPosition + "px; "; // BAD_TYPE_COERCION alarm: Expression 'backPosition' has an undefined value and type-coerced to string type.
}
return cssString;
}
function example2() {
var mod = $index & 1;
if (mod !== old$index & 1) { // BAD_TYPE_COERCION alarm: Expression 'mod !== old$index' has boolean type and type-coerced to number type.
if (mod === selector) {
addClass(scope.$eval(attr[name]));
} else {
removeClass(scope.$eval(attr[name]));
}
}
}
Compliant Code Example
View with noncompliant examples side by sidefunction example1() {
var cssString = "";
var backPosition;
if (animatedBackground.length === 3) {
backPosition = 0; // Assign a valid value.
cssString += "backgroundPosition: " + backPosition + "px; ";
}
return cssString;
}
function example2() {
var mod = $index & 1;
if (mod !== (old$index & 1)) { // Use parentheses.
if (mod === selector) {
addClass(scope.$eval(attr[name]));
} else {
removeClass(scope.$eval(attr[name]));
}
}
}
Version
This rule was introduced in DeepScan 1.0.0-alpha.