Skip to content

Commit f55005a

Browse files
committed
more precise warning message for implicit string/number conversions
1 parent 1baf5df commit f55005a

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

javascript/ql/src/Expressions/ImplicitOperandConversion.ql

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,26 @@ abstract class NullOrUndefinedConversion extends ImplicitConversion {
162162
class PlusConversion extends NullOrUndefinedConversion {
163163
PlusConversion() { parent instanceof AddExpr or parent instanceof AssignAddExpr }
164164

165-
override string getConversionTarget() { result = "number or string" }
165+
override string getConversionTarget() {
166+
result = getDefiniteCousinType()
167+
or
168+
not exists(getDefiniteCousinType()) and
169+
result = "number or string"
170+
}
171+
172+
/**
173+
* Gets the cousin of this implicit conversion.
174+
* E.g. if this is `a` in the expression `a + b`, then the cousin is `b`.
175+
*/
176+
private Expr getCousin() { result = parent.getAChild() and not result = this.getEnclosingExpr() }
177+
178+
/**
179+
* Gets the unique type of the cousin expression, if that type is `string` or `number`.
180+
*/
181+
private string getDefiniteCousinType() {
182+
result = unique(InferredType t | t = getCousin().flow().analyze().getAType()).getTypeofTag() and
183+
result = ["string", "number"]
184+
}
166185
}
167186

168187
/**

javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/ImplicitOperandConversion.expected

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
| tst.js:20:6:20:13 | 'string' | This expression will be implicitly converted from string to object. |
44
| tst.js:26:13:26:53 | "Settin ... o '%s'" | This expression will be implicitly converted from string to number. |
55
| tst.js:29:18:29:26 | !callback | This expression will be implicitly converted from boolean to object. |
6-
| tst.js:53:5:53:10 | void 0 | This expression will be implicitly converted from undefined to number or string. |
6+
| tst.js:53:5:53:10 | void 0 | This expression will be implicitly converted from undefined to number. |
77
| tst.js:61:3:61:3 | x | This expression will be implicitly converted from undefined to number. |
88
| tst.js:67:8:67:8 | y | This expression will be implicitly converted from undefined to number. |
99
| tst.js:73:5:73:5 | x | This expression will be implicitly converted from undefined to number. |
1010
| tst.js:79:19:79:22 | name | This expression will be implicitly converted from undefined to string. |
1111
| tst.js:85:3:85:3 | x | This expression will be implicitly converted from undefined to number. |
1212
| tst.js:100:5:100:7 | f() | This expression will be implicitly converted from undefined to number. |
1313
| tst.js:106:5:106:7 | g() | This expression will be implicitly converted from undefined to number. |
14+
| tst.js:109:13:109:15 | g() | This expression will be implicitly converted from undefined to number. |
15+
| tst.js:110:13:110:15 | g() | This expression will be implicitly converted from undefined to string. |

javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/tst.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,8 @@ function l() {
105105
}
106106
g()|0;
107107
g();
108+
109+
var a = g() + 2;
110+
var b = g() + "str";
108111
});
109112

0 commit comments

Comments
 (0)