Skip to content

Commit 7819dcf

Browse files
authored
Merge pull request #15043 from hvitved/ql/redundant-import
QL4QL: Improvements to `RedundantImport` query
2 parents 0618568 + e8f9e36 commit 7819dcf

File tree

21 files changed

+42
-39
lines changed

21 files changed

+42
-39
lines changed

javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ import experimental.adaptivethreatmodeling.EndpointTypes
66
private import semmle.javascript.security.dataflow.SqlInjectionCustomizations
77
private import semmle.javascript.security.dataflow.DomBasedXssCustomizations
88
private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
9-
private import semmle.javascript.security.dataflow.TaintedPathCustomizations
109
private import semmle.javascript.heuristics.SyntacticHeuristics as SyntacticHeuristics
1110
private import semmle.javascript.filters.ClassifyFiles as ClassifyFiles
1211
private import semmle.javascript.security.dataflow.XxeCustomizations
1312
private import semmle.javascript.security.dataflow.RemotePropertyInjectionCustomizations
1413
private import semmle.javascript.security.dataflow.TypeConfusionThroughParameterTamperingCustomizations
1514
private import semmle.javascript.security.dataflow.ZipSlipCustomizations
16-
private import semmle.javascript.security.dataflow.TaintedPathCustomizations
1715
private import semmle.javascript.security.dataflow.CleartextLoggingCustomizations
1816
private import semmle.javascript.security.dataflow.XpathInjectionCustomizations
1917
private import semmle.javascript.security.dataflow.Xss::Shared as Xss
@@ -28,10 +26,8 @@ private import semmle.javascript.security.dataflow.CommandInjectionCustomization
2826
private import semmle.javascript.security.dataflow.PrototypePollutionCustomizations
2927
private import semmle.javascript.security.dataflow.UnvalidatedDynamicMethodCallCustomizations
3028
private import semmle.javascript.security.dataflow.TaintedFormatStringCustomizations
31-
private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
3229
private import semmle.javascript.security.dataflow.PostMessageStarCustomizations
3330
private import semmle.javascript.security.dataflow.RegExpInjectionCustomizations
34-
private import semmle.javascript.security.dataflow.SqlInjectionCustomizations
3531
private import semmle.javascript.security.dataflow.InsecureRandomnessCustomizations
3632
private import semmle.javascript.security.dataflow.XmlBombCustomizations
3733
private import semmle.javascript.security.dataflow.InsufficientPasswordHashCustomizations

javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/extraction/ExtractMisclassifiedEndpointFeatures.ql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66

77
import javascript
88
import experimental.adaptivethreatmodeling.AdaptiveThreatModeling
9-
import experimental.adaptivethreatmodeling.ATMConfig
109
import experimental.adaptivethreatmodeling.BaseScoring
1110
import experimental.adaptivethreatmodeling.EndpointFeatures as EndpointFeatures
12-
import experimental.adaptivethreatmodeling.EndpointTypes
1311
import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
1412

1513
/** Gets the positive endpoint type for which you wish to find misclassified examples. */

javascript/ql/experimental/adaptivethreatmodeling/test/endpoint_large_scale/FilteredTruePositives.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
1616
import semmle.javascript.security.dataflow.SqlInjectionCustomizations
17-
import semmle.javascript.security.dataflow.TaintedPathCustomizations
1817
import semmle.javascript.security.dataflow.DomBasedXssCustomizations
1918
import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironmentCustomizations
2019
import experimental.adaptivethreatmodeling.NosqlInjectionATM as NosqlInjectionAtm

javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
private import javascript
7272
private import internal.FlowSteps
7373
private import internal.AccessPaths
74-
private import internal.CallGraphs
7574
private import semmle.javascript.Unit
7675
private import semmle.javascript.internal.CachedStages
7776

javascript/ql/lib/semmle/javascript/dataflow/TypeInference.qll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@
2727

2828
private import javascript
2929
import AbstractValues
30-
import AbstractProperties
3130
private import InferredTypes
3231
private import Refinements
33-
private import internal.AbstractValuesImpl
3432
import internal.BasicExprTypeInference
3533
import internal.InterModuleTypeInference
3634
import internal.InterProceduralTypeInference

javascript/ql/lib/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import javascript
1111
private import AngularJS
12-
private import ServiceDefinitions
1312

1413
/**
1514
* Holds if `nd` is an `angular.injector()` value

javascript/ql/lib/semmle/javascript/frameworks/Express.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44

55
import javascript
6-
import semmle.javascript.frameworks.HTTP
76
import semmle.javascript.frameworks.ExpressModules
87
private import semmle.javascript.dataflow.InferredTypes
98
private import semmle.javascript.frameworks.ConnectExpressShared::ConnectExpressShared

javascript/ql/lib/semmle/javascript/security/dataflow/LoopBoundInjectionQuery.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99

1010
import javascript
11-
import semmle.javascript.security.TaintedObject
1211
import LoopBoundInjectionCustomizations::LoopBoundInjection
1312

1413
/**

javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import javascript
88
import semmle.javascript.security.TaintedObject
9-
import semmle.javascript.dependencies.Dependencies
109
import semmle.javascript.dependencies.SemVer
1110

1211
module PrototypePollution {

javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionQuery.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import javascript
1111
import semmle.javascript.security.TaintedObject
12-
import semmle.javascript.dependencies.Dependencies
1312
import semmle.javascript.dependencies.SemVer
1413
import PrototypePollutionCustomizations::PrototypePollution
1514

javascript/ql/src/meta/analysis-quality/UnmodelledSteps.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010

1111
import javascript
12-
import meta.MetaMetrics
1312
private import Expressions.ExprHasNoEffect
1413
import meta.internal.TaintMetrics
1514

javascript/ql/test/library-tests/DependencyModuleImports/Test.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import javascript
2-
import semmle.javascript.dependencies.Dependencies
32
import semmle.javascript.dependencies.SemVer
43

54
class SampleVersionSink extends DataFlow::Node {

ql/ql/src/codeql_ql/ast/Ast.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,9 @@ class ModuleMember extends TModuleMember, AstNode {
889889

890890
/** Holds if this member is declared as `final`. */
891891
predicate isFinal() { this.hasAnnotation("final") }
892+
893+
/** Holds if this member is declared as `deprecated`. */
894+
predicate isDeprecated() { this.hasAnnotation("deprecated") }
892895
}
893896

894897
private newtype TDeclarationKind =
@@ -2738,6 +2741,18 @@ module YAML {
27382741
)
27392742
}
27402743

2744+
/**
2745+
* Gets the language library file for this QLPack, if any. For example, the
2746+
* language library file for `codeql/cpp-all` is `cpp.qll`.
2747+
*/
2748+
File getLanguageLib() {
2749+
exists(string name |
2750+
name = this.getExtractor() and
2751+
result.getParentContainer() = this.getFile().getParentContainer() and
2752+
result.getBaseName() = name + ".qll"
2753+
)
2754+
}
2755+
27412756
Location getLocation() {
27422757
// hacky, just pick the first node in the file.
27432758
result =
Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,64 @@
11
import ql
2+
private import YAML
3+
private import codeql_ql.ast.internal.Module
24

3-
Import imports(Import imp) {
5+
private FileOrModule getResolvedModule(Import imp) {
6+
result = imp.getResolvedModule() and
7+
// skip the top-level language files
8+
not result.asFile() = any(QLPack p).getLanguageLib()
9+
}
10+
11+
private Import imports(Import imp) {
412
(
513
exists(File file, TopLevel top |
6-
imp.getResolvedModule().asFile() = file and
14+
getResolvedModule(imp).asFile() = file and
715
top.getLocation().getFile() = file and
816
result = top.getAMember()
917
)
1018
or
1119
exists(Module mod |
12-
imp.getResolvedModule().asModule() = mod and
20+
getResolvedModule(imp).asModule() = mod and
1321
result = mod.getAMember()
1422
)
1523
)
1624
}
1725

18-
Import getAnImport(AstNode parent) {
26+
private Import getAnImport(AstNode parent) {
1927
result = parent.(TopLevel).getAMember()
2028
or
2129
result = parent.(Module).getAMember()
2230
}
2331

24-
pragma[inline]
25-
predicate importsFromSameFolder(Import a, Import b) {
26-
exists(string base |
27-
a.getImportString().regexpCapture("(.*)\\.[^\\.]*", 1) = base and
28-
b.getImportString().regexpCapture("(.*)\\.[^\\.]*", 1) = base
29-
)
30-
or
31-
not a.getImportString().matches("%.%") and
32-
not b.getImportString().matches("%.%")
33-
}
34-
3532
predicate problem(Import imp, Import redundant, string message) {
3633
not exists(imp.importedAs()) and
3734
not exists(redundant.importedAs()) and
3835
not exists(imp.getModuleExpr().getQualifier*().getArgument(_)) and // any type-arguments, and we ignore, they might be different.
3936
// skip the top-level language files, they have redundant imports, and that's fine.
40-
not exists(imp.getLocation().getFile().getParentContainer().getFile("qlpack.yml")) and
37+
not imp.getLocation().getFile() = any(QLPack p).getLanguageLib() and
4138
// skip the DataFlowImpl.qll and similar, they have redundant imports in some copies.
4239
not imp.getLocation()
4340
.getFile()
4441
.getBaseName()
4542
.regexpMatch([".*Impl\\d?\\.qll", "DataFlowImpl.*\\.qll"]) and
46-
// skip two imports that imports different things from the same folder.
47-
not importsFromSameFolder(imp, redundant) and
4843
// if the redundant is public, and the imp is private, then the redundant might add things that are exported.
4944
not (imp.isPrivate() and not redundant.isPrivate()) and
5045
// Actually checking if the import is redundant:
5146
exists(AstNode parent |
5247
imp = getAnImport(parent) and
53-
redundant = getAnImport(parent) and
54-
redundant.getLocation().getStartLine() > imp.getLocation().getStartLine()
48+
redundant = getAnImport(parent)
5549
|
5650
message = "Redundant import, the module is already imported inside $@." and
5751
// only looking for things directly imported one level down. Otherwise things gets complicated (lots of cycles).
5852
exists(Import inner | inner = imports(imp) |
59-
redundant.getResolvedModule() = inner.getResolvedModule() and
53+
getResolvedModule(redundant) = getResolvedModule(inner) and
6054
not inner.isPrivate() and // if the inner is private, then it's not propagated out.
55+
not inner.isDeprecated() and
6156
not exists(inner.importedAs())
6257
)
6358
or
6459
message = "Duplicate import, the module is already imported by $@." and
6560
// two different import statements, that import the same thing
66-
imp.getResolvedModule() = redundant.getResolvedModule()
61+
getResolvedModule(imp) = getResolvedModule(redundant) and
62+
redundant.getLocation().getStartLine() > imp.getLocation().getStartLine()
6763
)
6864
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import folder.A
2+
import folder.B
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import folder.A
2+
import folder.C
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| D.qll:1:1:1:15 | Import | Redundant import, the module is already imported inside $@. | D.qll:2:1:2:15 | Import | folder.B |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/style/RedundantImport.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
predicate p() { any() }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import A
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deprecated import A

0 commit comments

Comments
 (0)