Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6816f33

Browse files
committed
JS: Handle case-insensitive lodash imports
1 parent 8b8b352 commit 6816f33

4 files changed

Lines changed: 336 additions & 17 deletions

File tree

javascript/ql/src/semmle/javascript/frameworks/LodashUnderscore.qll

Lines changed: 314 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module LodashUnderscore {
2424
this = DataFlow::moduleMember("underscore", name) or
2525
this = DataFlow::moduleMember("lodash", name) or
2626
this = DataFlow::moduleImport("lodash/" + name) or
27-
this = DataFlow::moduleImport("lodash." + name) or
27+
this = DataFlow::moduleImport("lodash." + name.toLowerCase()) and isLodashMember(name) or
2828
this = DataFlow::globalVarRef("_").getAPropertyRead(name)
2929
}
3030

@@ -38,6 +38,319 @@ module LodashUnderscore {
3838
* In addition, the global variable `_` is assumed to refer to `lodash` or `underscore`.
3939
*/
4040
DataFlow::SourceNode member(string name) { result.(Member).getName() = name }
41+
42+
/**
43+
* Holds if `name` is the name of a member exported from the `lodash` package
44+
* which has a corresponding `lodash.xxx` NPM package.
45+
*/
46+
private predicate isLodashMember(string name) {
47+
name = "templateSettings" or
48+
name = "after" or
49+
name = "ary" or
50+
name = "assign" or
51+
name = "assignIn" or
52+
name = "assignInWith" or
53+
name = "assignWith" or
54+
name = "at" or
55+
name = "before" or
56+
name = "bind" or
57+
name = "bindAll" or
58+
name = "bindKey" or
59+
name = "castArray" or
60+
name = "chain" or
61+
name = "chunk" or
62+
name = "compact" or
63+
name = "concat" or
64+
name = "cond" or
65+
name = "conforms" or
66+
name = "constant" or
67+
name = "countBy" or
68+
name = "create" or
69+
name = "curry" or
70+
name = "curryRight" or
71+
name = "debounce" or
72+
name = "defaults" or
73+
name = "defaultsDeep" or
74+
name = "defer" or
75+
name = "delay" or
76+
name = "difference" or
77+
name = "differenceBy" or
78+
name = "differenceWith" or
79+
name = "drop" or
80+
name = "dropRight" or
81+
name = "dropRightWhile" or
82+
name = "dropWhile" or
83+
name = "fill" or
84+
name = "filter" or
85+
name = "flatMap" or
86+
name = "flatMapDeep" or
87+
name = "flatMapDepth" or
88+
name = "flatten" or
89+
name = "flattenDeep" or
90+
name = "flattenDepth" or
91+
name = "flip" or
92+
name = "flow" or
93+
name = "flowRight" or
94+
name = "fromPairs" or
95+
name = "functions" or
96+
name = "functionsIn" or
97+
name = "groupBy" or
98+
name = "initial" or
99+
name = "intersection" or
100+
name = "intersectionBy" or
101+
name = "intersectionWith" or
102+
name = "invert" or
103+
name = "invertBy" or
104+
name = "invokeMap" or
105+
name = "iteratee" or
106+
name = "keyBy" or
107+
name = "keys" or
108+
name = "keysIn" or
109+
name = "map" or
110+
name = "mapKeys" or
111+
name = "mapValues" or
112+
name = "matches" or
113+
name = "matchesProperty" or
114+
name = "memoize" or
115+
name = "merge" or
116+
name = "mergeWith" or
117+
name = "method" or
118+
name = "methodOf" or
119+
name = "mixin" or
120+
name = "negate" or
121+
name = "nthArg" or
122+
name = "omit" or
123+
name = "omitBy" or
124+
name = "once" or
125+
name = "orderBy" or
126+
name = "over" or
127+
name = "overArgs" or
128+
name = "overEvery" or
129+
name = "overSome" or
130+
name = "partial" or
131+
name = "partialRight" or
132+
name = "partition" or
133+
name = "pick" or
134+
name = "pickBy" or
135+
name = "property" or
136+
name = "propertyOf" or
137+
name = "pull" or
138+
name = "pullAll" or
139+
name = "pullAllBy" or
140+
name = "pullAllWith" or
141+
name = "pullAt" or
142+
name = "range" or
143+
name = "rangeRight" or
144+
name = "rearg" or
145+
name = "reject" or
146+
name = "remove" or
147+
name = "rest" or
148+
name = "reverse" or
149+
name = "sampleSize" or
150+
name = "set" or
151+
name = "setWith" or
152+
name = "shuffle" or
153+
name = "slice" or
154+
name = "sortBy" or
155+
name = "sortedUniq" or
156+
name = "sortedUniqBy" or
157+
name = "split" or
158+
name = "spread" or
159+
name = "tail" or
160+
name = "take" or
161+
name = "takeRight" or
162+
name = "takeRightWhile" or
163+
name = "takeWhile" or
164+
name = "tap" or
165+
name = "throttle" or
166+
name = "thru" or
167+
name = "toArray" or
168+
name = "toPairs" or
169+
name = "toPairsIn" or
170+
name = "toPath" or
171+
name = "toPlainObject" or
172+
name = "transform" or
173+
name = "unary" or
174+
name = "union" or
175+
name = "unionBy" or
176+
name = "unionWith" or
177+
name = "uniq" or
178+
name = "uniqBy" or
179+
name = "uniqWith" or
180+
name = "unset" or
181+
name = "unzip" or
182+
name = "unzipWith" or
183+
name = "update" or
184+
name = "updateWith" or
185+
name = "values" or
186+
name = "valuesIn" or
187+
name = "without" or
188+
name = "words" or
189+
name = "wrap" or
190+
name = "xor" or
191+
name = "xorBy" or
192+
name = "xorWith" or
193+
name = "zip" or
194+
name = "zipObject" or
195+
name = "zipObjectDeep" or
196+
name = "zipWith" or
197+
name = "entries" or
198+
name = "entriesIn" or
199+
name = "extend" or
200+
name = "extendWith" or
201+
name = "add" or
202+
name = "attempt" or
203+
name = "camelCase" or
204+
name = "capitalize" or
205+
name = "ceil" or
206+
name = "clamp" or
207+
name = "clone" or
208+
name = "cloneDeep" or
209+
name = "cloneDeepWith" or
210+
name = "cloneWith" or
211+
name = "conformsTo" or
212+
name = "deburr" or
213+
name = "defaultTo" or
214+
name = "divide" or
215+
name = "endsWith" or
216+
name = "eq" or
217+
name = "escape" or
218+
name = "escapeRegExp" or
219+
name = "every" or
220+
name = "find" or
221+
name = "findIndex" or
222+
name = "findKey" or
223+
name = "findLast" or
224+
name = "findLastIndex" or
225+
name = "findLastKey" or
226+
name = "floor" or
227+
name = "forEach" or
228+
name = "forEachRight" or
229+
name = "forIn" or
230+
name = "forInRight" or
231+
name = "forOwn" or
232+
name = "forOwnRight" or
233+
name = "get" or
234+
name = "gt" or
235+
name = "gte" or
236+
name = "has" or
237+
name = "hasIn" or
238+
name = "head" or
239+
name = "identity" or
240+
name = "includes" or
241+
name = "indexOf" or
242+
name = "inRange" or
243+
name = "invoke" or
244+
name = "isArguments" or
245+
name = "isArray" or
246+
name = "isArrayBuffer" or
247+
name = "isArrayLike" or
248+
name = "isArrayLikeObject" or
249+
name = "isBoolean" or
250+
name = "isBuffer" or
251+
name = "isDate" or
252+
name = "isElement" or
253+
name = "isEmpty" or
254+
name = "isEqual" or
255+
name = "isEqualWith" or
256+
name = "isError" or
257+
name = "isFinite" or
258+
name = "isFunction" or
259+
name = "isInteger" or
260+
name = "isLength" or
261+
name = "isMap" or
262+
name = "isMatch" or
263+
name = "isMatchWith" or
264+
name = "isNaN" or
265+
name = "isNative" or
266+
name = "isNil" or
267+
name = "isNull" or
268+
name = "isNumber" or
269+
name = "isObject" or
270+
name = "isObjectLike" or
271+
name = "isPlainObject" or
272+
name = "isRegExp" or
273+
name = "isSafeInteger" or
274+
name = "isSet" or
275+
name = "isString" or
276+
name = "isSymbol" or
277+
name = "isTypedArray" or
278+
name = "isUndefined" or
279+
name = "isWeakMap" or
280+
name = "isWeakSet" or
281+
name = "join" or
282+
name = "kebabCase" or
283+
name = "last" or
284+
name = "lastIndexOf" or
285+
name = "lowerCase" or
286+
name = "lowerFirst" or
287+
name = "lt" or
288+
name = "lte" or
289+
name = "max" or
290+
name = "maxBy" or
291+
name = "mean" or
292+
name = "meanBy" or
293+
name = "min" or
294+
name = "minBy" or
295+
name = "stubArray" or
296+
name = "stubFalse" or
297+
name = "stubObject" or
298+
name = "stubString" or
299+
name = "stubTrue" or
300+
name = "multiply" or
301+
name = "nth" or
302+
name = "noConflict" or
303+
name = "noop" or
304+
name = "now" or
305+
name = "pad" or
306+
name = "padEnd" or
307+
name = "padStart" or
308+
name = "parseInt" or
309+
name = "random" or
310+
name = "reduce" or
311+
name = "reduceRight" or
312+
name = "repeat" or
313+
name = "replace" or
314+
name = "result" or
315+
name = "round" or
316+
name = "runInContext" or
317+
name = "sample" or
318+
name = "size" or
319+
name = "snakeCase" or
320+
name = "some" or
321+
name = "sortedIndex" or
322+
name = "sortedIndexBy" or
323+
name = "sortedIndexOf" or
324+
name = "sortedLastIndex" or
325+
name = "sortedLastIndexBy" or
326+
name = "sortedLastIndexOf" or
327+
name = "startCase" or
328+
name = "startsWith" or
329+
name = "subtract" or
330+
name = "sum" or
331+
name = "sumBy" or
332+
name = "template" or
333+
name = "times" or
334+
name = "toFinite" or
335+
name = "toInteger" or
336+
name = "toLength" or
337+
name = "toLower" or
338+
name = "toNumber" or
339+
name = "toSafeInteger" or
340+
name = "toString" or
341+
name = "toUpper" or
342+
name = "trim" or
343+
name = "trimEnd" or
344+
name = "trimStart" or
345+
name = "truncate" or
346+
name = "unescape" or
347+
name = "uniqueId" or
348+
name = "upperCase" or
349+
name = "upperFirst" or
350+
name = "each" or
351+
name = "eachRight" or
352+
name = "first"
353+
}
41354
}
42355

43356
/**

javascript/ql/test/library-tests/Extend/ExtendCalls.expected

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@
2323
| tst.js:55:1:55:49 | checkDe ... arg())) | OK |
2424
| tst.js:56:1:56:53 | checkDe ... arg())) | OK |
2525
| tst.js:57:1:57:56 | checkDe ... arg())) | OK |
26-
| tst.js:61:1:61:42 | checkSh ... arg())) | OK |
27-
| tst.js:62:1:62:48 | checkSh ... arg())) | OK |
28-
| tst.js:63:1:63:54 | checkSh ... arg())) | OK |
29-
| tst.js:64:1:64:45 | checkSh ... arg())) | OK |
30-
| tst.js:65:1:65:52 | checkSh ... arg())) | OK |
31-
| tst.js:66:1:66:53 | checkSh ... arg())) | OK |
32-
| tst.js:67:1:67:53 | checkSh ... arg())) | OK |
33-
| tst.js:68:1:68:55 | checkSh ... arg())) | OK |
34-
| tst.js:69:1:69:52 | checkSh ... arg())) | OK |
35-
| tst.js:70:1:70:51 | checkSh ... arg())) | OK |
36-
| tst.js:71:1:71:51 | checkSh ... arg())) | OK |
37-
| tst.js:72:1:72:53 | checkSh ... arg())) | OK |
38-
| tst.js:73:1:73:53 | checkSh ... arg())) | OK |
39-
| tst.js:77:1:77:45 | checkSh ... arg())) | OK |
40-
| tst.js:78:1:78:55 | checkSh ... arg())) | OK |
41-
| tst.js:79:1:79:51 | checkSh ... arg())) | OK |
26+
| tst.js:58:1:58:53 | checkDe ... arg())) | OK |
27+
| tst.js:59:1:59:56 | checkDe ... arg())) | OK |
28+
| tst.js:63:1:63:42 | checkSh ... arg())) | OK |
29+
| tst.js:64:1:64:48 | checkSh ... arg())) | OK |
30+
| tst.js:65:1:65:54 | checkSh ... arg())) | OK |
31+
| tst.js:66:1:66:45 | checkSh ... arg())) | OK |
32+
| tst.js:67:1:67:52 | checkSh ... arg())) | OK |
33+
| tst.js:68:1:68:53 | checkSh ... arg())) | OK |
34+
| tst.js:69:1:69:53 | checkSh ... arg())) | OK |
35+
| tst.js:70:1:70:55 | checkSh ... arg())) | OK |
36+
| tst.js:71:1:71:52 | checkSh ... arg())) | OK |
37+
| tst.js:72:1:72:51 | checkSh ... arg())) | OK |
38+
| tst.js:73:1:73:51 | checkSh ... arg())) | OK |
39+
| tst.js:74:1:74:53 | checkSh ... arg())) | OK |
40+
| tst.js:75:1:75:53 | checkSh ... arg())) | OK |
41+
| tst.js:79:1:79:45 | checkSh ... arg())) | OK |
42+
| tst.js:80:1:80:55 | checkSh ... arg())) | OK |
43+
| tst.js:81:1:81:51 | checkSh ... arg())) | OK |

javascript/ql/test/library-tests/Extend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"js-extend": "^1.0.1",
1515
"just-extend": "^1.1.27",
1616
"lodash": "^4.17.10",
17+
"lodash.defaultsdeep": "^4.6.0",
18+
"lodash.mergewith": "^4.6.1",
1719
"merge": "^1.2.0",
1820
"merge-deep": "^3.0.2",
1921
"merge-options": "^1.0.1",

javascript/ql/test/library-tests/Extend/tst.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ checkDeep(require("smart-extend").deep(base(), arg()));
5555
checkDeep(require("lodash").merge(base(), arg()));
5656
checkDeep(require("lodash").mergeWith(base(), arg()));
5757
checkDeep(require("lodash").defaultsDeep(base(), arg()));
58+
checkDeep(require("lodash.mergewith")(base(), arg()));
59+
checkDeep(require("lodash.defaultsdeep")(base(), arg()));
5860

5961
// Always shallow
6062

0 commit comments

Comments
 (0)