Skip to content

Commit 69365cc

Browse files
committed
remove false positive in missingSpaceInAppend by requring the presence of a word-like fragment
1 parent b858962 commit 69365cc

File tree

5 files changed

+54
-7
lines changed

5 files changed

+54
-7
lines changed

change-notes/1.22/analysis-javascript.md

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
| Shift out of range (`js/shift-out-of-range`| Fewer false positive results | This rule now correctly handles BigInt shift operands. |
3737
| Superfluous trailing arguments (`js/superfluous-trailing-arguments`) | Fewer false-positive results. | This rule no longer flags calls to placeholder functions that trivially throw an exception. |
3838
| Undocumented parameter (`js/jsdoc/missing-parameter`) | No changes to results | This rule is now run on LGTM, although its results are still not shown by default. |
39+
| Missing space in string concatenation (`js/missing-space-in-concatenation`) | Fewer false positive results | The rule now requires a word-like part exists in the string concatenation. |
3940

4041
## Changes to QL libraries
4142

javascript/ql/src/Expressions/MissingSpaceInAppend.ql

+46-6
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,51 @@ Expr leftChild(Expr e) {
2222
result = e.(AddExpr).getLeftOperand()
2323
}
2424

25-
class LiteralOrTemplate extends Expr {
26-
LiteralOrTemplate() {
27-
this instanceof TemplateLiteral or
28-
this instanceof Literal
25+
predicate isInConcat(Expr e) {
26+
exists(ParExpr par | par.getExpression() = e)
27+
or
28+
exists(AddExpr a | a.getAnOperand() = e)
29+
}
30+
31+
class ConcatenationLiteral extends Expr {
32+
ConcatenationLiteral() {
33+
(
34+
this instanceof TemplateLiteral
35+
or
36+
this instanceof Literal
37+
)
38+
and isInConcat(this)
2939
}
3040
}
3141

32-
from AddExpr e, LiteralOrTemplate l, LiteralOrTemplate r, string word
42+
Expr getConcatChild(Expr e) {
43+
result = rightChild(e) or
44+
result = leftChild(e)
45+
}
46+
47+
Expr getConcatParent(Expr e) {
48+
e = getConcatChild(result)
49+
}
50+
51+
predicate isWordLike(ConcatenationLiteral lit) {
52+
lit.getStringValue().regexpMatch("(?i).*[a-z]{3,}.*")
53+
}
54+
55+
class ConcatRoot extends AddExpr {
56+
ConcatRoot() {
57+
not isInConcat(this)
58+
}
59+
}
60+
61+
ConcatRoot getAddRoot(AddExpr e) {
62+
result = getConcatParent*(e)
63+
}
64+
65+
predicate hasWordLikeFragment(AddExpr e) {
66+
isWordLike(getConcatChild*(getAddRoot(e)))
67+
}
68+
69+
from AddExpr e, ConcatenationLiteral l, ConcatenationLiteral r, string word
3370
where
3471
// l and r are appended together
3572
l = rightChild*(e.getLeftOperand()) and
@@ -41,5 +78,8 @@ where
4178
// needed, and intra-identifier punctuation in, for example, a qualified name.
4279
word = l.getStringValue().regexpCapture(".* (([-A-Za-z/'\\.:,]*[a-zA-Z]|[0-9]+)[\\.:,!?']*)", 1) and
4380
r.getStringValue().regexpMatch("[a-zA-Z].*") and
44-
not word.regexpMatch(".*[,\\.:].*[a-zA-Z].*[^a-zA-Z]")
81+
not word.regexpMatch(".*[,\\.:].*[a-zA-Z].*[^a-zA-Z]") and
82+
83+
// There must be a constant-string in the concatenation that looks like a word.
84+
hasWordLikeFragment(e)
4585
select l, "This string appears to be missing a space after '" + word + "'."

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

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
| missing.js:24:5:24:21 | `missing a space` | This string appears to be missing a space after 'space'. |
1212
| missing.js:26:5:26:21 | "missing a space" | This string appears to be missing a space after 'space'. |
1313
| missing.js:28:5:28:21 | `missing a space` | This string appears to be missing a space after 'space'. |
14+
| missing.js:31:7:31:12 | "h. 0" | This string appears to be missing a space after '0'. |

javascript/ql/test/query-tests/Expressions/MissingSpaceInAppend/missing.js

+2
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ s = "missing a space" +
2727
`here`;
2828
s = `missing a space` +
2929
`here`;
30+
31+
s = (("h. 0" + "h")) + "word"

javascript/ql/test/query-tests/Expressions/MissingSpaceInAppend/ok.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ s = "the class java.util." +
88
s = "some data: a,b,c," +
99
"d,e,f";
1010
s = "overflow: scroll;" +
11-
"position: absolute;";
11+
"position: absolute;";
12+
13+
s = "h. 0" + "h"
14+
s = ((("h. 0"))) + (("h")) + ("h")

0 commit comments

Comments
 (0)