From d92e49fb170ea07892d2428d5a017fe40a80f8d6 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Wed, 4 Mar 2020 01:14:07 -0800 Subject: [PATCH 01/14] Add libraries for go.mod expressions --- ql/src/go.qll | 1 + ql/src/semmle/go/AST.qll | 24 +++++ ql/src/semmle/go/Files.qll | 3 +- ql/src/semmle/go/GoModExpr.qll | 167 +++++++++++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 ql/src/semmle/go/GoModExpr.qll diff --git a/ql/src/go.qll b/ql/src/go.qll index b7d8af964a1..d2dc498b6f2 100644 --- a/ql/src/go.qll +++ b/ql/src/go.qll @@ -9,6 +9,7 @@ import semmle.go.Concepts import semmle.go.Decls import semmle.go.Expr import semmle.go.Files +import semmle.go.GoModExpr import semmle.go.Locations import semmle.go.Packages import semmle.go.Scopes diff --git a/ql/src/semmle/go/AST.qll b/ql/src/semmle/go/AST.qll index 3d1dddf8981..a58a8c3d78a 100644 --- a/ql/src/semmle/go/AST.qll +++ b/ql/src/semmle/go/AST.qll @@ -16,6 +16,7 @@ class AstNode extends @node, Locatable { */ AstNode getChild(int i) { result = this.(ExprParent).getChildExpr(i) or + result = this.(GoModExprParent).getChildGoModExpr(i) or result = this.(StmtParent).getChildStmt(i) or result = this.(DeclParent).getDecl(i) or result = this.(GenDecl).getSpec(i) or @@ -70,6 +71,29 @@ class ExprParent extends @exprparent, AstNode { int getNumChildExpr() { result = count(getAChildExpr()) } } +/** + * An AST node whose children include go.mod expressions. + */ +class GoModExprParent extends @modexprparent, AstNode { + /** + * Gets the `i`th child expression of this node. + * + * Note that the precise indices of child expressions are considered an implementation detail + * and are subject to change without notice. + */ + GoModExpr getChildGoModExpr(int i) { modexprs(result, _, this, i) } + + /** + * Gets an expression that is a child node of this node in the AST. + */ + GoModExpr getAChildGoModExpr() { result = getChildGoModExpr(_) } + + /** + * Gets the number of child expressions of this node. + */ + int getNumChildGoModExpr() { result = count(getAChildGoModExpr()) } +} + /** * An AST node whose children include statements. */ diff --git a/ql/src/semmle/go/Files.qll b/ql/src/semmle/go/Files.qll index 963c9943106..170ba9c2b3d 100644 --- a/ql/src/semmle/go/Files.qll +++ b/ql/src/semmle/go/Files.qll @@ -178,7 +178,8 @@ class Folder extends Container, @folder { } /** A file. */ -class File extends Container, @file, Documentable, ExprParent, DeclParent, ScopeNode { +class File extends Container, @file, Documentable, ExprParent, GoModExprParent, DeclParent, + ScopeNode { override Location getLocation() { has_location(this, result) } override string getAbsolutePath() { files(this, result, _, _, _) } diff --git a/ql/src/semmle/go/GoModExpr.qll b/ql/src/semmle/go/GoModExpr.qll new file mode 100644 index 00000000000..fced69266f7 --- /dev/null +++ b/ql/src/semmle/go/GoModExpr.qll @@ -0,0 +1,167 @@ +/** + * Provides classes for working with go.mod expressions. + */ + +import go + +/** + * A go.mod expression. + */ +class GoModExpr extends @modexpr, GoModExprParent { + /** + * Gets the kind of this expression, which is an integer value representing the expression's + * node type. + * + * Note that the mapping from node types to integer kinds is considered an implementation detail + * and subject to change without notice. + */ + int getKind() { modexprs(this, result, _, _) } + + /** + * Get the comment group associated with this expression. + */ + DocComment getComments() { result.getDocumentedElement() = this } + + override string toString() { result = "go.mod expression" } +} + +/** + * A top-level block of comments separate from any rule. + */ +class GoModCommentBlock extends @modcommentblock, GoModExpr { } + +/** + * A single line of tokens. + */ +class GoModLine extends @modline, GoModExpr { + /** + * Gets the `i`th token on this line. + */ + string getToken(int i) { modtokens(result, this, i) } + + override string toString() { result = "go.mod line" } +} + +/** + * A line that contains the module information + */ +class GoModModuleLine extends GoModLine { + GoModModuleLine() { + this.getParent().(GoModLineBlock).getToken(0) = "module" + or + not this.getParent() instanceof GoModLineBlock and + this.getToken(0) = "module" + } + + string getPath() { + if this.getParent() instanceof GoModLineBlock + then result = this.getToken(1) + else result = this.getToken(0) + } + + override string toString() { result = "go.mod module line" } +} + +/** + * A factored block of lines, for example `require ( "path" )`. + */ +class GoModLineBlock extends @modlineblock, GoModExpr { + /** + * Gets the `i`th token of this line block. + */ + string getToken(int i) { modtokens(result, this, i) } + + override string toString() { result = "go.mod line block" } +} + +/** + * A line that declares the Go version to be used, for example `go 1.14`. + */ +class GoModGoLine extends GoModLine { + GoModGoLine() { this.getToken(0) = "go" } + + /** Gets the Go version declared. */ + string getVer() { result = this.getToken(1) } + + override string toString() { result = "go.mod go line" } +} + +private string getOffsetToken(GoModLine line, int i) { + if line.getParent() instanceof GoModLineBlock + then result = line.getToken(i - 1) + else result = line.getToken(i) +} + +/** + * A line that declares a requirement, for example `require "path"`. + */ +class GoModRequireLine extends GoModLine { + GoModRequireLine() { + this.getParent().(GoModLineBlock).getToken(0) = "require" + or + not this.getParent() instanceof GoModLineBlock and + this.getToken(0) = "require" + } + + /** Gets the path of the dependency. */ + string getPath() { result = getOffsetToken(this, 1) } + + /** Gets the version of the dependency. */ + string getVer() { result = getOffsetToken(this, 2) } + + override string toString() { result = "go.mod require line" } +} + +/** + * A line that declares a dependency version to exclude, for example `exclude "ver"`. + */ +class GoModExcludeLine extends GoModLine { + GoModExcludeLine() { + this.getParent().(GoModLineBlock).getToken(0) = "exclude" + or + not this.getParent() instanceof GoModLineBlock and + this.getToken(0) = "exclude" + } + + /** Gets the path of the dependency to exclude a version of. */ + string getPath() { result = getOffsetToken(this, 1) } + + /** Gets the excluded version. */ + string getVer() { result = getOffsetToken(this, 2) } + + override string toString() { result = "go.mod exclude line" } +} + +/** + * A line that specifies a dependency to use instead of another one, for example + * `replace "a" => "b" ver`. + */ +class GoModReplaceLine extends GoModLine { + GoModReplaceLine() { + this.getParent().(GoModLineBlock).getToken(0) = "replace" + or + not this.getParent() instanceof GoModLineBlock and + this.getToken(0) = "replace" + } + + /** Gets the path of the dependency to be replaced. */ + string getOriginalPath() { result = getOffsetToken(this, 1) } + + /** Gets the path of the replacement dependency. */ + string getReplacementPath() { result = getOffsetToken(this, 3) } + + /** Gets the version of the replacement dependency. */ + string getReplacementVer() { result = getOffsetToken(this, 4) } + + override string toString() { result = "go.mod replace line" } +} + +/** A left parenthesis for a line block. */ +class GoModLParen extends @modlparen, GoModExpr { + override string toString() { result = "go.mod (" } +} + +/** A right parenthesis for a line block. */ +class GoModRParen extends @modrparen, GoModExpr { + override string toString() { result = "go.mod )" } +} From 6c78490bbeadb4dad64bc026e3de4d013a9c2aaa Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Wed, 4 Mar 2020 01:24:38 -0800 Subject: [PATCH 02/14] Add libraries modeling dependencies --- .../semmle/go/dependencies/Dependencies.qll | 78 +++++++++++++++ .../dependencies/DependencyCustomizations.qll | 1 + ql/src/semmle/go/dependencies/SemVer.qll | 96 +++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 ql/src/semmle/go/dependencies/Dependencies.qll create mode 100644 ql/src/semmle/go/dependencies/DependencyCustomizations.qll create mode 100644 ql/src/semmle/go/dependencies/SemVer.qll diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll new file mode 100644 index 00000000000..4972b0682e2 --- /dev/null +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -0,0 +1,78 @@ +/** + * Provides classes for modeling go.mod dependencies. + */ + +import go +private import semmle.go.dependencies.DependencyCustomizations + +/** + * An abstract representation of a dependency. + */ +abstract class Dependency extends Locatable { + /** + * Holds if this dependency has package path `path` and version `v`. + * + * If the version cannot be determined, `v` is bound to the string + * `"unknown"`. + */ + abstract predicate info(string path, string v); + + /** Gets the package path of this dependency. */ + string getDepPath() { this.info(result, _) } + + /** Gets the version of this dependency. */ + string getDepVer() { this.info(_, result) } + + /** + * An import of this dependency. + */ + ImportSpec getAnImport() { result.getPath() = this.getDepPath() } +} + +/** + * A dependency from a go.mod file. + */ +class GoModDependency extends Dependency, GoModRequireLine { + override predicate info(string path, string v) { + this.replacementInfo(path, v) + or + not this.replacementInfo(_, _) and + this.originalInfo(path, v) + } + + /** + * Holds if there is a replace line that replaces this dependency with a dependency to `path`, + * version `v`. + */ + predicate replacementInfo(string path, string v) { + exists(GoModReplaceLine replace | + replace.getFile() = this.getFile() and + replace.getOriginalPath() = this.getPath() + | + path = replace.getReplacementPath() and + ( + v = replace.getReplacementVer() + or + not exists(replace.getReplacementVer()) and + v = "unknown" + ) + ) + } + + /** + * Get a version that was excluded for this dependency. + */ + string getAnExcludedVer() { + exists(GoModExcludeLine exclude | + exclude.getFile() = this.getFile() and + exclude.getPath() = this.getPath() + | + result = exclude.getVer() + ) + } + + /** + * Holds if this require line originally states dependency `path` had version `ver`. + */ + predicate originalInfo(string path, string v) { path = this.getPath() and v = this.getVer() } +} diff --git a/ql/src/semmle/go/dependencies/DependencyCustomizations.qll b/ql/src/semmle/go/dependencies/DependencyCustomizations.qll new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/ql/src/semmle/go/dependencies/DependencyCustomizations.qll @@ -0,0 +1 @@ + diff --git a/ql/src/semmle/go/dependencies/SemVer.qll b/ql/src/semmle/go/dependencies/SemVer.qll new file mode 100644 index 00000000000..a9c6161dd22 --- /dev/null +++ b/ql/src/semmle/go/dependencies/SemVer.qll @@ -0,0 +1,96 @@ +import semmle.go.dependencies.Dependencies + +/** + * A SemVer-formatted version string in a dependency. + * + * Pre-release information and build metadata is not yet supported. + */ +class DependencySemVer extends string { + Dependency dep; + string normalized; + + DependencySemVer() { + this = dep.getDepVer() and + normalized = normalizeSemver(this) + } + + /** + * Holds if this version may be before `last`. + */ + bindingset[last] + predicate maybeBefore(string last) { normalized < normalizeSemver(last) } + + /** + * Holds if this version may be after `first`. + */ + bindingset[first] + predicate maybeAfter(string first) { normalizeSemver(first) < normalized } + + /** + * Holds if this version may be between `first` (inclusive) and `last` (exclusive). + */ + bindingset[first, last] + predicate maybeBetween(string first, string last) { + normalizeSemver(first) <= normalized and + normalized < normalizeSemver(last) + } + + /** + * Holds if this version is equivalent to `other`. + */ + bindingset[other] + predicate is(string other) { normalized = normalizeSemver(other) } + + /** + * Gets the dependency that uses this string. + */ + Dependency getDependency() { result = dep } +} + +bindingset[str] +private string leftPad(string str) { result = ("000" + str).suffix(str.length()) } + +/** + * Normalizes a SemVer string such that the lexicographical ordering + * of two normalized strings is consistent with the SemVer ordering. + * + * Pre-release information and build metadata is not yet supported. + */ +bindingset[orig] +private string normalizeSemver(string orig) { + exists(string pattern, string major, string minor, string patch | + pattern = "v?(\\d+)\\.(\\d+)\\.(\\d+)(\\D.*)?" and + major = orig.regexpCapture(pattern, 1) and + minor = orig.regexpCapture(pattern, 2) and + patch = orig.regexpCapture(pattern, 3) + | + result = leftPad(major) + "." + leftPad(minor) + "." + leftPad(patch) + ) +} + +/** + * A version string in a dependency that has a SemVer, but also contains a git commit SHA. + * + * This class is useful for interacting with go.mod versions, which use SemVer, but can also contain + * SHAs if no useful tags are found, or when a user wishes to specify a commit SHA. + * + * Pre-release information and build metadata is not yet supported. + */ +class DependencySemShaVer extends DependencySemVer { + string sha; + + DependencySemShaVer() { sha = this.regexpCapture(".*-([0-9a-f]+)", 1) } + + /** + * Gets the commit SHA associated with this version. + */ + string getSha() { result = sha } + + bindingset[other] + override predicate is(string other) { + this.getSha() = other.(DependencySemShaVer).getSha() + or + not other instanceof DependencySemShaVer and + super.is(other) + } +} From dddc8cecd4db5d1216b0c445971e8452f371b19d Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Wed, 4 Mar 2020 04:35:33 -0800 Subject: [PATCH 03/14] Add go.mod expression tests --- .../semmle/go/GoModExpr/ExcludeLines.expected | 3 +++ .../semmle/go/GoModExpr/ExcludeLines.ql | 5 ++++ .../semmle/go/GoModExpr/ReplaceLines.expected | 0 .../semmle/go/GoModExpr/ReplaceLines.ql | 11 +++++++++ .../semmle/go/GoModExpr/RequireLines.expected | 5 ++++ .../semmle/go/GoModExpr/RequireLines.ql | 5 ++++ .../semmle/go/GoModExpr/pkg1/go.mod | 10 ++++++++ .../semmle/go/GoModExpr/pkg1/pkg1.go | 16 +++++++++++++ .../semmle/go/GoModExpr/pkg2/go.mod | 16 +++++++++++++ .../semmle/go/GoModExpr/pkg2/pkg2.go | 13 ++++++++++ .../semmle/go/GoModExpr/squirrel/LICENSE | 23 ++++++++++++++++++ .../semmle/go/GoModExpr/squirrel/README.md | 3 +++ .../semmle/go/GoModExpr/squirrel/go.mod | 3 +++ .../semmle/go/GoModExpr/squirrel/squirrel.go | 24 +++++++++++++++++++ 14 files changed, 137 insertions(+) create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/pkg1/go.mod create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/pkg1/pkg1.go create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/pkg2/pkg2.go create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/squirrel/LICENSE create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/squirrel/README.md create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/squirrel/go.mod create mode 100644 ql/test/library-tests/semmle/go/GoModExpr/squirrel/squirrel.go diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected new file mode 100644 index 00000000000..d23727f1726 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected @@ -0,0 +1,3 @@ +| pkg1/go.mod:10:1:10:44 | go.mod exclude line | module | github.com/github/codeql-go | v1.23.1 | +| pkg2/go.mod:14:2:14:35 | go.mod exclude line | module | github.com/sirupsen/logrus | v1.4.2 | +| pkg2/go.mod:15:2:15:37 | go.mod exclude line | module | github.com/github/codeql-go | v1.23.1 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql new file mode 100644 index 00000000000..dfd2262b9b7 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql @@ -0,0 +1,5 @@ +import go + +from GoModExcludeLine excl, GoModModuleLine mod +where excl.getFile() = mod.getFile() +select excl, mod.getPath(), excl.getPath(), excl.getVer() diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql new file mode 100644 index 00000000000..0e82e2eea9d --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql @@ -0,0 +1,11 @@ +import go + +from GoModReplaceLine repl, GoModModuleLine mod, string repVer +where + repl.getFile() = mod.getFile() and + ( + repVer = repl.getReplacementVer() or + repVer = "no version" + ) +select repl, mod.getPath(), repl.getOriginalPath(), repl.getReplacementPath(), + repl.getReplacementVer() diff --git a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected new file mode 100644 index 00000000000..df5da59bc87 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected @@ -0,0 +1,5 @@ +| pkg1/go.mod:6:2:6:67 | go.mod require line | module | github.com/github/codeql-go | v1.23.2-0.20200302182241-5e71a04fdf30 | +| pkg1/go.mod:7:2:7:55 | go.mod require line | module | golang.org/x/tools | v0.0.0-20200109174759-ac4f524c1612 | +| pkg2/go.mod:7:1:7:38 | go.mod require line | module | github.com/gorilla/mux | v1.7.4 | +| pkg2/go.mod:9:2:9:35 | go.mod require line | module | github.com/sirupsen/logrus | v1.4.1 | +| pkg2/go.mod:10:2:10:40 | go.mod require line | module | github.com/Masterminds/squirrel | v1.2.0 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql new file mode 100644 index 00000000000..84854191b65 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql @@ -0,0 +1,5 @@ +import go + +from GoModRequireLine req, GoModModuleLine mod +where req.getFile() = mod.getFile() +select req, mod.getPath(), req.getPath(), req.getVer() diff --git a/ql/test/library-tests/semmle/go/GoModExpr/pkg1/go.mod b/ql/test/library-tests/semmle/go/GoModExpr/pkg1/go.mod new file mode 100644 index 00000000000..3416d3f0204 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/pkg1/go.mod @@ -0,0 +1,10 @@ +module codeql-go-tests/gomod/dep1 + +go 1.14 + +require ( + github.com/github/codeql-go v1.23.2-0.20200302182241-5e71a04fdf30 + golang.org/x/tools v0.0.0-20200109174759-ac4f524c1612 +) + +exclude github.com/github/codeql-go v1.23.1 diff --git a/ql/test/library-tests/semmle/go/GoModExpr/pkg1/pkg1.go b/ql/test/library-tests/semmle/go/GoModExpr/pkg1/pkg1.go new file mode 100644 index 00000000000..e071a1255a5 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/pkg1/pkg1.go @@ -0,0 +1,16 @@ +package pkg1 + +import ( + "fmt" + + "github.com/github/codeql-go/extractor/dbscheme" + "github.com/github/codeql-go/extractor/trap" + "golang.org/x/tools/go/packages" +) + +func usePkgs() { + fmt.Println(packages.NeedImports) + fmt.Println(dbscheme.LabelObjectType.Index()) + var lbl trap.Label + fmt.Println(lbl) +} diff --git a/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod new file mode 100644 index 00000000000..db778428e12 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod @@ -0,0 +1,16 @@ +module codeql-go-tests/gomod/dep2 + +go 1.14 + +replace github.com/Masterminds/squirrel => ../squirrel + +require github.com/gorilla/mux v1.7.4 +require ( + github.com/sirupsen/logrus v1.4.1 + github.com/Masterminds/squirrel v1.2.0 +) + +exclude ( + github.com/sirupsen/logrus v1.4.2 + github.com/github/codeql-go v1.23.1 +) diff --git a/ql/test/library-tests/semmle/go/GoModExpr/pkg2/pkg2.go b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/pkg2.go new file mode 100644 index 00000000000..16c3a325211 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/pkg2.go @@ -0,0 +1,13 @@ +package pkg2 + +import ( + "fmt" + + "github.com/Masterminds/squirrel" + "github.com/gorilla/mux" + "github.com/sirupsen/logrus" +) + +func useDeps() { + +} diff --git a/ql/test/library-tests/semmle/go/GoModExpr/squirrel/LICENSE b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/LICENSE new file mode 100644 index 00000000000..74c20a2b970 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/LICENSE @@ -0,0 +1,23 @@ +Squirrel +The Masterminds +Copyright (C) 2014-2015, Lann Martin +Copyright (C) 2015-2016, Google +Copyright (C) 2015, Matt Farina and Matt Butcher + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/GoModExpr/squirrel/README.md b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/README.md new file mode 100644 index 00000000000..d51962ba840 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/README.md @@ -0,0 +1,3 @@ +This is a simple stub for https://github.com/Masterminds/squirrel, strictly for use in query testing. + +See the LICENSE file in this folder for information about the licensing of the original library. diff --git a/ql/test/library-tests/semmle/go/GoModExpr/squirrel/go.mod b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/go.mod new file mode 100644 index 00000000000..78405f23173 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/go.mod @@ -0,0 +1,3 @@ +module github.com/github/codeql-go/ql/test/library-tests/semmle/go/GoModExpr/squirrel + +go 1.14 diff --git a/ql/test/library-tests/semmle/go/GoModExpr/squirrel/squirrel.go b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/squirrel.go new file mode 100644 index 00000000000..78a19d3a6f2 --- /dev/null +++ b/ql/test/library-tests/semmle/go/GoModExpr/squirrel/squirrel.go @@ -0,0 +1,24 @@ +package squirrel + +type StatementBuilderType struct{} + +func Expr(e string, args ...interface{}) string { + return Expr(e, args...) +} + +var StatementBuilder = &StatementBuilderType{} + +func (b *StatementBuilderType) Insert(table string) *StatementBuilderType { + return b +} + +func (b *StatementBuilderType) Columns(columns ...string) *StatementBuilderType { + return b +} + +func (b *StatementBuilderType) Values(strings ...string) *StatementBuilderType { + return b +} + +func (b *StatementBuilderType) Exec() { +} From 5911b7005a0ea897a97bf760f8e2912e81c2ce05 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Wed, 4 Mar 2020 05:19:52 -0800 Subject: [PATCH 04/14] Add tests for dependencies library --- .../go/dependencies/GoModDependency.expected | 60 ++++++ .../semmle/go/dependencies/GoModDependency.ql | 5 + .../semmle/go/dependencies/SemVer.expected | 50 +++++ .../semmle/go/dependencies/SemVer.ql | 11 + .../semmle/go/dependencies/ShaVer.expected | 23 ++ .../semmle/go/dependencies/ShaVer.ql | 4 + .../semmle/go/dependencies/codeql-go/go.mod | 8 + .../go/dependencies/fabric-snaps/LICENSE | 201 ++++++++++++++++++ .../go/dependencies/fabric-snaps/go.mod | 65 ++++++ .../go/dependencies/hrm-profile-tool/LICENSE | 21 ++ .../go/dependencies/hrm-profile-tool/go.mod | 22 ++ .../semmle/go/dependencies/sweb/LICENSE | 21 ++ .../semmle/go/dependencies/sweb/go.mod | 63 ++++++ 13 files changed, 554 insertions(+) create mode 100644 ql/test/library-tests/semmle/go/dependencies/GoModDependency.expected create mode 100644 ql/test/library-tests/semmle/go/dependencies/GoModDependency.ql create mode 100644 ql/test/library-tests/semmle/go/dependencies/SemVer.expected create mode 100644 ql/test/library-tests/semmle/go/dependencies/SemVer.ql create mode 100644 ql/test/library-tests/semmle/go/dependencies/ShaVer.expected create mode 100644 ql/test/library-tests/semmle/go/dependencies/ShaVer.ql create mode 100644 ql/test/library-tests/semmle/go/dependencies/codeql-go/go.mod create mode 100644 ql/test/library-tests/semmle/go/dependencies/fabric-snaps/LICENSE create mode 100644 ql/test/library-tests/semmle/go/dependencies/fabric-snaps/go.mod create mode 100644 ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/LICENSE create mode 100644 ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/go.mod create mode 100644 ql/test/library-tests/semmle/go/dependencies/sweb/LICENSE create mode 100644 ql/test/library-tests/semmle/go/dependencies/sweb/go.mod diff --git a/ql/test/library-tests/semmle/go/dependencies/GoModDependency.expected b/ql/test/library-tests/semmle/go/dependencies/GoModDependency.expected new file mode 100644 index 00000000000..de38b1a1c7b --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/GoModDependency.expected @@ -0,0 +1,60 @@ +| codeql-go/go.mod:6:2:6:25 | go.mod require line | golang.org/x/mod | v0.2.0 | golang.org/x/mod | v0.2.0 | +| codeql-go/go.mod:7:2:7:55 | go.mod require line | golang.org/x/tools | v0.0.0-20200302225559-9b52d559c609 | golang.org/x/tools | v0.0.0-20200302225559-9b52d559c609 | +| fabric-snaps/go.mod:4:2:4:34 | go.mod require line | github.com/DATA-DOG/godog | v0.7.4 | github.com/DATA-DOG/godog | v0.7.4 | +| fabric-snaps/go.mod:5:2:5:56 | go.mod require line | github.com/cactus/go-statsd-client | v3.1.1+incompatible | github.com/cactus/go-statsd-client | v3.1.1+incompatible | +| fabric-snaps/go.mod:6:2:6:64 | go.mod require line | github.com/cloudflare/cfssl | v0.0.0-20180323000720-5d63dbd981b5 | github.com/cloudflare/cfssl | v0.0.0-20180323000720-5d63dbd981b5 | +| fabric-snaps/go.mod:7:2:7:64 | go.mod require line | github.com/facebookgo/clock | v0.0.0-20150410010913-600d898af40a | github.com/facebookgo/clock | v0.0.0-20150410010913-600d898af40a | +| fabric-snaps/go.mod:8:2:8:42 | go.mod require line | github.com/fsouza/go-dockerclient | v1.3.0 | github.com/fsouza/go-dockerclient | v1.3.0 | +| fabric-snaps/go.mod:9:2:9:30 | go.mod require line | github.com/go-kit/kit | v0.7.0 | github.com/go-kit/kit | v0.7.0 | +| fabric-snaps/go.mod:10:2:10:36 | go.mod require line | github.com/go-logfmt/logfmt | v0.4.0 | github.com/go-logfmt/logfmt | v0.3.0 | +| fabric-snaps/go.mod:11:2:11:35 | go.mod require line | github.com/golang/protobuf | v1.2.0 | github.com/golang/protobuf | v1.2.0 | +| fabric-snaps/go.mod:12:2:12:82 | go.mod require line | github.com/google/certificate-transparency-go | v0.0.0-20180219093839-391726f8973d | github.com/google/certificate-transparency-go | v0.0.0-20180219093839-391726f8973d | +| fabric-snaps/go.mod:13:2:13:38 | go.mod require line | github.com/hyperledger/fabric | v1.4.0 | github.com/securekey/fabric-next | v0.0.0-20190216163058-9e08161f2597 | +| fabric-snaps/go.mod:14:2:14:73 | go.mod require line | github.com/hyperledger/fabric-sdk-go | v0.0.0-20190125204638-b490519efff9 | github.com/hyperledger/fabric-sdk-go | v0.0.0-20190125204638-b490519efff9 | +| fabric-snaps/go.mod:15:2:15:31 | go.mod require line | github.com/onsi/gomega | v1.5.0 | github.com/onsi/gomega | v1.4.2 | +| fabric-snaps/go.mod:16:2:16:61 | go.mod require line | github.com/op/go-logging | v0.0.0-20160315200505-970db520ece7 | github.com/op/go-logging | v0.0.0-20160315200505-970db520ece7 | +| fabric-snaps/go.mod:17:2:17:30 | go.mod require line | github.com/pkg/errors | v0.8.1 | github.com/pkg/errors | v0.8.0 | +| fabric-snaps/go.mod:18:2:18:54 | go.mod require line | github.com/rs/xid | v0.0.0-20170604230408-02dd45c33376 | github.com/rs/xid | v0.0.0-20170604230408-02dd45c33376 | +| fabric-snaps/go.mod:19:2:19:72 | go.mod require line | github.com/securekey/fabric-snaps/membershipsnap/pkg/membership | v0.0.0 | ./membershipsnap/pkg/membership | unknown | +| fabric-snaps/go.mod:20:2:20:56 | go.mod require line | github.com/securekey/fabric-snaps/util/rolesmgr | v0.4.0 | ./util/rolesmgr | unknown | +| fabric-snaps/go.mod:21:2:21:56 | go.mod require line | github.com/securekey/fabric-snaps/util/statemgr | v0.4.0 | ./util/statemgr | unknown | +| fabric-snaps/go.mod:22:2:22:31 | go.mod require line | github.com/spf13/cobra | v0.0.3 | github.com/spf13/cobra | v0.0.3 | +| fabric-snaps/go.mod:23:2:23:31 | go.mod require line | github.com/spf13/pflag | v1.0.3 | github.com/spf13/pflag | v1.0.3 | +| fabric-snaps/go.mod:24:2:24:59 | go.mod require line | github.com/spf13/viper | v0.0.0-20171227194143-aafc9e6bc7b7 | github.com/spf13/viper | v0.0.0-20171227194143-aafc9e6bc7b7 | +| fabric-snaps/go.mod:25:2:25:36 | go.mod require line | github.com/stretchr/testify | v1.3.0 | github.com/stretchr/testify | v1.2.2 | +| fabric-snaps/go.mod:26:2:26:46 | go.mod require line | github.com/uber-go/tally | v3.3.2+incompatible | github.com/uber-go/tally | v3.3.2+incompatible | +| fabric-snaps/go.mod:27:2:27:69 | go.mod require line | github.com/xeipuuv/gojsonpointer | v0.0.0-20170225233418-6fe8760cad35 | github.com/xeipuuv/gojsonpointer | v0.0.0-20170225233418-6fe8760cad35 | +| fabric-snaps/go.mod:28:2:28:71 | go.mod require line | github.com/xeipuuv/gojsonreference | v0.0.0-20150808065054-e02fc20de94c | github.com/xeipuuv/gojsonreference | v0.0.0-20150808065054-e02fc20de94c | +| fabric-snaps/go.mod:29:2:29:68 | go.mod require line | github.com/xeipuuv/gojsonschema | v0.0.0-20170528113821-0c8571ac0ce1 | github.com/xeipuuv/gojsonschema | v0.0.0-20170528113821-0c8571ac0ce1 | +| fabric-snaps/go.mod:30:2:30:56 | go.mod require line | golang.org/x/crypto | v0.0.0-20181001203147-e3636079e1a4 | golang.org/x/crypto | v0.0.0-20180827131323-e3636079e1a4 | +| fabric-snaps/go.mod:31:2:31:53 | go.mod require line | golang.org/x/net | v0.0.0-20181003013248-f5e5bdd77824 | golang.org/x/net | v0.0.0-20181003013248-f5e5bdd77824 | +| fabric-snaps/go.mod:32:2:32:55 | go.mod require line | golang.org/x/tools | v0.0.0-20181026183834-f60e5f99f081 | golang.org/x/tools | v0.0.0-20181026183834-f60e5f99f081 | +| fabric-snaps/go.mod:33:2:33:32 | go.mod require line | google.golang.org/grpc | v1.17.0 | google.golang.org/grpc | v1.15.0 | +| hrm-profile-tool/go.mod:4:2:4:61 | go.mod require line | github.com/ajstarks/svgo | v0.0.0-20180830174826-7338bd80e790 | github.com/ajstarks/svgo | v0.0.0-20180830174826-7338bd80e790 | +| hrm-profile-tool/go.mod:5:2:5:48 | go.mod require line | github.com/clj/hrm-profile-tool/cmd/hrm | v0.0.0 | ./cmd/hrm | unknown | +| hrm-profile-tool/go.mod:6:2:6:53 | go.mod require line | github.com/clj/hrm-profile-tool/instructions | v0.0.0 | ./instructions | unknown | +| hrm-profile-tool/go.mod:7:2:7:48 | go.mod require line | github.com/clj/hrm-profile-tool/profile | v0.0.0 | ./profile | unknown | +| hrm-profile-tool/go.mod:8:2:8:47 | go.mod require line | github.com/clj/hrm-profile-tool/render | v0.0.0 | ./render | unknown | +| sweb/go.mod:40:2:40:30 | go.mod require line | github.com/Joker/jade | v1.0.0 | github.com/Joker/jade | v1.0.0 | +| sweb/go.mod:41:2:41:66 | go.mod require line | github.com/Shopify/goreferrer | v0.0.0-20181106222321-ec9c9a553398 | github.com/Shopify/goreferrer | v0.0.0-20181106222321-ec9c9a553398 | +| sweb/go.mod:42:2:42:49 | go.mod require line | github.com/aymerick/raymond | v2.0.2+incompatible | github.com/aymerick/raymond | v2.0.2+incompatible | +| sweb/go.mod:43:2:43:59 | go.mod require line | github.com/eknkc/amber | v0.0.0-20171010120322-cdade1c07385 | github.com/eknkc/amber | v0.0.0-20171010120322-cdade1c07385 | +| sweb/go.mod:44:2:44:33 | go.mod require line | github.com/fatih/structs | v1.1.0 | github.com/fatih/structs | v1.1.0 | +| sweb/go.mod:45:2:45:61 | go.mod require line | github.com/flosch/pongo2 | v0.0.0-20190707114632-bbf5a6c351f4 | github.com/flosch/pongo2 | v0.0.0-20190707114632-bbf5a6c351f4 | +| sweb/go.mod:46:2:46:57 | go.mod require line | github.com/iris-contrib/blackfriday | v2.0.0+incompatible | github.com/iris-contrib/blackfriday | v2.0.0+incompatible | +| sweb/go.mod:47:2:47:71 | go.mod require line | github.com/iris-contrib/formBinder | v0.0.0-20190104093907-fbd5963f41e1 | github.com/iris-contrib/formBinder | v0.0.0-20190104093907-fbd5963f41e1 | +| sweb/go.mod:48:2:48:53 | go.mod require line | github.com/iris-contrib/go.uuid | v2.0.0+incompatible | github.com/iris-contrib/go.uuid | v2.0.0+incompatible | +| sweb/go.mod:49:2:49:36 | go.mod require line | github.com/json-iterator/go | v1.1.6 | github.com/json-iterator/go | v1.1.6 | +| sweb/go.mod:50:2:50:61 | go.mod require line | github.com/kataras/golog | v0.0.0-20190624001437-99c81de45f40 | github.com/kataras/golog | v0.0.0-20190624001437-99c81de45f40 | +| sweb/go.mod:51:2:51:46 | go.mod require line | github.com/kataras/iris | v11.1.1+incompatible | github.com/kataras/iris | v11.1.1+incompatible | +| sweb/go.mod:52:2:52:59 | go.mod require line | github.com/kataras/pio | v0.0.0-20190103105442-ea782b38602d | github.com/kataras/pio | v0.0.0-20190103105442-ea782b38602d | +| sweb/go.mod:53:2:53:38 | go.mod require line | github.com/klauspost/compress | v1.7.2 | github.com/klauspost/compress | v1.7.2 | +| sweb/go.mod:54:2:54:35 | go.mod require line | github.com/klauspost/cpuid | v1.2.1 | github.com/klauspost/cpuid | v1.2.1 | +| sweb/go.mod:55:2:55:43 | go.mod require line | github.com/microcosm-cc/bluemonday | v1.0.2 | github.com/microcosm-cc/bluemonday | v1.0.2 | +| sweb/go.mod:56:2:56:40 | go.mod require line | github.com/mitchellh/go-homedir | v1.1.0 | github.com/mitchellh/go-homedir | v1.1.0 | +| sweb/go.mod:57:2:57:68 | go.mod require line | github.com/modern-go/concurrent | v0.0.0-20180306012644-bacd9c7ef1dd | github.com/modern-go/concurrent | v0.0.0-20180306012644-bacd9c7ef1dd | +| sweb/go.mod:58:2:58:38 | go.mod require line | github.com/modern-go/reflect2 | v1.0.1 | github.com/modern-go/reflect2 | v1.0.1 | +| sweb/go.mod:59:2:59:51 | go.mod require line | github.com/ryanuber/columnize | v2.1.0+incompatible | github.com/ryanuber/columnize | v2.1.0+incompatible | +| sweb/go.mod:60:2:60:50 | go.mod require line | github.com/shurcooL/sanitized_anchor_name | v1.0.0 | github.com/shurcooL/sanitized_anchor_name | v1.0.0 | +| sweb/go.mod:61:2:61:31 | go.mod require line | github.com/spf13/cobra | v0.0.5 | github.com/spf13/cobra | v0.0.5 | +| sweb/go.mod:62:2:62:31 | go.mod require line | github.com/spf13/viper | v1.4.0 | github.com/spf13/viper | v1.4.0 | diff --git a/ql/test/library-tests/semmle/go/dependencies/GoModDependency.ql b/ql/test/library-tests/semmle/go/dependencies/GoModDependency.ql new file mode 100644 index 00000000000..646dd7b5cb7 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/GoModDependency.ql @@ -0,0 +1,5 @@ +import semmle.go.dependencies.Dependencies + +from GoModDependency dep, string origpath, string origver, string path, string ver +where dep.info(path, ver) and dep.originalInfo(origpath, origver) +select dep, origpath, origver, path, ver diff --git a/ql/test/library-tests/semmle/go/dependencies/SemVer.expected b/ql/test/library-tests/semmle/go/dependencies/SemVer.expected new file mode 100644 index 00000000000..84c864deea2 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/SemVer.expected @@ -0,0 +1,50 @@ +| v0.0.0-20150410010913-600d898af40a | 0.0.0 | +| v0.0.0-20150808065054-e02fc20de94c | 0.0.0 | +| v0.0.0-20160315200505-970db520ece7 | 0.0.0 | +| v0.0.0-20170225233418-6fe8760cad35 | 0.0.0 | +| v0.0.0-20170528113821-0c8571ac0ce1 | 0.0.0 | +| v0.0.0-20170604230408-02dd45c33376 | 0.0.0 | +| v0.0.0-20171010120322-cdade1c07385 | 0.0.0 | +| v0.0.0-20171227194143-aafc9e6bc7b7 | 0.0.0 | +| v0.0.0-20180219093839-391726f8973d | 0.0.0 | +| v0.0.0-20180306012644-bacd9c7ef1dd | 0.0.0 | +| v0.0.0-20180323000720-5d63dbd981b5 | 0.0.0 | +| v0.0.0-20180827131323-e3636079e1a4 | 0.0.0 | +| v0.0.0-20180830174826-7338bd80e790 | 0.0.0 | +| v0.0.0-20181003013248-f5e5bdd77824 | 0.0.0 | +| v0.0.0-20181026183834-f60e5f99f081 | 0.0.0 | +| v0.0.0-20181106222321-ec9c9a553398 | 0.0.0 | +| v0.0.0-20190103105442-ea782b38602d | 0.0.0 | +| v0.0.0-20190104093907-fbd5963f41e1 | 0.0.0 | +| v0.0.0-20190125204638-b490519efff9 | 0.0.0 | +| v0.0.0-20190216163058-9e08161f2597 | 0.0.0 | +| v0.0.0-20190624001437-99c81de45f40 | 0.0.0 | +| v0.0.0-20190707114632-bbf5a6c351f4 | 0.0.0 | +| v0.0.0-20200302225559-9b52d559c609 | 0.0.0 | +| v0.0.3 | 0.0.3 | +| v0.0.5 | 0.0.5 | +| v0.2.0 | 0.2.0 | +| v0.3.0 | 0.3.0 | +| v0.7.0 | 0.7.0 | +| v0.7.4 | 0.7.4 | +| v0.8.0 | 0.8.0 | +| v1.0.0 | 1.0.0 | +| v1.0.1 | 1.0.1 | +| v1.0.2 | 1.0.2 | +| v1.0.3 | 1.0.3 | +| v1.1.0 | 1.1.0 | +| v1.1.6 | 1.1.6 | +| v1.2.0 | 1.2.0 | +| v1.2.1 | 1.2.1 | +| v1.2.2 | 1.2.2 | +| v1.3.0 | 1.3.0 | +| v1.4.0 | 1.4.0 | +| v1.4.2 | 1.4.2 | +| v1.7.2 | 1.7.2 | +| v1.15.0 | 1.15.0 | +| v2.0.0+incompatible | 2.0.0 | +| v2.0.2+incompatible | 2.0.2 | +| v2.1.0+incompatible | 2.1.0 | +| v3.1.1+incompatible | 3.1.1 | +| v3.3.2+incompatible | 3.3.2 | +| v11.1.1+incompatible | 11.1.1 | diff --git a/ql/test/library-tests/semmle/go/dependencies/SemVer.ql b/ql/test/library-tests/semmle/go/dependencies/SemVer.ql new file mode 100644 index 00000000000..0c6b7374b94 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/SemVer.ql @@ -0,0 +1,11 @@ +import semmle.go.dependencies.SemVer + +from DependencySemVer ver, string normVer +where + exists(int major, int minor, int patch | + major = [0 .. 20] and minor = [0 .. 20] and patch = [0 .. 20] + | + normVer = major + "." + minor + "." + patch + ) and + ver.is(normVer) +select ver, normVer diff --git a/ql/test/library-tests/semmle/go/dependencies/ShaVer.expected b/ql/test/library-tests/semmle/go/dependencies/ShaVer.expected new file mode 100644 index 00000000000..8b3b364aff0 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/ShaVer.expected @@ -0,0 +1,23 @@ +| v0.0.0-20150410010913-600d898af40a | 600d898af40a | +| v0.0.0-20150808065054-e02fc20de94c | e02fc20de94c | +| v0.0.0-20160315200505-970db520ece7 | 970db520ece7 | +| v0.0.0-20170225233418-6fe8760cad35 | 6fe8760cad35 | +| v0.0.0-20170528113821-0c8571ac0ce1 | 0c8571ac0ce1 | +| v0.0.0-20170604230408-02dd45c33376 | 02dd45c33376 | +| v0.0.0-20171010120322-cdade1c07385 | cdade1c07385 | +| v0.0.0-20171227194143-aafc9e6bc7b7 | aafc9e6bc7b7 | +| v0.0.0-20180219093839-391726f8973d | 391726f8973d | +| v0.0.0-20180306012644-bacd9c7ef1dd | bacd9c7ef1dd | +| v0.0.0-20180323000720-5d63dbd981b5 | 5d63dbd981b5 | +| v0.0.0-20180827131323-e3636079e1a4 | e3636079e1a4 | +| v0.0.0-20180830174826-7338bd80e790 | 7338bd80e790 | +| v0.0.0-20181003013248-f5e5bdd77824 | f5e5bdd77824 | +| v0.0.0-20181026183834-f60e5f99f081 | f60e5f99f081 | +| v0.0.0-20181106222321-ec9c9a553398 | ec9c9a553398 | +| v0.0.0-20190103105442-ea782b38602d | ea782b38602d | +| v0.0.0-20190104093907-fbd5963f41e1 | fbd5963f41e1 | +| v0.0.0-20190125204638-b490519efff9 | b490519efff9 | +| v0.0.0-20190216163058-9e08161f2597 | 9e08161f2597 | +| v0.0.0-20190624001437-99c81de45f40 | 99c81de45f40 | +| v0.0.0-20190707114632-bbf5a6c351f4 | bbf5a6c351f4 | +| v0.0.0-20200302225559-9b52d559c609 | 9b52d559c609 | diff --git a/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql b/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql new file mode 100644 index 00000000000..19b9b319bdc --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql @@ -0,0 +1,4 @@ +import semmle.go.dependencies.SemVer + +from DependencySemShaVer ver +select ver, ver.getSha() diff --git a/ql/test/library-tests/semmle/go/dependencies/codeql-go/go.mod b/ql/test/library-tests/semmle/go/dependencies/codeql-go/go.mod new file mode 100644 index 00000000000..06ecc65d84a --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/codeql-go/go.mod @@ -0,0 +1,8 @@ +module github.com/github/codeql-go + +go 1.13 + +require ( + golang.org/x/mod v0.2.0 + golang.org/x/tools v0.0.0-20200302225559-9b52d559c609 +) diff --git a/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/LICENSE b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/LICENSE new file mode 100644 index 00000000000..8dada3edaf5 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/go.mod b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/go.mod new file mode 100644 index 00000000000..3751c58532a --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/go.mod @@ -0,0 +1,65 @@ +module github.com/securekey/fabric-snaps + +require ( + github.com/DATA-DOG/godog v0.7.4 + github.com/cactus/go-statsd-client v3.1.1+incompatible // indirect + github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 // indirect + github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect + github.com/fsouza/go-dockerclient v1.3.0 + github.com/go-kit/kit v0.7.0 + github.com/go-logfmt/logfmt v0.4.0 // indirect + github.com/golang/protobuf v1.2.0 + github.com/google/certificate-transparency-go v0.0.0-20180219093839-391726f8973d // indirect + github.com/hyperledger/fabric v1.4.0 + github.com/hyperledger/fabric-sdk-go v0.0.0-20190125204638-b490519efff9 + github.com/onsi/gomega v1.5.0 // indirect + github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 + github.com/pkg/errors v0.8.1 + github.com/rs/xid v0.0.0-20170604230408-02dd45c33376 + github.com/securekey/fabric-snaps/membershipsnap/pkg/membership v0.0.0 + github.com/securekey/fabric-snaps/util/rolesmgr v0.4.0 + github.com/securekey/fabric-snaps/util/statemgr v0.4.0 + github.com/spf13/cobra v0.0.3 + github.com/spf13/pflag v1.0.3 + github.com/spf13/viper v0.0.0-20171227194143-aafc9e6bc7b7 + github.com/stretchr/testify v1.3.0 + github.com/uber-go/tally v3.3.2+incompatible // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20170225233418-6fe8760cad35 // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20150808065054-e02fc20de94c // indirect + github.com/xeipuuv/gojsonschema v0.0.0-20170528113821-0c8571ac0ce1 + golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 + golang.org/x/net v0.0.0-20181003013248-f5e5bdd77824 + golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081 + google.golang.org/grpc v1.17.0 + +) + +replace github.com/hyperledger/fabric => github.com/securekey/fabric-next v0.0.0-20190216163058-9e08161f2597 + +replace github.com/docker/libnetwork => github.com/docker/libnetwork v0.0.0-20180608203834-19279f049241 + +replace github.com/docker/docker => github.com/docker/docker v0.0.0-20180827131323-0c5f8d2b9b23 + +replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20180827131323-e3636079e1a4 + +replace github.com/spf13/afero => github.com/spf13/afero v1.2.1 + +replace github.com/hashicorp/hcl => github.com/hashicorp/hcl v1.0.0 + +replace github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.3.0 + +replace github.com/stretchr/testify => github.com/stretchr/testify v1.2.2 + +replace github.com/onsi/gomega => github.com/onsi/gomega v1.4.2 + +replace github.com/securekey/fabric-snaps/util/rolesmgr => ./util/rolesmgr + +replace github.com/securekey/fabric-snaps/util/statemgr => ./util/statemgr + +replace github.com/securekey/fabric-snaps/membershipsnap/pkg/membership => ./membershipsnap/pkg/membership + +replace google.golang.org/grpc => google.golang.org/grpc v1.15.0 + +replace github.com/pkg/errors => github.com/pkg/errors v0.8.0 + +replace github.com/spf13/oldviper => github.com/spf13/viper v0.0.0-20150908122457-1967d93db724 diff --git a/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/LICENSE b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/LICENSE new file mode 100644 index 00000000000..2c54e25f712 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Christian Lyder Jacobsen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/go.mod b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/go.mod new file mode 100644 index 00000000000..4b0ac268e96 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/go.mod @@ -0,0 +1,22 @@ +module github.com/clj/hrm-profile-tool + +require ( + github.com/ajstarks/svgo v0.0.0-20180830174826-7338bd80e790 + github.com/clj/hrm-profile-tool/cmd/hrm v0.0.0 + github.com/clj/hrm-profile-tool/instructions v0.0.0 + github.com/clj/hrm-profile-tool/profile v0.0.0 + github.com/clj/hrm-profile-tool/render v0.0.0 + +) + +replace github.com/clj/hrm-profile-tool/cmd/hrm => ./cmd/hrm + +replace github.com/clj/hrm-profile-tool/profile => ./profile + +replace github.com/clj/hrm-profile-tool/instructions => ./instructions + +replace github.com/clj/hrm-profile-tool/render => ./render + +replace github.com/clj/hrm-profile-tool/utils/text => ./utils/text + +replace github.com/clj/hrm-profile-tool/utils/seekbufio => ./utils/seekbufio diff --git a/ql/test/library-tests/semmle/go/dependencies/sweb/LICENSE b/ql/test/library-tests/semmle/go/dependencies/sweb/LICENSE new file mode 100644 index 00000000000..108b937dfc3 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/sweb/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 ender + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/dependencies/sweb/go.mod b/ql/test/library-tests/semmle/go/dependencies/sweb/go.mod new file mode 100644 index 00000000000..096134411f9 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/sweb/go.mod @@ -0,0 +1,63 @@ +module github.com/xuender/sweb + +go 1.12 + +replace golang.org/x/text => github.com/golang/text v0.3.2 + +replace golang.org/x/net => github.com/golang/net v0.0.0-20190620200207-3b0461eec859 + +replace golang.org/x/crypto => github.com/golang/crypto v0.0.0-20190621222207-cc06ce4a13d4 + +replace golang.org/x/tools => github.com/golang/tools v0.0.0-20190625160430-252024b82959 + +replace golang.org/x/sync => github.com/golang/sync v0.0.0-20190423024810-112230192c58 + +replace golang.org/x/sys => github.com/golang/sys v0.0.0-20190624142023-c5567b49c5d0 + +replace cloud.google.com/go => github.com/googleapis/google-cloud-go v0.40.0 + +replace google.golang.org/genproto => github.com/google/go-genproto v0.0.0-20190620144150-6af8c5fc6601 + +replace golang.org/x/exp => github.com/golang/exp v0.0.0-20190510132918-efd6b22b2522 + +replace golang.org/x/time => github.com/golang/time v0.0.0-20190308202827-9d24e82272b4 + +replace golang.org/x/oauth2 => github.com/golang/oauth2 v0.0.0-20190604053449-0f29369cfe45 + +replace golang.org/x/lint => github.com/golang/lint v0.0.0-20190409202823-959b441ac422 + +replace google.golang.org/grpc => github.com/grpc/grpc-go v1.21.1 + +replace google.golang.org/api => github.com/googleapis/google-api-go-client v0.7.0 + +replace google.golang.org/appengine => github.com/golang/appengine v1.6.1 + +replace golang.org/x/mobile => github.com/golang/mobile v0.0.0-20190607214518-6fa95d984e88 + +replace golang.org/x/image => github.com/golang/image v0.0.0-20190622003408-7e034cad6442 + +require ( + github.com/Joker/jade v1.0.0 // indirect + github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 // indirect + github.com/aymerick/raymond v2.0.2+incompatible // indirect + github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 // indirect + github.com/iris-contrib/blackfriday v2.0.0+incompatible // indirect + github.com/iris-contrib/formBinder v0.0.0-20190104093907-fbd5963f41e1 // indirect + github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect + github.com/json-iterator/go v1.1.6 // indirect + github.com/kataras/golog v0.0.0-20190624001437-99c81de45f40 // indirect + github.com/kataras/iris v11.1.1+incompatible + github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d // indirect + github.com/klauspost/compress v1.7.2 // indirect + github.com/klauspost/cpuid v1.2.1 // indirect + github.com/microcosm-cc/bluemonday v1.0.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/ryanuber/columnize v2.1.0+incompatible // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/spf13/cobra v0.0.5 + github.com/spf13/viper v1.4.0 +) From dd3f98c5493efd12c492faf6f780e538383c7321 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Thu, 5 Mar 2020 01:56:57 -0800 Subject: [PATCH 05/14] extractor: Don't log directory being walked for go.mod files --- extractor/extractor.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/extractor/extractor.go b/extractor/extractor.go index ca99c51e87a..90c76193e4c 100644 --- a/extractor/extractor.go +++ b/extractor/extractor.go @@ -121,8 +121,6 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { cwd = rcwd } - log.Printf("Walking file tree from %s to discover go.mod files...", cwd) - goModPaths := make([]string, 0, 10) filepath.Walk(cwd, func(path string, info os.FileInfo, err error) error { From b27e63ba8334aaef1f62d539653072bfdd5a7726 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Thu, 5 Mar 2020 02:42:13 -0800 Subject: [PATCH 06/14] Address review comments Co-authored-by: Max Schaefer --- ql/src/semmle/go/GoModExpr.qll | 104 +++++++++++------- .../semmle/go/dependencies/Dependencies.qll | 15 ++- ql/src/semmle/go/dependencies/SemVer.qll | 10 +- .../semmle/go/GoModExpr/ExcludeLines.expected | 6 +- .../semmle/go/GoModExpr/ExcludeLines.ql | 5 +- .../semmle/go/GoModExpr/ReplaceLines.expected | 1 + .../semmle/go/GoModExpr/ReplaceLines.ql | 19 +++- .../semmle/go/GoModExpr/RequireLines.expected | 10 +- .../semmle/go/GoModExpr/RequireLines.ql | 5 +- .../semmle/go/dependencies/SemVer.ql | 8 +- .../semmle/go/dependencies/ShaVer.ql | 2 +- .../go/dependencies/fabric-snaps/README.md | 3 + .../dependencies/hrm-profile-tool/README.md | 3 + .../semmle/go/dependencies/sweb/README.md | 3 + 14 files changed, 119 insertions(+), 75 deletions(-) create mode 100644 ql/test/library-tests/semmle/go/dependencies/fabric-snaps/README.md create mode 100644 ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/README.md create mode 100644 ql/test/library-tests/semmle/go/dependencies/sweb/README.md diff --git a/ql/src/semmle/go/GoModExpr.qll b/ql/src/semmle/go/GoModExpr.qll index fced69266f7..959fd1a62fa 100644 --- a/ql/src/semmle/go/GoModExpr.qll +++ b/ql/src/semmle/go/GoModExpr.qll @@ -5,7 +5,7 @@ import go /** - * A go.mod expression. + * An expression in a go.mod file, which is used to declare dependencies. */ class GoModExpr extends @modexpr, GoModExprParent { /** @@ -22,6 +22,11 @@ class GoModExpr extends @modexpr, GoModExprParent { */ DocComment getComments() { result.getDocumentedElement() = this } + /** Gets path of the module of this go.mod expression. */ + string getModulePath() { + exists(GoModModuleLine mod | this.getFile() = mod.getFile() | result = mod.getPath()) + } + override string toString() { result = "go.mod expression" } } @@ -43,27 +48,13 @@ class GoModLine extends @modline, GoModExpr { } /** - * A line that contains the module information - */ -class GoModModuleLine extends GoModLine { - GoModModuleLine() { - this.getParent().(GoModLineBlock).getToken(0) = "module" - or - not this.getParent() instanceof GoModLineBlock and - this.getToken(0) = "module" - } - - string getPath() { - if this.getParent() instanceof GoModLineBlock - then result = this.getToken(1) - else result = this.getToken(0) - } - - override string toString() { result = "go.mod module line" } -} - -/** - * A factored block of lines, for example `require ( "path" )`. + * A factored block of lines, for example: + * ``` + * require ( + * "github.com/github/codeql-go" v1.2.3 + * "golang.org/x/tools" v3.2.1 + * ) + * ``` */ class GoModLineBlock extends @modlineblock, GoModExpr { /** @@ -75,17 +66,9 @@ class GoModLineBlock extends @modlineblock, GoModExpr { } /** - * A line that declares the Go version to be used, for example `go 1.14`. + * Gets the `i`th token of `line`, including the token in the line block declaration, if it there is + * one. */ -class GoModGoLine extends GoModLine { - GoModGoLine() { this.getToken(0) = "go" } - - /** Gets the Go version declared. */ - string getVer() { result = this.getToken(1) } - - override string toString() { result = "go.mod go line" } -} - private string getOffsetToken(GoModLine line, int i) { if line.getParent() instanceof GoModLineBlock then result = line.getToken(i - 1) @@ -93,7 +76,38 @@ private string getOffsetToken(GoModLine line, int i) { } /** - * A line that declares a requirement, for example `require "path"`. + * A line that contains the module information + */ +class GoModModuleLine extends GoModLine { + GoModModuleLine() { + this.getParent().(GoModLineBlock).getToken(0) = "module" + or + not this.getParent() instanceof GoModLineBlock and + this.getToken(0) = "module" + } + + /** + * Get the path of the module being declared. + */ + string getPath() { result = getOffsetToken(this, 1) } + + override string toString() { result = "go.mod module line" } +} + +/** + * A line that declares the Go version to be used, for example `go 1.14`. + */ +class GoModGoLine extends GoModLine { + GoModGoLine() { this.getToken(0) = "go" } + + /** Gets the Go version declared. */ + string getVersion() { result = this.getToken(1) } + + override string toString() { result = "go.mod go line" } +} + +/** + * A line that declares a requirement, for example `require "github.com/github/codeql-go" v1.2.3`. */ class GoModRequireLine extends GoModLine { GoModRequireLine() { @@ -107,13 +121,14 @@ class GoModRequireLine extends GoModLine { string getPath() { result = getOffsetToken(this, 1) } /** Gets the version of the dependency. */ - string getVer() { result = getOffsetToken(this, 2) } + string getVersion() { result = getOffsetToken(this, 2) } override string toString() { result = "go.mod require line" } } /** - * A line that declares a dependency version to exclude, for example `exclude "ver"`. + * A line that declares a dependency version to exclude, for example + * `exclude "github.com/github/codeql-go" v1.2.3`. */ class GoModExcludeLine extends GoModLine { GoModExcludeLine() { @@ -127,14 +142,14 @@ class GoModExcludeLine extends GoModLine { string getPath() { result = getOffsetToken(this, 1) } /** Gets the excluded version. */ - string getVer() { result = getOffsetToken(this, 2) } + string getVersion() { result = getOffsetToken(this, 2) } override string toString() { result = "go.mod exclude line" } } /** * A line that specifies a dependency to use instead of another one, for example - * `replace "a" => "b" ver`. + * `replace "golang.org/x/tools" => "github.com/golang/tools" v1.2.3`. */ class GoModReplaceLine extends GoModLine { GoModReplaceLine() { @@ -147,11 +162,22 @@ class GoModReplaceLine extends GoModLine { /** Gets the path of the dependency to be replaced. */ string getOriginalPath() { result = getOffsetToken(this, 1) } + /** Gets the path of the dependency to be replaced, if any. */ + string getOriginalVersion() { result = getOffsetToken(this, 2) and not result = "=>" } + /** Gets the path of the replacement dependency. */ - string getReplacementPath() { result = getOffsetToken(this, 3) } + string getReplacementPath() { + if exists(this.getOriginalVersion()) + then result = getOffsetToken(this, 4) + else result = getOffsetToken(this, 3) + } /** Gets the version of the replacement dependency. */ - string getReplacementVer() { result = getOffsetToken(this, 4) } + string getReplacementVersion() { + if exists(this.getOriginalVersion()) + then result = getOffsetToken(this, 5) + else result = getOffsetToken(this, 4) + } override string toString() { result = "go.mod replace line" } } diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll index 4972b0682e2..ad09b62e0e5 100644 --- a/ql/src/semmle/go/dependencies/Dependencies.qll +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -21,7 +21,7 @@ abstract class Dependency extends Locatable { string getDepPath() { this.info(result, _) } /** Gets the version of this dependency. */ - string getDepVer() { this.info(_, result) } + string getDepVersion() { this.info(_, result) } /** * An import of this dependency. @@ -51,9 +51,9 @@ class GoModDependency extends Dependency, GoModRequireLine { | path = replace.getReplacementPath() and ( - v = replace.getReplacementVer() + v = replace.getReplacementVersion() or - not exists(replace.getReplacementVer()) and + not exists(replace.getReplacementVersion()) and v = "unknown" ) ) @@ -62,17 +62,20 @@ class GoModDependency extends Dependency, GoModRequireLine { /** * Get a version that was excluded for this dependency. */ - string getAnExcludedVer() { + string getAnExcludedVersion() { exists(GoModExcludeLine exclude | exclude.getFile() = this.getFile() and exclude.getPath() = this.getPath() | - result = exclude.getVer() + result = exclude.getVersion() ) } /** * Holds if this require line originally states dependency `path` had version `ver`. + * + * The actual info of this dependency can change based on `replace` directives in the same go.mod + * file, which replace a dependency with another one. */ - predicate originalInfo(string path, string v) { path = this.getPath() and v = this.getVer() } + predicate originalInfo(string path, string v) { path = this.getPath() and v = this.getVersion() } } diff --git a/ql/src/semmle/go/dependencies/SemVer.qll b/ql/src/semmle/go/dependencies/SemVer.qll index a9c6161dd22..7dfb97e0a5c 100644 --- a/ql/src/semmle/go/dependencies/SemVer.qll +++ b/ql/src/semmle/go/dependencies/SemVer.qll @@ -10,7 +10,7 @@ class DependencySemVer extends string { string normalized; DependencySemVer() { - this = dep.getDepVer() and + this = dep.getDepVersion() and normalized = normalizeSemver(this) } @@ -76,10 +76,10 @@ private string normalizeSemver(string orig) { * * Pre-release information and build metadata is not yet supported. */ -class DependencySemShaVer extends DependencySemVer { +class DependencySemShaVersion extends DependencySemVer { string sha; - DependencySemShaVer() { sha = this.regexpCapture(".*-([0-9a-f]+)", 1) } + DependencySemShaVersion() { sha = this.regexpCapture(".*-([0-9a-f]+)", 1) } /** * Gets the commit SHA associated with this version. @@ -88,9 +88,9 @@ class DependencySemShaVer extends DependencySemVer { bindingset[other] override predicate is(string other) { - this.getSha() = other.(DependencySemShaVer).getSha() + this.getSha() = other.(DependencySemShaVersion).getSha() or - not other instanceof DependencySemShaVer and + not other instanceof DependencySemShaVersion and super.is(other) } } diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected index d23727f1726..b4025cd96ec 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected @@ -1,3 +1,3 @@ -| pkg1/go.mod:10:1:10:44 | go.mod exclude line | module | github.com/github/codeql-go | v1.23.1 | -| pkg2/go.mod:14:2:14:35 | go.mod exclude line | module | github.com/sirupsen/logrus | v1.4.2 | -| pkg2/go.mod:15:2:15:37 | go.mod exclude line | module | github.com/github/codeql-go | v1.23.1 | +| pkg1/go.mod:10:1:10:44 | go.mod exclude line | codeql-go-tests/gomod/dep1 | github.com/github/codeql-go | v1.23.1 | +| pkg2/go.mod:14:2:14:35 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/sirupsen/logrus | v1.4.2 | +| pkg2/go.mod:15:2:15:37 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/github/codeql-go | v1.23.1 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql index dfd2262b9b7..f469a5d5b21 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql +++ b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.ql @@ -1,5 +1,4 @@ import go -from GoModExcludeLine excl, GoModModuleLine mod -where excl.getFile() = mod.getFile() -select excl, mod.getPath(), excl.getPath(), excl.getVer() +from GoModExcludeLine excl +select excl, excl.getModulePath(), excl.getPath(), excl.getVersion() diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected index e69de29bb2d..8aec48809a2 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected @@ -0,0 +1 @@ +| pkg2/go.mod:5:1:5:55 | go.mod replace line | codeql-go-tests/gomod/dep2 | github.com/Masterminds/squirrel | no version | ../squirrel | no version | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql index 0e82e2eea9d..485a7c69c44 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql +++ b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.ql @@ -1,11 +1,18 @@ import go -from GoModReplaceLine repl, GoModModuleLine mod, string repVer +from GoModReplaceLine repl, string origVersion, string repVersion where - repl.getFile() = mod.getFile() and ( - repVer = repl.getReplacementVer() or - repVer = "no version" + repVersion = repl.getReplacementVersion() + or + not exists(repl.getReplacementVersion()) and + repVersion = "no version" + ) and + ( + origVersion = repl.getOriginalVersion() + or + not exists(repl.getOriginalVersion()) and + origVersion = "no version" ) -select repl, mod.getPath(), repl.getOriginalPath(), repl.getReplacementPath(), - repl.getReplacementVer() +select repl, repl.getModulePath(), repl.getOriginalPath(), origVersion, repl.getReplacementPath(), + repVersion diff --git a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected index df5da59bc87..49ec4d743be 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected @@ -1,5 +1,5 @@ -| pkg1/go.mod:6:2:6:67 | go.mod require line | module | github.com/github/codeql-go | v1.23.2-0.20200302182241-5e71a04fdf30 | -| pkg1/go.mod:7:2:7:55 | go.mod require line | module | golang.org/x/tools | v0.0.0-20200109174759-ac4f524c1612 | -| pkg2/go.mod:7:1:7:38 | go.mod require line | module | github.com/gorilla/mux | v1.7.4 | -| pkg2/go.mod:9:2:9:35 | go.mod require line | module | github.com/sirupsen/logrus | v1.4.1 | -| pkg2/go.mod:10:2:10:40 | go.mod require line | module | github.com/Masterminds/squirrel | v1.2.0 | +| pkg1/go.mod:6:2:6:67 | go.mod require line | codeql-go-tests/gomod/dep1 | github.com/github/codeql-go | v1.23.2-0.20200302182241-5e71a04fdf30 | +| pkg1/go.mod:7:2:7:55 | go.mod require line | codeql-go-tests/gomod/dep1 | golang.org/x/tools | v0.0.0-20200109174759-ac4f524c1612 | +| pkg2/go.mod:7:1:7:38 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/gorilla/mux | v1.7.4 | +| pkg2/go.mod:9:2:9:35 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/sirupsen/logrus | v1.4.1 | +| pkg2/go.mod:10:2:10:40 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/Masterminds/squirrel | v1.2.0 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql index 84854191b65..d3c1ebf3e75 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql +++ b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.ql @@ -1,5 +1,4 @@ import go -from GoModRequireLine req, GoModModuleLine mod -where req.getFile() = mod.getFile() -select req, mod.getPath(), req.getPath(), req.getVer() +from GoModRequireLine req +select req, req.getModulePath(), req.getPath(), req.getVersion() diff --git a/ql/test/library-tests/semmle/go/dependencies/SemVer.ql b/ql/test/library-tests/semmle/go/dependencies/SemVer.ql index 0c6b7374b94..15a5701673c 100644 --- a/ql/test/library-tests/semmle/go/dependencies/SemVer.ql +++ b/ql/test/library-tests/semmle/go/dependencies/SemVer.ql @@ -1,11 +1,11 @@ import semmle.go.dependencies.SemVer -from DependencySemVer ver, string normVer +from DependencySemVer ver, string normVersion where exists(int major, int minor, int patch | major = [0 .. 20] and minor = [0 .. 20] and patch = [0 .. 20] | - normVer = major + "." + minor + "." + patch + normVersion = major + "." + minor + "." + patch ) and - ver.is(normVer) -select ver, normVer + ver.is(normVersion) +select ver, normVersion diff --git a/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql b/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql index 19b9b319bdc..b85b5cbbfab 100644 --- a/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql +++ b/ql/test/library-tests/semmle/go/dependencies/ShaVer.ql @@ -1,4 +1,4 @@ import semmle.go.dependencies.SemVer -from DependencySemShaVer ver +from DependencySemShaVersion ver select ver, ver.getSha() diff --git a/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/README.md b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/README.md new file mode 100644 index 00000000000..343b9e55123 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/fabric-snaps/README.md @@ -0,0 +1,3 @@ +This is the go.mod and go.sum files from https://github.com/securekey/fabric-snaps, strictly for use in query testing. + +See the LICENSE file in this folder for information about the licensing of the original code. diff --git a/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/README.md b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/README.md new file mode 100644 index 00000000000..98ad865d147 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/hrm-profile-tool/README.md @@ -0,0 +1,3 @@ +This is the go.mod and go.sum files from https://github.com/clj/hrm-profile-tool, strictly for use in query testing. + +See the LICENSE file in this folder for information about the licensing of the original code. diff --git a/ql/test/library-tests/semmle/go/dependencies/sweb/README.md b/ql/test/library-tests/semmle/go/dependencies/sweb/README.md new file mode 100644 index 00000000000..549bdee8bf8 --- /dev/null +++ b/ql/test/library-tests/semmle/go/dependencies/sweb/README.md @@ -0,0 +1,3 @@ +This is the go.mod and go.sum files from https://github.com/xuender/sweb, strictly for use in query testing. + +See the LICENSE file in this folder for information about the licensing of the original code. From 78239accd5dd79ea0341d8691710b4dfa7c7983a Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Thu, 5 Mar 2020 02:52:13 -0800 Subject: [PATCH 07/14] Dependencies: Make getAnImport() more precise In particular, ensure that the go file importing the dependency is under the directory of the file where the dependency is declared. Co-authored-by: Max Schaefer --- ql/src/semmle/go/dependencies/Dependencies.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll index ad09b62e0e5..5b1afa6cda6 100644 --- a/ql/src/semmle/go/dependencies/Dependencies.qll +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -26,7 +26,12 @@ abstract class Dependency extends Locatable { /** * An import of this dependency. */ - ImportSpec getAnImport() { result.getPath() = this.getDepPath() } + ImportSpec getAnImport() { + result.getPath() = this.getDepPath() and + exists(Folder parent | parent.getAFile() = this.getFile() | + parent.getAFolder*().getAFile() = result.getFile() + ) + } } /** From 25577a81088086ef5c9ca62ac21c46782ad08957 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Thu, 5 Mar 2020 02:56:10 -0800 Subject: [PATCH 08/14] Remove DependencyCustomizations --- ql/src/semmle/go/dependencies/Dependencies.qll | 1 - ql/src/semmle/go/dependencies/DependencyCustomizations.qll | 1 - 2 files changed, 2 deletions(-) delete mode 100644 ql/src/semmle/go/dependencies/DependencyCustomizations.qll diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll index 5b1afa6cda6..5c41588b4f3 100644 --- a/ql/src/semmle/go/dependencies/Dependencies.qll +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -3,7 +3,6 @@ */ import go -private import semmle.go.dependencies.DependencyCustomizations /** * An abstract representation of a dependency. diff --git a/ql/src/semmle/go/dependencies/DependencyCustomizations.qll b/ql/src/semmle/go/dependencies/DependencyCustomizations.qll deleted file mode 100644 index 8b137891791..00000000000 --- a/ql/src/semmle/go/dependencies/DependencyCustomizations.qll +++ /dev/null @@ -1 +0,0 @@ - From 4b9cc87c2ebe7e3d23c3a58b18f87c3e587a533e Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 03:26:25 -0800 Subject: [PATCH 09/14] Add test for replace line with versions --- .../library-tests/semmle/go/GoModExpr/ExcludeLines.expected | 4 ++-- .../library-tests/semmle/go/GoModExpr/ReplaceLines.expected | 1 + .../library-tests/semmle/go/GoModExpr/RequireLines.expected | 6 +++--- ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected index b4025cd96ec..b94f4383c1b 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/ExcludeLines.expected @@ -1,3 +1,3 @@ | pkg1/go.mod:10:1:10:44 | go.mod exclude line | codeql-go-tests/gomod/dep1 | github.com/github/codeql-go | v1.23.1 | -| pkg2/go.mod:14:2:14:35 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/sirupsen/logrus | v1.4.2 | -| pkg2/go.mod:15:2:15:37 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/github/codeql-go | v1.23.1 | +| pkg2/go.mod:15:2:15:35 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/sirupsen/logrus | v1.4.2 | +| pkg2/go.mod:16:2:16:37 | go.mod exclude line | codeql-go-tests/gomod/dep2 | github.com/github/codeql-go | v1.23.1 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected index 8aec48809a2..7d4d0b310c4 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/ReplaceLines.expected @@ -1 +1,2 @@ | pkg2/go.mod:5:1:5:55 | go.mod replace line | codeql-go-tests/gomod/dep2 | github.com/Masterminds/squirrel | no version | ../squirrel | no version | +| pkg2/go.mod:6:1:6:79 | go.mod replace line | codeql-go-tests/gomod/dep2 | github.com/Sirupsen/logrus | v1.4.1 | github.com/sirupsen/logrus | v1.4.1 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected index 49ec4d743be..60a0dfedd56 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected +++ b/ql/test/library-tests/semmle/go/GoModExpr/RequireLines.expected @@ -1,5 +1,5 @@ | pkg1/go.mod:6:2:6:67 | go.mod require line | codeql-go-tests/gomod/dep1 | github.com/github/codeql-go | v1.23.2-0.20200302182241-5e71a04fdf30 | | pkg1/go.mod:7:2:7:55 | go.mod require line | codeql-go-tests/gomod/dep1 | golang.org/x/tools | v0.0.0-20200109174759-ac4f524c1612 | -| pkg2/go.mod:7:1:7:38 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/gorilla/mux | v1.7.4 | -| pkg2/go.mod:9:2:9:35 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/sirupsen/logrus | v1.4.1 | -| pkg2/go.mod:10:2:10:40 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/Masterminds/squirrel | v1.2.0 | +| pkg2/go.mod:8:1:8:38 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/gorilla/mux | v1.7.4 | +| pkg2/go.mod:10:2:10:35 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/Sirupsen/logrus | v1.4.1 | +| pkg2/go.mod:11:2:11:40 | go.mod require line | codeql-go-tests/gomod/dep2 | github.com/Masterminds/squirrel | v1.2.0 | diff --git a/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod index db778428e12..698fe145ad7 100644 --- a/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod +++ b/ql/test/library-tests/semmle/go/GoModExpr/pkg2/go.mod @@ -3,10 +3,11 @@ module codeql-go-tests/gomod/dep2 go 1.14 replace github.com/Masterminds/squirrel => ../squirrel +replace github.com/Sirupsen/logrus v1.4.1 => github.com/sirupsen/logrus v1.4.1 require github.com/gorilla/mux v1.7.4 require ( - github.com/sirupsen/logrus v1.4.1 + github.com/Sirupsen/logrus v1.4.1 github.com/Masterminds/squirrel v1.2.0 ) From 34f34e22413e4ad49076a3ffe4c766da6b49c64f Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 03:27:22 -0800 Subject: [PATCH 10/14] GoModExpr.qll: Rename getOffsetToken to GoModLine.getToken Also add getRawToken to do what getToken did before, and fix up documentation. --- ql/src/semmle/go/GoModExpr.qll | 104 +++++++++++++++++---------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/ql/src/semmle/go/GoModExpr.qll b/ql/src/semmle/go/GoModExpr.qll index 959fd1a62fa..c7acb09e44e 100644 --- a/ql/src/semmle/go/GoModExpr.qll +++ b/ql/src/semmle/go/GoModExpr.qll @@ -40,9 +40,40 @@ class GoModCommentBlock extends @modcommentblock, GoModExpr { } */ class GoModLine extends @modline, GoModExpr { /** - * Gets the `i`th token on this line. + * Gets the `i`th token on this line, 0-based. + * + * Generally, one should use `getToken`, as that accounts for lines inside of line blocks. */ - string getToken(int i) { modtokens(result, this, i) } + string getRawToken(int i) { modtokens(result, this, i) } + + /** + * Gets the `i`th token of `line`, including the token in the line block declaration, if it there is + * one, 0-based. + * + * This compensates for the fact that lines in line blocks have their 0th token in the line block + * declaration, and makes dealing with lines more uniform. + * + * For example, `.getToken(1)` will result in the dependency path (`github.com/github/codeql-go`) + * for both lines for normal require lines like `require "github.com/github/codeql-go" v1.2.3` and + * in a line block like + * + * ``` + * require ( + * "github.com/github/codeql-go" v1.2.3 + * ... + * ) + * ``` + * + * As a special case, when `i` is `0` and the line is in a line block, the result will be the + * token from the line block. + */ + string getToken(int i) { + i = 0 and result = this.getParent().(GoModLineBlock).getRawToken(0) + or + if this.getParent() instanceof GoModLineBlock + then result = this.getRawToken(i - 1) + else result = this.getRawToken(i) + } override string toString() { result = "go.mod line" } } @@ -58,38 +89,26 @@ class GoModLine extends @modline, GoModExpr { */ class GoModLineBlock extends @modlineblock, GoModExpr { /** - * Gets the `i`th token of this line block. + * Gets the `i`th token of this line block, 0-based. + * + * Usually one should not have to use this, as `GoModLine.getToken(0)` will get the token from its + * parent line block, if any. */ - string getToken(int i) { modtokens(result, this, i) } + string getRawToken(int i) { modtokens(result, this, i) } override string toString() { result = "go.mod line block" } } /** - * Gets the `i`th token of `line`, including the token in the line block declaration, if it there is - * one. - */ -private string getOffsetToken(GoModLine line, int i) { - if line.getParent() instanceof GoModLineBlock - then result = line.getToken(i - 1) - else result = line.getToken(i) -} - -/** - * A line that contains the module information + * A line that contains the module's package path, for example `module github.com/github/codeql-go`. */ class GoModModuleLine extends GoModLine { - GoModModuleLine() { - this.getParent().(GoModLineBlock).getToken(0) = "module" - or - not this.getParent() instanceof GoModLineBlock and - this.getToken(0) = "module" - } + GoModModuleLine() { this.getToken(0) = "module" } /** * Get the path of the module being declared. */ - string getPath() { result = getOffsetToken(this, 1) } + string getPath() { result = this.getToken(1) } override string toString() { result = "go.mod module line" } } @@ -110,18 +129,13 @@ class GoModGoLine extends GoModLine { * A line that declares a requirement, for example `require "github.com/github/codeql-go" v1.2.3`. */ class GoModRequireLine extends GoModLine { - GoModRequireLine() { - this.getParent().(GoModLineBlock).getToken(0) = "require" - or - not this.getParent() instanceof GoModLineBlock and - this.getToken(0) = "require" - } + GoModRequireLine() { this.getToken(0) = "require" } /** Gets the path of the dependency. */ - string getPath() { result = getOffsetToken(this, 1) } + string getPath() { result = this.getToken(1) } /** Gets the version of the dependency. */ - string getVersion() { result = getOffsetToken(this, 2) } + string getVersion() { result = this.getToken(2) } override string toString() { result = "go.mod require line" } } @@ -131,18 +145,13 @@ class GoModRequireLine extends GoModLine { * `exclude "github.com/github/codeql-go" v1.2.3`. */ class GoModExcludeLine extends GoModLine { - GoModExcludeLine() { - this.getParent().(GoModLineBlock).getToken(0) = "exclude" - or - not this.getParent() instanceof GoModLineBlock and - this.getToken(0) = "exclude" - } + GoModExcludeLine() { this.getToken(0) = "exclude" } /** Gets the path of the dependency to exclude a version of. */ - string getPath() { result = getOffsetToken(this, 1) } + string getPath() { result = this.getToken(1) } /** Gets the excluded version. */ - string getVersion() { result = getOffsetToken(this, 2) } + string getVersion() { result = this.getToken(2) } override string toString() { result = "go.mod exclude line" } } @@ -152,31 +161,26 @@ class GoModExcludeLine extends GoModLine { * `replace "golang.org/x/tools" => "github.com/golang/tools" v1.2.3`. */ class GoModReplaceLine extends GoModLine { - GoModReplaceLine() { - this.getParent().(GoModLineBlock).getToken(0) = "replace" - or - not this.getParent() instanceof GoModLineBlock and - this.getToken(0) = "replace" - } + GoModReplaceLine() { this.getToken(0) = "replace" } /** Gets the path of the dependency to be replaced. */ - string getOriginalPath() { result = getOffsetToken(this, 1) } + string getOriginalPath() { result = this.getToken(1) } /** Gets the path of the dependency to be replaced, if any. */ - string getOriginalVersion() { result = getOffsetToken(this, 2) and not result = "=>" } + string getOriginalVersion() { result = this.getToken(2) and not result = "=>" } /** Gets the path of the replacement dependency. */ string getReplacementPath() { if exists(this.getOriginalVersion()) - then result = getOffsetToken(this, 4) - else result = getOffsetToken(this, 3) + then result = this.getToken(4) + else result = this.getToken(3) } /** Gets the version of the replacement dependency. */ string getReplacementVersion() { if exists(this.getOriginalVersion()) - then result = getOffsetToken(this, 5) - else result = getOffsetToken(this, 4) + then result = this.getToken(5) + else result = this.getToken(4) } override string toString() { result = "go.mod replace line" } From 38596dddc0ecd527f4d8b70baa23f9457043aca1 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 03:35:11 -0800 Subject: [PATCH 11/14] Address review comments. Co-authored-by: Max Schaefer --- ql/src/semmle/go/dependencies/Dependencies.qll | 18 ++++++++++++++---- ql/src/semmle/go/dependencies/SemVer.qll | 4 ++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll index 5c41588b4f3..c38d4437380 100644 --- a/ql/src/semmle/go/dependencies/Dependencies.qll +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -22,14 +22,18 @@ abstract class Dependency extends Locatable { /** Gets the version of this dependency. */ string getDepVersion() { this.info(_, result) } + /** + * This dependency is relevant for imports in file `file`. That is, an import of this + * dependency's path that is in `file` will use this dependency. + */ + abstract predicate relevantForFile(File file); + /** * An import of this dependency. */ ImportSpec getAnImport() { result.getPath() = this.getDepPath() and - exists(Folder parent | parent.getAFile() = this.getFile() | - parent.getAFolder*().getAFile() = result.getFile() - ) + this.relevantForFile(result.getFile()) } } @@ -44,8 +48,14 @@ class GoModDependency extends Dependency, GoModRequireLine { this.originalInfo(path, v) } + override predicate relevantForFile(File file) { + exists(Folder parent | parent.getAFile() = this.getFile() | + parent.getAFolder*().getAFile() = file + ) + } + /** - * Holds if there is a replace line that replaces this dependency with a dependency to `path`, + * Holds if there is a replace line that replaces this dependency with a dependency on `path`, * version `v`. */ predicate replacementInfo(string path, string v) { diff --git a/ql/src/semmle/go/dependencies/SemVer.qll b/ql/src/semmle/go/dependencies/SemVer.qll index 7dfb97e0a5c..fd079291dc3 100644 --- a/ql/src/semmle/go/dependencies/SemVer.qll +++ b/ql/src/semmle/go/dependencies/SemVer.qll @@ -1,3 +1,7 @@ +/** + * Provides classes for dealing with semantic versions, for strings that dependency's versions. + */ + import semmle.go.dependencies.Dependencies /** From 555b0a9527447882bb55e7308719029e0f421df1 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 03:42:27 -0800 Subject: [PATCH 12/14] Add a GoModFile class --- ql/src/go.qll | 2 +- ql/src/semmle/go/{GoModExpr.qll => GoMod.qll} | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) rename ql/src/semmle/go/{GoModExpr.qll => GoMod.qll} (92%) diff --git a/ql/src/go.qll b/ql/src/go.qll index d2dc498b6f2..dfdd54726cf 100644 --- a/ql/src/go.qll +++ b/ql/src/go.qll @@ -9,7 +9,7 @@ import semmle.go.Concepts import semmle.go.Decls import semmle.go.Expr import semmle.go.Files -import semmle.go.GoModExpr +import semmle.go.GoMod import semmle.go.Locations import semmle.go.Packages import semmle.go.Scopes diff --git a/ql/src/semmle/go/GoModExpr.qll b/ql/src/semmle/go/GoMod.qll similarity index 92% rename from ql/src/semmle/go/GoModExpr.qll rename to ql/src/semmle/go/GoMod.qll index c7acb09e44e..0cabb7359b7 100644 --- a/ql/src/semmle/go/GoModExpr.qll +++ b/ql/src/semmle/go/GoMod.qll @@ -4,6 +4,16 @@ import go +/** A go.mod file. */ +class GoModFile extends File { + GoModFile() { this.getBaseName() = "go.mod" } + + /** + * Gets the module declaration of this file, that is, the line declaring the path of this module. + */ + GoModModuleLine getModuleDeclaration() { result.getFile() = this } +} + /** * An expression in a go.mod file, which is used to declare dependencies. */ @@ -22,10 +32,10 @@ class GoModExpr extends @modexpr, GoModExprParent { */ DocComment getComments() { result.getDocumentedElement() = this } + override GoModFile getFile() { result = GoModExprParent.super.getFile() } + /** Gets path of the module of this go.mod expression. */ - string getModulePath() { - exists(GoModModuleLine mod | this.getFile() = mod.getFile() | result = mod.getPath()) - } + string getModulePath() { result = this.getFile().getModuleDeclaration().getPath() } override string toString() { result = "go.mod expression" } } From 43fbf47da31290ceeb3f79c41392eface013f0c6 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 06:42:25 -0800 Subject: [PATCH 13/14] Add a change note about go.mod extraction --- change-notes/1.24/extractor-go.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.24/extractor-go.md b/change-notes/1.24/extractor-go.md index dedba0b1499..744d4732f86 100644 --- a/change-notes/1.24/extractor-go.md +++ b/change-notes/1.24/extractor-go.md @@ -5,3 +5,4 @@ ## Changes to code extraction * The autobuilder now runs Makefiles or custom build scripts present in the codebase to install dependencies. +* The extractor now supports extracting go.mod files, enabling queries on dependencies and their versions. From 3d88032f81824eb79aa7b23a76fbda1f6a8d7b70 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 6 Mar 2020 06:44:12 -0800 Subject: [PATCH 14/14] Address review comments. Co-authored-by: Max Schaefer --- ql/src/semmle/go/GoMod.qll | 2 +- ql/src/semmle/go/dependencies/Dependencies.qll | 2 +- ql/src/semmle/go/dependencies/SemVer.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ql/src/semmle/go/GoMod.qll b/ql/src/semmle/go/GoMod.qll index 0cabb7359b7..63a01b72c14 100644 --- a/ql/src/semmle/go/GoMod.qll +++ b/ql/src/semmle/go/GoMod.qll @@ -1,5 +1,5 @@ /** - * Provides classes for working with go.mod expressions. + * Provides classes for working with go.mod files. */ import go diff --git a/ql/src/semmle/go/dependencies/Dependencies.qll b/ql/src/semmle/go/dependencies/Dependencies.qll index c38d4437380..9bf5e5c4726 100644 --- a/ql/src/semmle/go/dependencies/Dependencies.qll +++ b/ql/src/semmle/go/dependencies/Dependencies.qll @@ -23,7 +23,7 @@ abstract class Dependency extends Locatable { string getDepVersion() { this.info(_, result) } /** - * This dependency is relevant for imports in file `file`. That is, an import of this + * Holds if this dependency is relevant for imports in file `file`. That is, an import of this * dependency's path that is in `file` will use this dependency. */ abstract predicate relevantForFile(File file); diff --git a/ql/src/semmle/go/dependencies/SemVer.qll b/ql/src/semmle/go/dependencies/SemVer.qll index fd079291dc3..88d37563931 100644 --- a/ql/src/semmle/go/dependencies/SemVer.qll +++ b/ql/src/semmle/go/dependencies/SemVer.qll @@ -1,5 +1,5 @@ /** - * Provides classes for dealing with semantic versions, for strings that dependency's versions. + * Provides classes for dealing with semantic versions, for dependency versions. */ import semmle.go.dependencies.Dependencies