Remove repo contents after migration

The contents of this repository have been migrated
to the `github/codeql` repository,
specifically https://github.com/github/codeql/tree/main/go.

See https://github.com/github/codeql-go/issues/741 for details.

Remove the contents of this repo, keeping only licensing and repo docs,
so that users who clone both the `codeql` and `codeql-go` repos
do not end up with conflicting source files, particularly CodeQL packs.
This commit is contained in:
Aditya Sharad 2022-09-02 17:19:26 -07:00
Родитель 2471d3c4da
Коммит b8a54aa916
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 66D1E528054C320C
2271 изменённых файлов: 0 добавлений и 198978 удалений

Просмотреть файл

@ -1,20 +0,0 @@
{
"provide": [
"ql/src/qlpack.yml",
"ql/lib/qlpack.yml",
"ql/examples/qlpack.yml",
"ql/test/qlpack.yml",
"ql/config/legacy-support/qlpack.yml",
"build/codeql-extractor-go/codeql-extractor.yml"
],
"ignore": [
"the-extractor-which-needs-to-be-built"
],
"versionPolicies": {
"default": {
"requireChangeNotes": true,
"committedPrereleaseSuffix": "dev",
"committedVersion": "nextPatchRelease"
}
}
}

Просмотреть файл

@ -1,10 +0,0 @@
{
"extensions": [
"github.vscode-codeql",
"slevesque.vscode-zipexplorer"
],
"settings": {
"codeQL.runningQueries.memory": 2048,
"codeQL.runningQueries.debug": true
}
}

6
.gitattributes поставляемый
Просмотреть файл

@ -1,6 +0,0 @@
# Force git not to modify line endings for go or html files under the ql directory
ql/**/*.go -text
ql/**/*.html -text
# Force git not to modify line endings for dbschemes
*.dbscheme -text

4
.github/codeql/codeql-config.yml поставляемый
Просмотреть файл

@ -1,4 +0,0 @@
name: "CodeQL config"
queries:
- uses: security-and-quality

Просмотреть файл

@ -1,14 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-query-format",
"pattern": [
{
"regexp": "^((.*) would change by autoformatting\\.)$",
"file": 2,
"message": 1
}
]
}
]
}

Просмотреть файл

@ -1,17 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-syntax-check",
"pattern": [
{
"regexp": "^((ERROR|WARNING): .* \\((.*):(\\d+),(\\d+)-\\d+\\))$",
"message": 1,
"file": 3,
"line": 4,
"col": 5,
"severity": 2
}
]
}
]
}

14
.github/problem-matchers/codeql-test-run.json поставляемый
Просмотреть файл

@ -1,14 +0,0 @@
{
"problemMatcher": [
{
"owner": "codeql-test-run",
"pattern": [
{
"regexp": "(\\[.*\\] FAILED\\((RESULT|COMPILATION)\\) (.*))$",
"file": 3,
"message": 1
}
]
}
]
}

13
.github/problem-matchers/make.json поставляемый
Просмотреть файл

@ -1,13 +0,0 @@
{
"problemMatcher": [
{
"owner": "make",
"pattern": [
{
"regexp": "^(make: \\*\\*\\* .*)$",
"message": 1
}
]
}
]
}

33
.github/workflows/check-change-note.yml поставляемый
Просмотреть файл

@ -1,33 +0,0 @@
on:
pull_request_target:
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
paths:
- "ql/src/**/*.ql"
- "ql/src/**/*.qll"
- "!**/experimental/**"
jobs:
check-change-note:
runs-on: ubuntu-latest
steps:
- name: Check if change note file is present
uses: dorny/paths-filter@7c0f15b688b020e95e00f15c61299b022f08ca95 # v2.8.0
id: paths_filter
with:
filters: |
change_note:
- '**/change-notes/*.md'
- name: Get PR labels
id: pr-labels
uses: joerick/pr-labels-action@0a4cc4ee0ab557ec0b1ae1157fa6fa7f9f4c494b # v1.0.6
- name: Fail if change note is missing
uses: actions/github-script@v3
if: |
github.event.pull_request.draft == false &&
steps.paths_filter.outputs.change_note == 'false' &&
!contains(steps.pr-labels.outputs.labels, ' no-change-note-required ')
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
core.setFailed('No change note found.' +
' Either add one, or add the `no-change-note-required` label.')

143
.github/workflows/codeqltest.yml поставляемый
Просмотреть файл

@ -1,143 +0,0 @@
name: CodeQL tests
on: [pull_request]
jobs:
test-linux:
name: Test Linux (Ubuntu)
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.18.1
uses: actions/setup-go@v1
with:
go-version: 1.18.1
id: go
- name: Set up CodeQL CLI
run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd $HOME
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q codeql-linux64.zip
rm -f codeql-linux64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Check out code
uses: actions/checkout@v2
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: env PATH=$PATH:$HOME/codeql make
- name: Check that all QL and Go code is autoformatted
run: env PATH=$PATH:$HOME/codeql make check-formatting
- name: Compile qhelp files to markdown
run: env PATH=$PATH:$HOME/codeql QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown
- name: Upload qhelp markdown
uses: actions/upload-artifact@v2
with:
name: qhelp-markdown
path: qhelp-out/**/*.md
- name: Test
run: env PATH=$PATH:$HOME/codeql make test
test-mac:
name: Test MacOS
runs-on: macOS-latest
steps:
- name: Set up Go 1.18.1
uses: actions/setup-go@v1
with:
go-version: 1.18.1
id: go
- name: Set up CodeQL CLI
run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd $HOME
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-osx64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q codeql-osx64.zip
rm -f codeql-osx64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Check out code
uses: actions/checkout@v2
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: env PATH=$PATH:$HOME/codeql make
- name: Test
run: env PATH=$PATH:$HOME/codeql make test
test-win:
name: Test Windows
runs-on: windows-2019
steps:
- name: Set up Go 1.18.1
uses: actions/setup-go@v1
with:
go-version: 1.18.1
id: go
- name: Set up CodeQL CLI
run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd "$HOME"
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-win64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q -o codeql-win64.zip
unzip -q -o codeql-win64.zip codeql/codeql.exe
rm -f codeql-win64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
shell:
bash
- name: Check out code
uses: actions/checkout@v2
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: |
$Env:Path += ";$HOME\codeql"
make
- name: Test
run: |
$Env:Path += ";$HOME\codeql"
make test

25
.gitignore поставляемый
Просмотреть файл

@ -1,28 +1,3 @@
# editor and OS artifacts
*~
.DS_STORE
# query compilation caches
.cache
# build artifacts
build/*
# qltest projects and artifacts
ql/test/**/*.testproj
ql/test/**/*.actual
ql/test/**/go.sum
# Java class files
**/*.class
# binaries
tools/bin
tools/linux64
tools/osx64
tools/win64
tools/tokenizer.jar
main
# QL pack output directories
.codeql

Просмотреть файл

@ -1,5 +0,0 @@
path_classifiers:
test:
- ql/test
example:
- ql/src

142
Makefile
Просмотреть файл

@ -1,142 +0,0 @@
all: extractor ql/lib/go.dbscheme install-deps
ifeq ($(OS),Windows_NT)
EXE = .exe
CODEQL_PLATFORM = win64
else
EXE =
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CODEQL_PLATFORM = linux64
endif
ifeq ($(UNAME_S),Darwin)
CODEQL_PLATFORM = osx64
endif
endif
CODEQL_TOOLS = $(addprefix codeql-tools/,autobuild.cmd autobuild.sh pre-finalize.cmd pre-finalize.sh index.cmd index.sh linux64 osx64 win64 tracing-config.lua)
EXTRACTOR_PACK_OUT = build/codeql-extractor-go
BINARIES = go-extractor go-tokenizer go-autobuilder go-build-runner go-bootstrap go-gen-dbscheme
.PHONY: tools tools-codeql tools-codeql-full clean autoformat \
tools-linux64 tools-osx64 tools-win64 check-formatting
clean:
rm -rf tools/bin tools/linux64 tools/osx64 tools/win64 tools/net tools/opencsv
rm -rf $(EXTRACTOR_PACK_OUT) build/stats build/testdb
DATAFLOW_BRANCH=main
autoformat:
find ql -iregex '.*\.qll?' -print0 | xargs -0 codeql query format -qq -i
find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -w
check-formatting:
find ql -iregex '.*\.qll?' -print0 | xargs -0 codeql query format --check-only
test -z "$$(find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -l)"
install-deps:
bash scripts/install-deps.sh $(CODEQL_LOCK_MODE)
ifeq ($(QHELP_OUT_DIR),)
# If not otherwise specified, compile qhelp to markdown in place
QHELP_OUT_DIR := ql/src
endif
qhelp-to-markdown:
scripts/qhelp-to-markdown.sh ql/src "$(QHELP_OUT_DIR)"
tools: $(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))) tools/tokenizer.jar
.PHONY: $(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES)))
$(addsuffix $(EXE),$(addprefix tools/bin/,$(BINARIES))):
go build -mod=vendor -o $@ ./extractor/cli/$(basename $(@F))
tools-codeql: tools-$(CODEQL_PLATFORM)
tools-codeql-full: tools-linux64 tools-osx64 tools-win64
tools-linux64: $(addprefix tools/linux64/,$(BINARIES))
.PHONY: $(addprefix tools/linux64/,$(BINARIES))
$(addprefix tools/linux64/,$(BINARIES)):
GOOS=linux GOARCH=amd64 go build -mod=vendor -o $@ ./extractor/cli/$(@F)
tools-osx64: $(addprefix tools/osx64/,$(BINARIES))
.PHONY: $(addprefix tools/osx64/,$(BINARIES))
$(addprefix tools/osx64/,$(BINARIES)):
GOOS=darwin GOARCH=amd64 go build -mod=vendor -o $@ ./extractor/cli/$(@F)
tools-win64: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES)))
.PHONY: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES)))
$(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))):
env GOOS=windows GOARCH=amd64 go build -mod=vendor -o $@ ./extractor/cli/$(basename $(@F))
.PHONY: extractor-common extractor extractor-full install-deps
extractor-common: codeql-extractor.yml LICENSE ql/lib/go.dbscheme \
tools/tokenizer.jar $(CODEQL_TOOLS)
rm -rf $(EXTRACTOR_PACK_OUT)
mkdir -p $(EXTRACTOR_PACK_OUT)
cp codeql-extractor.yml LICENSE ql/lib/go.dbscheme ql/lib/go.dbscheme.stats $(EXTRACTOR_PACK_OUT)
mkdir $(EXTRACTOR_PACK_OUT)/tools
cp -r tools/tokenizer.jar $(CODEQL_TOOLS) $(EXTRACTOR_PACK_OUT)/tools
extractor: extractor-common tools-codeql
cp -r tools/$(CODEQL_PLATFORM) $(EXTRACTOR_PACK_OUT)/tools
extractor-full: extractor-common tools-codeql-full
cp -r $(addprefix tools/,linux64 osx64 win64) $(EXTRACTOR_PACK_OUT)/tools
tools/tokenizer.jar: tools/net/sourceforge/pmd/cpd/GoLanguage.class
jar cf $@ -C tools net
jar uf $@ -C tools opencsv
tools/net/sourceforge/pmd/cpd/GoLanguage.class: extractor/net/sourceforge/pmd/cpd/GoLanguage.java
javac -cp extractor -d tools $<
rm tools/net/sourceforge/pmd/cpd/AbstractLanguage.class
rm tools/net/sourceforge/pmd/cpd/SourceCode.class
rm tools/net/sourceforge/pmd/cpd/TokenEntry.class
rm tools/net/sourceforge/pmd/cpd/Tokenizer.class
ql/lib/go.dbscheme: tools/$(CODEQL_PLATFORM)/go-gen-dbscheme$(EXE)
$< $@
build/stats/src.stamp:
mkdir -p $(@D)/src
git clone 'https://github.com/golang/tools' $(@D)/src
git -C $(@D)/src checkout 9b52d559c609 -q
touch $@
ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor
rm -rf build/stats/database
codeql database create -l go -s build/stats/src -j4 --search-path . build/stats/database
codeql dataset measure -o $@ build/stats/database/db-go
test: all build/testdb/check-upgrade-path
codeql test run ql/test --search-path . --consistency-queries ql/test/consistency
# use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported
env GOOS=linux GOARCH=386 codeql$(EXE) test run ql/test/query-tests/Security/CWE-681 --search-path . --consistency-queries ql/test/consistency
cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]"
bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1)
.PHONY: build/testdb/check-upgrade-path
build/testdb/check-upgrade-path : build/testdb/go.dbscheme ql/lib/go.dbscheme
codeql dataset upgrade build/testdb --search-path ql/lib
diff -q build/testdb/go.dbscheme ql/lib/go.dbscheme
.PHONY: build/testdb/go.dbscheme
build/testdb/go.dbscheme: ql/lib/upgrades/initial/go.dbscheme
rm -rf build/testdb
echo >build/empty.trap
codeql dataset import -S ql/lib/upgrades/initial/go.dbscheme build/testdb build/empty.trap
.PHONY: sync-dataflow-libraries
sync-dataflow-libraries:
for f in DataFlowImpl.qll DataFlowImpl2.qll DataFlowImplCommon.qll DataFlowImplConsistency.qll tainttracking1/TaintTrackingImpl.qll tainttracking2/TaintTrackingImpl.qll FlowSummaryImpl.qll AccessPathSyntax.qll;\
do\
curl -s -o ./ql/lib/semmle/go/dataflow/internal/$$f https://raw.githubusercontent.com/github/codeql/$(DATAFLOW_BRANCH)/java/ql/lib/semmle/code/java/dataflow/internal/$$f;\
done

Просмотреть файл

@ -1,3 +0,0 @@
precision = ("veryhigh", "high", "medium", "low")
severity = ("error", "warning", "recommendation")
security = ("true", "false")

Просмотреть файл

Просмотреть файл

@ -1,14 +0,0 @@
name: "go"
display_name: "Go"
version: 0.1.0
pull_request_triggers:
- "**/go.mod"
- "**/glide.yaml"
- "**/Gopkg.toml"
column_kind: "utf8"
file_types:
- name: go
display_name: Go
extensions:
- .go
legacy_qltest_extraction: true

Просмотреть файл

@ -1,15 +0,0 @@
@echo off
SETLOCAL EnableDelayedExpansion
rem Some legacy environment variables for the autobuilder.
set LGTM_SRC=%CD%
if "%CODEQL_EXTRACTOR_GO_BUILD_TRACING%"=="on" (
echo "Tracing enabled"
type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/%CODEQL_PLATFORM%/go-build-runner.exe"
) else (
type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/%CODEQL_PLATFORM%/go-autobuilder.exe"
)
exit /b %ERRORLEVEL%
ENDLOCAL

Просмотреть файл

@ -1,19 +0,0 @@
#!/bin/sh
set -eu
if [ "$CODEQL_PLATFORM" != "linux64" ] && [ "$CODEQL_PLATFORM" != "osx64" ] ; then
echo "Automatic build detection for $CODEQL_PLATFORM is not implemented."
exit 1
fi
# Some legacy environment variables used by the autobuilder.
LGTM_SRC="$(pwd)"
export LGTM_SRC
if [ "${CODEQL_EXTRACTOR_GO_BUILD_TRACING:-}" = "on" ]; then
echo "Tracing enabled"
"$CODEQL_EXTRACTOR_GO_ROOT/tools/$CODEQL_PLATFORM/go-build-runner"
else
"$CODEQL_EXTRACTOR_GO_ROOT/tools/$CODEQL_PLATFORM/go-autobuilder"
fi

Просмотреть файл

@ -1,8 +0,0 @@
@echo off
SETLOCAL EnableDelayedExpansion
type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/%CODEQL_PLATFORM%/go-extractor.exe" -mod=vendor ./...
type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/pre-finalize.cmd"
exit /b %ERRORLEVEL%
ENDLOCAL

Просмотреть файл

@ -1,11 +0,0 @@
#!/bin/sh
set -eu
if [ "$CODEQL_PLATFORM" != "linux64" ] && [ "$CODEQL_PLATFORM" != "osx64" ] ; then
echo "Automatic build detection for $CODEQL_PLATFORM is not implemented."
exit 1
fi
"$CODEQL_EXTRACTOR_GO_ROOT/tools/$CODEQL_PLATFORM/go-extractor" -mod=vendor ./...
"$CODEQL_EXTRACTOR_GO_ROOT/tools/pre-finalize.sh"

Просмотреть файл

@ -1,7 +0,0 @@
**/go-autobuilder:
order compiler
trace no
**/go:
invoke ${config_dir}/go-extractor
prepend --mimic
prepend "${compiler}"

Просмотреть файл

@ -1,7 +0,0 @@
**/go-autobuilder:
order compiler
trace no
**/go:
invoke ${config_dir}/go-extractor
prepend --mimic
prepend "${compiler}"

Просмотреть файл

@ -1,19 +0,0 @@
@echo off
SETLOCAL EnableDelayedExpansion
if NOT "%CODEQL_EXTRACTOR_GO_EXTRACT_HTML%"=="no" (
type NUL && "%CODEQL_DIST%/codeql.exe" database index-files ^
--working-dir=. ^
--include-extension=.htm ^
--include-extension=.html ^
--include-extension=.xhtm ^
--include-extension=.xhtml ^
--include-extension=.vue ^
--size-limit 10m ^
--language html ^
-- ^
"%CODEQL_EXTRACTOR_GO_WIP_DATABASE%" ^
|| echo "HTML extraction failed; continuing"
exit /b %ERRORLEVEL%
)

Просмотреть файл

@ -1,18 +0,0 @@
#!/bin/sh
set -eu
if [ "${CODEQL_EXTRACTOR_GO_EXTRACT_HTML:-yes}" != "no" ]; then
"$CODEQL_DIST/codeql" database index-files \
--working-dir=. \
--include-extension=.htm \
--include-extension=.html \
--include-extension=.xhtm \
--include-extension=.xhtml \
--include-extension=.vue \
--size-limit 10m \
--language html \
-- \
"$CODEQL_EXTRACTOR_GO_WIP_DATABASE" \
|| echo "HTML extraction failed; continuing."
fi

Просмотреть файл

@ -1,29 +0,0 @@
function RegisterExtractorPack()
local goExtractor = GetPlatformToolsDirectory() .. 'go-extractor'
local patterns = {
CreatePatternMatcher({'^go-autobuilder$'}, MatchCompilerName, nil,
{trace = false}),
CreatePatternMatcher({'^go$'}, MatchCompilerName, goExtractor, {
prepend = {'--mimic', '${compiler}'},
order = ORDER_BEFORE
})
}
if OperatingSystem == 'windows' then
goExtractor = goExtractor .. 'go-extractor.exe'
patterns = {
CreatePatternMatcher({'^go-autobuilder%.exe$'}, MatchCompilerName,
nil, {trace = false}),
CreatePatternMatcher({'^go%.exe$'}, MatchCompilerName, goExtractor,
{
prepend = {'--mimic', '"${compiler}"'},
order = ORDER_BEFORE
})
}
end
return patterns
end
-- Return a list of minimum supported versions of the configuration file format
-- return one entry per supported major version.
function GetCompatibleVersions() return {'1.0.0'} end

Просмотреть файл

@ -1,7 +0,0 @@
**/go-autobuilder.exe:
order compiler
trace no
**/go.exe:
invoke ${config_dir}/go-extractor.exe
prepend --mimic
prepend "${compiler}"

Просмотреть файл

@ -1,490 +0,0 @@
Abstract syntax tree classes for working with Go programs
=========================================================
CodeQL has a large selection of classes for representing the abstract syntax tree of Go programs.
.. include:: ../../reusables/abstract-syntax-tree.rst
Statement classes
-----------------
This table lists all subclasses of `Stmt <https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__.
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Statement syntax | CodeQL class | Superclasses | Remarks |
+===================================================================================================================+===================================================================================================================+===============================================================================================================+===================================================================================================================+
| ``;`` | EmptyStmt_ | | |
| | | | |
| | .. _EmptyStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$EmptyStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ | ExprStmt_ | | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ExprStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExprStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``{`` Stmt_ ``...`` ``}`` | BlockStmt_ | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``if`` Expr_ BlockStmt_ | IfStmt_ | | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _IfStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IfStmt.html | | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``if`` Expr_ BlockStmt_ ``else`` Stmt_ | | | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``if`` Stmt_\ ``;`` Expr_ BlockStmt_ | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``for`` Expr_ BlockStmt_ | ForStmt_ | LoopStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ForStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ForStmt.html | .. _LoopStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LoopStmt.html | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``for`` Stmt_\ ``;`` Expr_\ ``;`` Stmt_ BlockStmt_ | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``for`` Expr_ ``...`` ``=`` ``range`` Expr_ BlockStmt_ | RangeStmt_ | LoopStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RangeStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RangeStmt.html | .. _LoopStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LoopStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``switch`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | ExpressionSwitchStmt_ | SwitchStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ExpressionSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExpressionSwitchStmt.html | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html | |
| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``switch`` Stmt_\ ``;`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``switch`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | TypeSwitchStmt_ | SwitchStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _TypeSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$TypeSwitchStmt.html | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html | |
| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``switch`` SimpleAssignStmt_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | |
| | | | |
| .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | | | |
| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``switch`` Stmt_\ ``;`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``select`` ``{`` CommClause_ ``...`` ``}`` | SelectStmt_ | | |
| | | | |
| .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html | .. _SelectStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SelectStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``return`` | ReturnStmt_ | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``return`` Expr_ ``...`` | .. _ReturnStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ReturnStmt.html | | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``break`` | BreakStmt_ | BranchStmt_ | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``break`` LabelName_ | .. _BreakStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BreakStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | |
| | | | |
| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``continue`` | ContinueStmt_ | BranchStmt_ | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``continue`` LabelName_ | .. _ContinueStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ContinueStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | |
| | | | |
| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``goto`` LabelName_ | GotoStmt_ | BranchStmt_ | |
| | | | |
| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | .. _GotoStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$GotoStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``fallthrough`` | FallthroughStmt_ | BranchStmt_ | can only occur as final non-empty child of a CaseClause_ in an ExpressionSwitchStmt_ |
| | | | |
| | .. _FallthroughStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$FallthroughStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html |
| | | | .. _ExpressionSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExpressionSwitchStmt.html |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| LabelName_\ ``:`` Stmt_ | LabeledStmt_ | | |
| | | | |
| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | .. _LabeledStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LabeledStmt.html | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``var`` VariableName_ TypeName_ | DeclStmt_ | | |
| | | | |
| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | .. _DeclStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DeclStmt.html | | |
| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``const`` VariableName_ ``=`` Expr_ | | | |
| | | | |
| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``type`` TypeName_ TypeExpr_ | | | |
| | | | |
| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | |
| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``type`` TypeName_ ``=`` TypeExpr_ | | | |
| | | | |
| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | |
| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``...`` ``=`` Expr_ ``...`` | AssignStmt_ | SimpleAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AssignStmt.html | .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| VariableName_ ``...`` ``:=`` Expr_ ``...`` | DefineStmt_ | SimpleAssignStmt_, Assignment_ | |
| | | | |
| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | .. _DefineStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DefineStmt.html | .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``+=`` Expr_ | AddAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AddAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AddAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``-=`` Expr_ | SubAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _SubAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SubAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _MulAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$MulAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``/=`` Expr_ | QuoAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _QuoAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$QuoAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``%=`` Expr_ | RemAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RemAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RemAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _MulAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$MulAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``&=`` Expr_ | AndAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AndAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AndAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``|=`` Expr_ | OrAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _OrAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$OrAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``^=`` Expr_ | XorAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _XorAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$XorAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``<<=`` Expr_ | ShlAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ShlAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ShlAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``>>=`` Expr_ | ShrAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ShrAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ShrAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``&^=`` Expr_ | AndNotAssignStmt_ | CompoundAssignStmt_, Assignment_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AndNotAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AndNotAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``++`` | IncStmt_ | IncDecStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _IncStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncStmt.html | .. _IncDecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncDecStmt.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``--`` | DecStmt_ | IncDecStmt_ | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _DecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DecStmt.html | .. _IncDecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncDecStmt.html | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``go`` CallExpr_ | GoStmt_ | | |
| | | | |
| .. _CallExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html | .. _GoStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$GoStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``defer`` CallExpr_ | DeferStmt_ | | |
| | | | |
| .. _CallExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html | .. _DeferStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DeferStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``<-`` Expr_ | SendStmt_ | | |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _SendStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SendStmt.html | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``case`` Expr_ ``...``\ ``:`` Stmt_ ``...`` | CaseClause_ | | can only occur as child of a SwitchStmt_ |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``case`` TypeExpr_ ``...``\ ``:`` Stmt_ ``...`` | | | |
| | | | |
| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``default:`` Stmt_ ``...`` | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| ``case`` SendStmt_\ ``:`` Stmt_ ``...`` | CommClause_ | | can only occur as child of a SelectStmt_ |
| | | | |
| .. _SendStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SendStmt.html | .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html | | .. _SelectStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SelectStmt.html |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``case`` RecvStmt_\ ``:`` Stmt_ ``...`` | | | |
| | | | |
| .. _RecvStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RecvStmt.html | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| ``default:`` Stmt_ ``...`` | | | |
| | | | |
| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| Expr_ ``...`` ``=`` RecvExpr_ | RecvStmt_ | | can only occur as child of a CommClause_ |
| | | | |
| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RecvStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RecvStmt.html | | .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html |
| .. _RecvExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+ | | |
| VariableName_ ``...`` ``:=`` RecvExpr_ | | | |
| | | | |
| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | | | |
| .. _RecvExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html | | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
| (anything unparseable) | BadStmt_ | | |
| | | | |
| | .. _BadStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BadStmt.html | | |
+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+
Expression classes
------------------
There are many expression classes, so we present them by category.
All classes in this section are subclasses of
`Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__.
Literals
~~~~~~~~
All classes in this subsection are subclasses of
`Literal <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Literal.html>`__.
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Expression syntax example | CodeQL class | Superclass |
+=========================================+==============================================================================================+==============================================================================================================================================================================================================+
| ``23`` | `IntLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$IntLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``4.2`` | `FloatLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FloatLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``4.2 + 2.7i`` | `ImagLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ImagLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``'a'`` | `CharLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CharLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``"Hello"`` | `StringLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StringLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``func(x, y int) int { return x + y }`` | `FuncLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FuncLit.html>`__ | `FuncDef <https://help.semmle.com/qldoc/go/semmle/go/Decls.qll/type.Decls$FuncDef.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``[6]int{1, 2, 3, 5}`` | `ArrayLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArrayLit.html>`__ | `ArrayOrSliceLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArrayOrSliceLit.html>`__, `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``[]int{1, 2, 3, 5}`` | `SliceLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SliceLit.html>`__ | `ArrayOrSliceLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArrayOrSliceLit.html>`__, `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``map[string]int{"A": 1, "B": 2}`` | `MapLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MapLit.html>`__ | `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``Point3D{0.5, -0.5, 0.5}`` | `StructLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StructLit.html>`__ | `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ |
+-----------------------------------------+----------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Unary expressions
~~~~~~~~~~~~~~~~~
All classes in this subsection are subclasses of
`UnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$UnaryExpr.html>`__.
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| Expression syntax | CodeQL class | Superclasses |
+============================================================================================+========================================================================================================+==================================================================================================================+
| ``+``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `PlusExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$PlusExpr.html>`__ | `ArithmeticUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticUnaryExpr.html>`__ |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| ``-``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `MinusExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MinusExpr.html>`__ | `ArithmeticUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticUnaryExpr.html>`__ |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| ``!``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `NotExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$NotExpr.html>`__ | `LogicalUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalUnaryExpr.html>`__ |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| ``^``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ComplementExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ComplementExpr.html>`__ | `BitwiseUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseUnaryExpr.html>`__ |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| ``&``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AddressExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AddressExpr.html>`__ | |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| ``<-``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `RecvExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html>`__ | |
+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
Binary expressions
~~~~~~~~~~~~~~~~~~
All classes in this subsection are subclasses of
`BinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BinaryExpr.html>`__.
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| Expression syntax | CodeQL class | Superclasses |
+==============================================================================================================================================================================+================================================================================================+============================================================================================================================+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``*`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `MulExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MulExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``/`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `QuoExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$QuoExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``%`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `RemExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RemExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``+`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AddExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AddExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``-`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `SubExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SubExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<<`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ShlExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShlExpr.html>`__ | `ShiftExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShiftExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>>`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ShrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShrExpr.html>`__ | `ShiftExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShiftExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&&`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LandExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LandExpr.html>`__ | `LogicalBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``||`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LorExpr.html>`__ | `LogicalBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LssExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LssExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `GtrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$GtrExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LeqExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `GeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$GeqExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``==`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `EqlExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqlExpr.html>`__ | `EqualityTestExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqualityTestExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``!=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `NeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$NeqExpr.html>`__ | `EqualityTestExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqualityTestExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AndExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AndExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``|`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `OrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$OrExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``^`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `XorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$XorExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&^`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AndNotExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AndNotExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+
Type expressions
~~~~~~~~~~~~~~~~
All classes in this subsection are subclasses of
`TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| Expression syntax | CodeQL class | Superclasses |
+=========================================================================================================================================================================================================+====================================================================================================================+====================================================================================================+
| ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `ArrayTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArrayTypeExpr.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``struct { ... }`` | `StructTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StructTypeExpr.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``func`` `FunctionName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FunctionName.html>`__\ ``(...) (...)`` | `FuncTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FuncTypeExpr.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``interface { ... }`` | `InterfaceTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$InterfaceTypeExpr.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``map[``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``]``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `MapTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MapTypeExpr.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``chan<-`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `SendChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SendChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``<-chan`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `RecvChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| ``chan`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `SendRecvChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SendRecvChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
Name expressions
~~~~~~~~~~~~~~~~
All classes in this subsection are subclasses of
`Name <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Name.html>`__.
The following classes relate to the structure of the name.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| Expression syntax | CodeQL class | Superclasses |
+===================================================================================================================================================================================+======================================================================================================+====================================================================================================+
| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `SimpleName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SimpleName.html>`__ | `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__\ ``.``\ `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `QualifiedName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$QualifiedName.html>`__ | `SelectorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SelectorExpr.html>`__ |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+
The following classes relate to what sort of entity the name refers to.
- `PackageName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$PackageName.html>`__
- `TypeName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html>`__
- `LabelName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html>`__
- `ValueName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ValueName.html>`__
- `ConstantName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ConstantName.html>`__
- `VariableName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html>`__
- `FunctionName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FunctionName.html>`__
Miscellaneous
~~~~~~~~~~~~~
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Expression syntax | CodeQL class | Superclasses | Remarks |
+============================================================================================================================================================================================================================================================================================================================================================================+========================================================================================================+====================================================================================================================+==========================================================================================================================================================================================================================+
| ``foo`` | `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``_`` | `BlankIdent <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BlankIdent.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``...`` | `Ellipsis <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ellipsis.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``(``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``)`` | `ParenExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ParenExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__\ ``.``\ `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `SelectorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SelectorExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` | `IndexExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$IndexExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` | `SliceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SliceExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``.(``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``)`` | `TypeAssertExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeAssertExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``*``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `StarExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StarExpr.html>`__ | | can be a `ValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ValueExpr.html>`__ or `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ depending on context |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `KeyValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$KeyValueExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``(``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``)`` | `ConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ConversionExpr.html>`__ | `CallOrConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallOrConversionExpr.html>`__ | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``(...)`` | `CallExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html>`__ | `CallOrConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallOrConversionExpr.html>`__ | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| (anything unparseable) | `BadExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BadExpr.html>`__ | | |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
The following classes organize expressions by the kind of entity they refer to.
+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| CodeQL class | Explanation |
+======================================================================================================+=========================================================================================================================================================================================================================================================+
| `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | an expression that denotes a type |
+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `ReferenceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ReferenceExpr.html>`__ | an expression that refers to a variable, a constant, a function, a field, or an element of an array or a slice |
+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `ValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BadExpr.html>`__ | an expression that can be evaluated to a value (as opposed to expressions that refer to a package, a type, or a statement label). This generalizes `ReferenceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ReferenceExpr.html>`__ |
+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Further reading
---------------
.. include:: ../../reusables/go-further-reading.rst
.. include:: ../../reusables/codeql-ref-tools-further-reading.rst

Просмотреть файл

@ -1,122 +0,0 @@
Modeling data flow in Go libraries
==================================
When analyzing a Go program, CodeQL does not examine the source code for
external packages. To track the flow of untrusted data through a library, you
can create a model of the library.
You can find existing models in the ``ql/src/semmle/go/frameworks/`` folder of the
`CodeQL for Go repository <https://github.com/github/codeql-go/tree/main/ql/src/semmle/go/frameworks>`__.
To add a new model, you should make a new file in that folder, named after the library.
Sources
-------
To mark a source of data that is controlled by an untrusted user, we
create a class extending ``UntrustedFlowSource::Range``. Inheritance and
the characteristic predicate of the class should be used to specify
exactly the dataflow node that introduces the data. Here is a short
example from ``Mux.qll``.
.. code-block:: ql
class RequestVars extends DataFlow::UntrustedFlowSource::Range, DataFlow::CallNode {
RequestVars() { this.getTarget().hasQualifiedName("github.com/gorilla/mux", "Vars") }
}
This has the effect that all calls to `the function Vars from the
package mux <http://www.gorillatoolkit.org/pkg/mux#Vars>`__ are
treated as sources of untrusted data.
Flow propagation
----------------
By default, we assume that all functions in libraries do not have
any data flow. To indicate that a particular function does have data flow,
create a class extending ``TaintTracking::FunctionModel`` (or
``DataFlow::FunctionModel`` if the untrusted user data is passed on
without being modified).
Inheritance and the characteristic predicate of the class should specify
the function. The class should also have a member predicate with the signature
``override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp)``
(or
``override predicate hasDataFlow(FunctionInput inp, FunctionOutput outp)``
if extending ``DataFlow::FunctionModel``). The body should constrain
``inp`` and ``outp``.
``FunctionInput`` is an abstract representation of the inputs to a
function. The options are:
* the receiver (``inp.isReceiver()``)
* one of the parameters (``inp.isParameter(i)``)
* one of the results (``inp.isResult(i)``, or ``inp.isResult`` if there is only one result)
Note that it may seem strange that the result of a function could be
considered as a function input, but it is needed in some cases. For
instance, the function ``bufio.NewWriter`` returns a writer ``bw`` that
buffers write operations to an underlying writer ``w``. If tainted data
is written to ``bw``, then it makes sense to propagate that taint back
to the underlying writer ``w``, which can be modeled by saying that
``bufio.NewWriter`` propagates taint from its result to its first
argument.
Similarly, ``FunctionOutput`` is an abstract representation of the
outputs to a function. The options are:
* the receiver (``outp.isReceiver()``)
* one of the parameters (``outp.isParameter(i)``)
* one of the results (``outp.isResult(i)``, or ``outp.isResult`` if there is only one result)
Here is an example from ``Gin.qll``, which has been slightly simplified.
.. code-block:: ql
private class ParamsGet extends TaintTracking::FunctionModel, Method {
ParamsGet() { this.hasQualifiedName("github.com/gin-gonic/gin", "Params", "Get") }
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
inp.isReceiver() and outp.isResult(0)
}
}
This has the effect that calls to the ``Get`` method with receiver type
``Params`` from the ``gin-gonic/gin`` package allow taint to flow from
the receiver to the first result. In other words, if ``p`` has type
``Params`` and taint can flow to it, then after the line
``x := p.Get("foo")`` taint can also flow to ``x``.
Sanitizers
----------
It is not necessary to indicate that library functions are sanitizers.
Their bodies are not analyzed, so it is assumed that data does not
flow through them.
Sinks
-----
Data-flow sinks are specified by queries rather than by library models.
However, you can use library models to indicate when functions belong to
special categories. Queries can then use these categories when specifying
sinks. Classes representing these special categories are contained in
``ql/src/semmle/go/Concepts.qll`` in the `CodeQL for Go repository
<https://github.com/github/codeql-go/blob/main/ql/src/semmle/go/Concepts.qll>`__.
``Concepts.qll`` includes classes for logger mechanisms,
HTTP response writers, HTTP redirects, and marshaling and unmarshaling
functions.
Here is a short example from ``Stdlib.qll``, which has been slightly simplified.
.. code-block:: ql
private class PrintfCall extends LoggerCall::Range, DataFlow::CallNode {
PrintfCall() { this.getTarget().hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
override DataFlow::Node getAMessageComponent() { result = this.getAnArgument() }
}
This has the effect that any call to ``Print``, ``Printf``, or
``Println`` in the package ``fmt`` is recognized as a logger call.
Any query that uses logger calls as a sink will then identify when tainted data
has been passed as an argument to ``Print``, ``Printf``, or ``Println``.

Просмотреть файл

@ -1,41 +0,0 @@
class Expr_ extends @expr {
string toString() { result = "Expr" }
}
class ExprParent_ extends @exprparent {
string toString() { result = "ExprParent" }
}
/**
* Two new kinds have been inserted such that `@sliceexpr` which used to have
* index 13 now has index 15. Another new kind has been inserted such that
* `@plusexpr` which used to have index 23 now has index 26. Entries with
* indices lower than 13 are unchanged.
*/
bindingset[new_index]
int old_index(int new_index) {
if new_index < 13
then result = new_index
else
if new_index = [13, 14]
then result = 0 // badexpr
else
if new_index < 23
then result + (15 - 13) = new_index
else
if new_index = 23
then result = 0 // badexpr
else result + (26 - 23) = new_index
}
// The schema for exprs is:
//
// exprs(unique int id: @expr,
// int kind: int ref,
// int parent: @exprparent ref,
// int idx: int ref);
from Expr_ expr, int new_kind, ExprParent_ parent, int idx, int old_kind
where
exprs(expr, new_kind, parent, idx) and
old_kind = old_index(new_kind)
select expr, old_kind, parent, idx

Просмотреть файл

@ -1,531 +0,0 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* XML Files
*/
xmlEncoding(
unique int id: @file ref,
string encoding: string ref
);
xmlDTDs(
unique int id: @xmldtd,
string root: string ref,
string publicId: string ref,
string systemId: string ref,
int fileid: @file ref
);
xmlElements(
unique int id: @xmlelement,
string name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref
);
xmlAttrs(
unique int id: @xmlattribute,
int elementid: @xmlelement ref,
string name: string ref,
string value: string ref,
int idx: int ref,
int fileid: @file ref
);
xmlNs(
int id: @xmlnamespace,
string prefixName: string ref,
string URI: string ref,
int fileid: @file ref
);
xmlHasNs(
int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref
);
xmlComments(
unique int id: @xmlcomment,
string text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref
);
xmlChars(
unique int id: @xmlcharacters,
string text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref
);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(
int xmlElement: @xmllocatable ref,
int location: @location_default ref
);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
compilations(unique int id: @compilation, string cwd: string ref);
#keyset[id, num]
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
#keyset[id, num, kind]
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
#keyset[id, num]
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
string full_error_message: string ref, int location: @location ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref);
folders(unique int id: @folder, string name: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
has_ellipsis(int id: @callorconversionexpr ref);
variadic(int id: @signaturetype ref);
@container = @file | @folder;
@locatable = @xmllocatable | @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
| @comment_group | @comment;
@documentable = @file | @field | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @sliceexpr
| 14 = @typeassertexpr
| 15 = @callorconversionexpr
| 16 = @starexpr
| 17 = @keyvalueexpr
| 18 = @arraytypeexpr
| 19 = @structtypeexpr
| 20 = @functypeexpr
| 21 = @interfacetypeexpr
| 22 = @maptypeexpr
| 23 = @plusexpr
| 24 = @minusexpr
| 25 = @notexpr
| 26 = @complementexpr
| 27 = @derefexpr
| 28 = @addressexpr
| 29 = @arrowexpr
| 30 = @lorexpr
| 31 = @landexpr
| 32 = @eqlexpr
| 33 = @neqexpr
| 34 = @lssexpr
| 35 = @leqexpr
| 36 = @gtrexpr
| 37 = @geqexpr
| 38 = @addexpr
| 39 = @subexpr
| 40 = @orexpr
| 41 = @xorexpr
| 42 = @mulexpr
| 43 = @quoexpr
| 44 = @remexpr
| 45 = @shlexpr
| 46 = @shrexpr
| 47 = @andexpr
| 48 = @andnotexpr
| 49 = @sendchantypeexpr
| 50 = @recvchantypeexpr
| 51 = @sendrcvchantypeexpr
| 52 = @errorexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typedefspec
| 3 = @aliasspec;
@typespec = @typedefspec | @aliasspec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @arraytype
| 27 = @slicetype
| 28 = @structtype
| 29 = @pointertype
| 30 = @interfacetype
| 31 = @tupletype
| 32 = @signaturetype
| 33 = @maptype
| 34 = @sendchantype
| 35 = @recvchantype
| 36 = @sendrcvchantype
| 37 = @namedtype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @containertype | @structtype | @pointertype | @interfacetype | @tupletype | @signaturetype | @namedtype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

Просмотреть файл

@ -1,547 +0,0 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* XML Files
*/
xmlEncoding(
unique int id: @file ref,
string encoding: string ref
);
xmlDTDs(
unique int id: @xmldtd,
string root: string ref,
string publicId: string ref,
string systemId: string ref,
int fileid: @file ref
);
xmlElements(
unique int id: @xmlelement,
string name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref
);
xmlAttrs(
unique int id: @xmlattribute,
int elementid: @xmlelement ref,
string name: string ref,
string value: string ref,
int idx: int ref,
int fileid: @file ref
);
xmlNs(
int id: @xmlnamespace,
string prefixName: string ref,
string URI: string ref,
int fileid: @file ref
);
xmlHasNs(
int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref
);
xmlComments(
unique int id: @xmlcomment,
string text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref
);
xmlChars(
unique int id: @xmlcharacters,
string text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref
);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(
int xmlElement: @xmllocatable ref,
int location: @location_default ref
);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
compilations(unique int id: @compilation, string cwd: string ref);
#keyset[id, num]
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
#keyset[id, num, kind]
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
#keyset[id, num]
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
string full_error_message: string ref, int location: @location ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref);
folders(unique int id: @folder, string name: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
has_ellipsis(int id: @callorconversionexpr ref);
variadic(int id: @signaturetype ref);
#keyset[parent, idx]
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
int parent: @typeparamparentobject ref, int idx: int ref);
@container = @file | @folder;
@locatable = @xmllocatable | @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
| @scopenode | @comment_group | @comment;
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@typeparamdeclparent = @funcdecl | @typespec;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @genericfunctioninstantiationexpr
| 14 = @generictypeinstantiationexpr
| 15 = @sliceexpr
| 16 = @typeassertexpr
| 17 = @callorconversionexpr
| 18 = @starexpr
| 19 = @keyvalueexpr
| 20 = @arraytypeexpr
| 21 = @structtypeexpr
| 22 = @functypeexpr
| 23 = @interfacetypeexpr
| 24 = @maptypeexpr
| 25 = @typesetliteralexpr
| 26 = @plusexpr
| 27 = @minusexpr
| 28 = @notexpr
| 29 = @complementexpr
| 30 = @derefexpr
| 31 = @addressexpr
| 32 = @arrowexpr
| 33 = @lorexpr
| 34 = @landexpr
| 35 = @eqlexpr
| 36 = @neqexpr
| 37 = @lssexpr
| 38 = @leqexpr
| 39 = @gtrexpr
| 40 = @geqexpr
| 41 = @addexpr
| 42 = @subexpr
| 43 = @orexpr
| 44 = @xorexpr
| 45 = @mulexpr
| 46 = @quoexpr
| 47 = @remexpr
| 48 = @shlexpr
| 49 = @shrexpr
| 50 = @andexpr
| 51 = @andnotexpr
| 52 = @sendchantypeexpr
| 53 = @recvchantypeexpr
| 54 = @sendrcvchantypeexpr
| 55 = @errorexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typedefspec
| 3 = @aliasspec;
@typespec = @typedefspec | @aliasspec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@typeparamparentobject = @decltypeobject | @declfunctionobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @typeparamtype
| 27 = @arraytype
| 28 = @slicetype
| 29 = @structtype
| 30 = @pointertype
| 31 = @interfacetype
| 32 = @tupletype
| 33 = @signaturetype
| 34 = @maptype
| 35 = @sendchantype
| 36 = @recvchantype
| 37 = @sendrcvchantype
| 38 = @namedtype
| 39 = @typesetliteraltype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
| @signaturetype | @namedtype | @typesetliteraltype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

Просмотреть файл

@ -1,31 +0,0 @@
class Type_ extends @type {
string toString() { result = "Type" }
}
/**
* A new kind has been inserted such that `@arraytype` which used to have index
* 26 now has index 27. Another new kind has been inserted at 39, which is the
* end of the list. Entries with lower indices are unchanged.
*/
bindingset[new_index]
int old_index(int new_index) {
if new_index < 26
then result = new_index
else
if new_index = 26
then result = 0 // invalidtype
else
if new_index < 39
then result + (27 - 26) = new_index
else result = 0 // invalidtype
}
// The schema for types is:
//
// types(unique int id: @type,
// int kind: int ref);
from Type_ type, int new_kind, int old_kind
where
types(type, new_kind) and
old_kind = old_index(new_kind)
select type, old_kind

Просмотреть файл

@ -1,6 +0,0 @@
description: Add generic instantiation expressions and type parameter types
compatibility: full
exprs.rel: run exprs.qlo
types.rel: run types.qlo
typeparamdecls.rel: delete
typeparam.rel: delete

Просмотреть файл

@ -1,531 +0,0 @@
/** Auto-generated dbscheme; do not edit. */
/** Duplicate code **/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity;
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/** External data **/
externalData(
int id : @externalDataElement,
varchar(900) path : string ref,
int column: int ref,
varchar(900) value : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* XML Files
*/
xmlEncoding(
unique int id: @file ref,
string encoding: string ref
);
xmlDTDs(
unique int id: @xmldtd,
string root: string ref,
string publicId: string ref,
string systemId: string ref,
int fileid: @file ref
);
xmlElements(
unique int id: @xmlelement,
string name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref
);
xmlAttrs(
unique int id: @xmlattribute,
int elementid: @xmlelement ref,
string name: string ref,
string value: string ref,
int idx: int ref,
int fileid: @file ref
);
xmlNs(
int id: @xmlnamespace,
string prefixName: string ref,
string URI: string ref,
int fileid: @file ref
);
xmlHasNs(
int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref
);
xmlComments(
unique int id: @xmlcomment,
string text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref
);
xmlChars(
unique int id: @xmlcharacters,
string text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref
);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(
int xmlElement: @xmllocatable ref,
int location: @location_default ref
);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
compilations(unique int id: @compilation, string cwd: string ref);
#keyset[id, num]
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
#keyset[id, num, kind]
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
#keyset[id, num]
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
string full_error_message: string ref, int location: @location ref);
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
int endLine: int ref, int endColumn: int ref);
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
files(unique int id: @file, string name: string ref);
folders(unique int id: @folder, string name: string ref);
containerparent(int parent: @container ref, unique int child: @container ref);
has_location(unique int locatable: @locatable ref, int location: @location ref);
#keyset[parent, idx]
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
#keyset[parent, idx]
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
#keyset[parent, idx]
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
#keyset[parent, idx]
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
#keyset[parent, idx]
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
scopes(unique int id: @scope, int kind: int ref);
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
objects(unique int id: @object, int kind: int ref, string name: string ref);
objectscopes(unique int object: @object ref, int scope: @scope ref);
objecttypes(unique int object: @object ref, int tp: @type ref);
methodreceivers(unique int method: @object ref, int receiver: @object ref);
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
methodhosts(int method: @object ref, int host: @namedtype ref);
defs(int ident: @ident ref, int object: @object ref);
uses(int ident: @ident ref, int object: @object ref);
types(unique int id: @type, int kind: int ref);
type_of(unique int expr: @expr ref, int tp: @type ref);
typename(unique int tp: @type ref, string name: string ref);
key_type(unique int map: @maptype ref, int tp: @type ref);
element_type(unique int container: @containertype ref, int tp: @type ref);
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
underlying_type(unique int named: @namedtype ref, int tp: @type ref);
#keyset[parent, index]
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
array_length(unique int tp: @arraytype ref, string len: string ref);
type_objects(unique int tp: @type ref, int object: @object ref);
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
#keyset[parent, idx]
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
#keyset[parent, idx]
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
#keyset[package, idx]
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
has_ellipsis(int id: @callorconversionexpr ref);
variadic(int id: @signaturetype ref);
@container = @file | @folder;
@locatable = @xmllocatable | @node | @localscope;
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @scopenode
| @comment_group | @comment;
@documentable = @file | @field | @spec | @gendecl | @funcdecl | @modexpr;
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @spec;
@modexprparent = @file | @modexpr;
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
@stmtparent = @funcdef | @stmt | @decl;
@declparent = @file | @declstmt;
@funcdef = @funclit | @funcdecl;
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
@location = @location_default;
@sourceline = @locatable;
case @comment.kind of
0 = @slashslashcomment
| 1 = @slashstarcomment;
case @expr.kind of
0 = @badexpr
| 1 = @ident
| 2 = @ellipsis
| 3 = @intlit
| 4 = @floatlit
| 5 = @imaglit
| 6 = @charlit
| 7 = @stringlit
| 8 = @funclit
| 9 = @compositelit
| 10 = @parenexpr
| 11 = @selectorexpr
| 12 = @indexexpr
| 13 = @sliceexpr
| 14 = @typeassertexpr
| 15 = @callorconversionexpr
| 16 = @starexpr
| 17 = @keyvalueexpr
| 18 = @arraytypeexpr
| 19 = @structtypeexpr
| 20 = @functypeexpr
| 21 = @interfacetypeexpr
| 22 = @maptypeexpr
| 23 = @plusexpr
| 24 = @minusexpr
| 25 = @notexpr
| 26 = @complementexpr
| 27 = @derefexpr
| 28 = @addressexpr
| 29 = @arrowexpr
| 30 = @lorexpr
| 31 = @landexpr
| 32 = @eqlexpr
| 33 = @neqexpr
| 34 = @lssexpr
| 35 = @leqexpr
| 36 = @gtrexpr
| 37 = @geqexpr
| 38 = @addexpr
| 39 = @subexpr
| 40 = @orexpr
| 41 = @xorexpr
| 42 = @mulexpr
| 43 = @quoexpr
| 44 = @remexpr
| 45 = @shlexpr
| 46 = @shrexpr
| 47 = @andexpr
| 48 = @andnotexpr
| 49 = @sendchantypeexpr
| 50 = @recvchantypeexpr
| 51 = @sendrcvchantypeexpr
| 52 = @errorexpr;
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
@logicalunaryexpr = @notexpr;
@bitwiseunaryexpr = @complementexpr;
@arithmeticunaryexpr = @plusexpr | @minusexpr;
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
@logicalbinaryexpr = @lorexpr | @landexpr;
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
@shiftexpr = @shlexpr | @shrexpr;
@comparison = @equalitytest | @relationalcomparison;
@equalitytest = @eqlexpr | @neqexpr;
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
case @stmt.kind of
0 = @badstmt
| 1 = @declstmt
| 2 = @emptystmt
| 3 = @labeledstmt
| 4 = @exprstmt
| 5 = @sendstmt
| 6 = @incstmt
| 7 = @decstmt
| 8 = @gostmt
| 9 = @deferstmt
| 10 = @returnstmt
| 11 = @breakstmt
| 12 = @continuestmt
| 13 = @gotostmt
| 14 = @fallthroughstmt
| 15 = @blockstmt
| 16 = @ifstmt
| 17 = @caseclause
| 18 = @exprswitchstmt
| 19 = @typeswitchstmt
| 20 = @commclause
| 21 = @selectstmt
| 22 = @forstmt
| 23 = @rangestmt
| 24 = @assignstmt
| 25 = @definestmt
| 26 = @addassignstmt
| 27 = @subassignstmt
| 28 = @mulassignstmt
| 29 = @quoassignstmt
| 30 = @remassignstmt
| 31 = @andassignstmt
| 32 = @orassignstmt
| 33 = @xorassignstmt
| 34 = @shlassignstmt
| 35 = @shrassignstmt
| 36 = @andnotassignstmt;
@incdecstmt = @incstmt | @decstmt;
@assignment = @simpleassignstmt | @compoundassignstmt;
@simpleassignstmt = @assignstmt | @definestmt;
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
@switchstmt = @exprswitchstmt | @typeswitchstmt;
@loopstmt = @forstmt | @rangestmt;
case @decl.kind of
0 = @baddecl
| 1 = @importdecl
| 2 = @constdecl
| 3 = @typedecl
| 4 = @vardecl
| 5 = @funcdecl;
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
case @spec.kind of
0 = @importspec
| 1 = @valuespec
| 2 = @typedefspec
| 3 = @aliasspec;
@typespec = @typedefspec | @aliasspec;
case @object.kind of
0 = @pkgobject
| 1 = @decltypeobject
| 2 = @builtintypeobject
| 3 = @declconstobject
| 4 = @builtinconstobject
| 5 = @declvarobject
| 6 = @declfunctionobject
| 7 = @builtinfunctionobject
| 8 = @labelobject;
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
@typeobject = @decltypeobject | @builtintypeobject;
@valueobject = @constobject | @varobject | @functionobject;
@constobject = @declconstobject | @builtinconstobject;
@varobject = @declvarobject;
@functionobject = @declfunctionobject | @builtinfunctionobject;
case @scope.kind of
0 = @universescope
| 1 = @packagescope
| 2 = @localscope;
case @type.kind of
0 = @invalidtype
| 1 = @boolexprtype
| 2 = @inttype
| 3 = @int8type
| 4 = @int16type
| 5 = @int32type
| 6 = @int64type
| 7 = @uinttype
| 8 = @uint8type
| 9 = @uint16type
| 10 = @uint32type
| 11 = @uint64type
| 12 = @uintptrtype
| 13 = @float32type
| 14 = @float64type
| 15 = @complex64type
| 16 = @complex128type
| 17 = @stringexprtype
| 18 = @unsafepointertype
| 19 = @boolliteraltype
| 20 = @intliteraltype
| 21 = @runeliteraltype
| 22 = @floatliteraltype
| 23 = @complexliteraltype
| 24 = @stringliteraltype
| 25 = @nilliteraltype
| 26 = @arraytype
| 27 = @slicetype
| 28 = @structtype
| 29 = @pointertype
| 30 = @interfacetype
| 31 = @tupletype
| 32 = @signaturetype
| 33 = @maptype
| 34 = @sendchantype
| 35 = @recvchantype
| 36 = @sendrcvchantype
| 37 = @namedtype;
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
@booltype = @boolexprtype | @boolliteraltype;
@numerictype = @integertype | @floattype | @complextype;
@integertype = @signedintegertype | @unsignedintegertype;
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
@floattype = @float32type | @float64type | @floatliteraltype;
@complextype = @complex64type | @complex128type | @complexliteraltype;
@stringtype = @stringexprtype | @stringliteraltype;
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
| @stringliteraltype | @nilliteraltype;
@compositetype = @containertype | @structtype | @pointertype | @interfacetype | @tupletype | @signaturetype | @namedtype;
@containertype = @arraytype | @slicetype | @maptype | @chantype;
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
case @modexpr.kind of
0 = @modcommentblock
| 1 = @modline
| 2 = @modlineblock
| 3 = @modlparen
| 4 = @modrparen;
case @error.kind of
0 = @unknownerror
| 1 = @listerror
| 2 = @parseerror
| 3 = @typeerror;

Просмотреть файл

@ -1,4 +0,0 @@
name: codeql/go-downgrades
groups: go
downgrades: .
library: true

Просмотреть файл

@ -1,27 +0,0 @@
- description: Selectors for selecting the Code-Scanning-relevant queries for a language
- include:
kind:
- problem
- path-problem
- alert
- path-alert
precision:
- high
- very-high
problem.severity:
- error
- warning
tags contain:
- security
- include:
kind:
- diagnostic
- include:
kind:
- metric
tags contain:
- summary
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

Просмотреть файл

@ -1,12 +0,0 @@
- description: Selectors for excluding queries that LGTM doesn't display by default
- exclude:
kind:
- problem
- path-problem
precision: medium
- exclude:
kind:
- problem
- path-problem
precision: high
problem.severity: recommendation

Просмотреть файл

@ -1,25 +0,0 @@
- description: Selectors for selecting the LGTM-relevant queries for a language
- include:
kind:
- problem
- path-problem
precision:
- high
- very-high
- include:
kind:
- problem
- path-problem
precision: medium
problem.severity:
- error
- warning
- include:
kind:
- definitions
- alert-suppression
- file-classifier
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

Просмотреть файл

@ -1,3 +0,0 @@
name: codeql/suite-helpers
version: 0.0.2
library: true

Просмотреть файл

@ -1,29 +0,0 @@
- description: Selectors for selecting the security-and-quality queries for a language
- include:
kind:
- problem
- path-problem
precision:
- high
- very-high
- include:
kind:
- problem
- path-problem
precision: medium
problem.severity:
- error
- warning
- include:
kind:
- diagnostic
- include:
kind:
- metric
tags contain:
- summary
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

Просмотреть файл

@ -1,34 +0,0 @@
- description: Selectors for selecting the security-extended queries for a language
- include:
kind:
- problem
- path-problem
precision:
- high
- very-high
tags contain:
- security
- include:
kind:
- problem
- path-problem
precision:
- medium
problem.severity:
- error
- warning
tags contain:
- security
- include:
kind:
- diagnostic
- include:
kind:
- metric
tags contain:
- summary
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

4
extractor-smoke-test/.gitignore поставляемый
Просмотреть файл

@ -1,4 +0,0 @@
*.bqrs
tracing-out.csv
notracing-out.csv
testdb

Просмотреть файл

@ -1,12 +0,0 @@
"1","assignment to i"
"assignment to i","selection of Println"
"call to Println","exit"
"entry","skip"
"entry","skip"
"function declaration","exit"
"i","call to Println"
"nd","col1"
"selection of Println","i"
"skip","1"
"skip","function declaration"
"skip","skip"
1 1 assignment to i
2 assignment to i selection of Println
3 call to Println exit
4 entry skip
5 entry skip
6 function declaration exit
7 i call to Println
8 nd col1
9 selection of Println i
10 skip 1
11 skip function declaration
12 skip skip

Просмотреть файл

@ -1,3 +0,0 @@
module github.com/codeql-go-extractor-smoke-test
go 1.14

Просмотреть файл

@ -1,8 +0,0 @@
package main
import "fmt"
func main() {
var i int = 1
fmt.Println(i)
}

Просмотреть файл

@ -1,26 +0,0 @@
#!/bin/bash
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
cd $DIR
rm -rf testdb
codeql database create --language=go testdb --search-path ..
codeql dataset check testdb/db-go
codeql query run ../ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.ql --database=testdb --output=notracing-out.bqrs --search-path ..
codeql bqrs decode notracing-out.bqrs --format=csv --output=notracing-out.csv
diff -w -u <(sort notracing-out.csv) expected.csv
# Now do it again with tracing enabled
export CODEQL_EXTRACTOR_GO_BUILD_TRACING=on
rm -rf testdb
codeql database create --language=go testdb --search-path ..
codeql dataset check testdb/db-go
codeql query run ../ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.ql --database=testdb --output=tracing-out.bqrs --search-path ..
codeql bqrs decode tracing-out.bqrs --format=csv --output=tracing-out.csv
diff -w -u <(sort tracing-out.csv) expected.csv

Просмотреть файл

@ -1,81 +0,0 @@
// Package autobuilder implements a simple system that attempts to run build commands for common
// build frameworks, if the relevant files exist.
package autobuilder
import (
"log"
"os"
"os/exec"
"github.com/github/codeql-go/extractor/util"
)
// CheckExtracted sets whether the autobuilder should check whether source files have been extracted
// to the CodeQL source directory as well as whether the build command executed successfully.
var CheckExtracted = false
// checkEmpty checks whether a directory either doesn't exist or is empty.
func checkEmpty(dir string) (bool, error) {
if !util.DirExists(dir) {
return true, nil
}
d, err := os.Open(dir)
if err != nil {
return false, err
}
defer d.Close()
names, err := d.Readdirnames(-1)
if err != nil {
return false, err
}
return len(names) == 0, nil
}
// checkExtractorRun checks whether the CodeQL Go extractor has run, by checking if the source
// archive directory is empty or not.
func checkExtractorRun() bool {
srcDir := os.Getenv("CODEQL_EXTRACTOR_GO_SOURCE_ARCHIVE_DIR")
if srcDir != "" {
empty, err := checkEmpty(srcDir)
if err != nil {
log.Fatalf("Unable to read source archive directory %s.", srcDir)
}
if empty {
log.Printf("No Go code seen; continuing to try other builds.")
return false
}
return true
} else {
log.Fatalf("No source directory set.\nThis binary should not be run manually; instead, use the CodeQL CLI or VSCode extension. See https://securitylab.github.com/tools/codeql.")
return false
}
}
// tryBuildIfExists tries to run the command `cmd args...` if the file `buildFile` exists and is not
// a directory. Returns true if the command was successful and false if not.
func tryBuildIfExists(buildFile, cmd string, args ...string) bool {
if util.FileExists(buildFile) {
log.Printf("%s found.\n", buildFile)
return tryBuild(cmd, args...)
}
return false
}
// tryBuild tries to run `cmd args...`, returning true if successful and false if not.
func tryBuild(cmd string, args ...string) bool {
log.Printf("Trying build command %s %v", cmd, args)
res := util.RunCmd(exec.Command(cmd, args...))
return res && (!CheckExtracted || checkExtractorRun())
}
// Autobuild attempts to detect build system and run the corresponding command.
func Autobuild() bool {
return tryBuildIfExists("Makefile", "make") ||
tryBuildIfExists("makefile", "make") ||
tryBuildIfExists("GNUmakefile", "make") ||
tryBuildIfExists("build.ninja", "ninja") ||
tryBuildIfExists("build", "./build") ||
tryBuildIfExists("build.sh", "./build.sh")
}

Просмотреть файл

@ -1,588 +0,0 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"golang.org/x/mod/semver"
"github.com/github/codeql-go/extractor/autobuilder"
"github.com/github/codeql-go/extractor/util"
)
func usage() {
fmt.Fprintf(os.Stderr,
`%s is a wrapper script that installs dependencies and calls the extractor.
When LGTM_SRC is not set, the script installs dependencies as described below, and then invokes the
extractor in the working directory.
If LGTM_SRC is set, it checks for the presence of the files 'go.mod', 'Gopkg.toml', and
'glide.yaml' to determine how to install dependencies: if a 'Gopkg.toml' file is present, it uses
'dep ensure', if there is a 'glide.yaml' it uses 'glide install', and otherwise 'go get'.
Additionally, unless a 'go.mod' file is detected, it sets up a temporary GOPATH and moves all
source files into a folder corresponding to the package's import path before installing
dependencies.
This behavior can be further customized using environment variables: setting LGTM_INDEX_NEED_GOPATH
to 'false' disables the GOPATH set-up, CODEQL_EXTRACTOR_GO_BUILD_COMMAND (or alternatively
LGTM_INDEX_BUILD_COMMAND), can be set to a newline-separated list of commands to run in order to
install dependencies, and LGTM_INDEX_IMPORT_PATH can be used to override the package import path,
which is otherwise inferred from the SEMMLE_REPO_URL or GITHUB_REPOSITORY environment variables.
In resource-constrained environments, the environment variable CODEQL_EXTRACTOR_GO_MAX_GOROUTINES
(or its legacy alias SEMMLE_MAX_GOROUTINES) can be used to limit the number of parallel goroutines
started by the extractor, which reduces CPU and memory requirements. The default value for this
variable is 32.
`,
os.Args[0])
fmt.Fprintf(os.Stderr, "Usage:\n\n %s\n", os.Args[0])
}
var goVersion = ""
// Returns the current Go version as returned by 'go version', e.g. go1.14.4
func getEnvGoVersion() string {
if goVersion == "" {
gover, err := exec.Command("go", "version").CombinedOutput()
if err != nil {
log.Fatalf("Unable to run the go command, is it installed?\nError: %s", err.Error())
}
goVersion = strings.Fields(string(gover))[2]
}
return goVersion
}
// Returns the current Go version in semver format, e.g. v1.14.4
func getEnvGoSemVer() string {
goVersion := getEnvGoVersion()
if !strings.HasPrefix(goVersion, "go") {
log.Fatalf("Expected 'go version' output of the form 'go1.2.3'; got '%s'", goVersion)
}
return "v" + goVersion[2:]
}
func tryBuild(buildFile, cmd string, args ...string) bool {
if util.FileExists(buildFile) {
log.Printf("%s found, running %s\n", buildFile, cmd)
return util.RunCmd(exec.Command(cmd, args...))
}
return false
}
func getImportPath() (importpath string) {
importpath = os.Getenv("LGTM_INDEX_IMPORT_PATH")
if importpath == "" {
repourl := os.Getenv("SEMMLE_REPO_URL")
if repourl == "" {
githubrepo := os.Getenv("GITHUB_REPOSITORY")
if githubrepo == "" {
log.Printf("Unable to determine import path, as neither LGTM_INDEX_IMPORT_PATH nor GITHUB_REPOSITORY is set\n")
return ""
} else {
importpath = "github.com/" + githubrepo
}
} else {
importpath = getImportPathFromRepoURL(repourl)
if importpath == "" {
log.Printf("Failed to determine import path from SEMMLE_REPO_URL '%s'\n", repourl)
return
}
}
}
log.Printf("Import path is '%s'\n", importpath)
return
}
func getImportPathFromRepoURL(repourl string) string {
// check for scp-like URL as in "git@github.com:github/codeql-go.git"
shorturl := regexp.MustCompile("^([^@]+@)?([^:]+):([^/].*?)(\\.git)?$")
m := shorturl.FindStringSubmatch(repourl)
if m != nil {
return m[2] + "/" + m[3]
}
// otherwise parse as proper URL
u, err := url.Parse(repourl)
if err != nil {
log.Fatalf("Malformed repository URL '%s'\n", repourl)
}
if u.Scheme == "file" {
// we can't determine import paths from file paths
return ""
}
if u.Hostname() == "" || u.Path == "" {
return ""
}
host := u.Hostname()
path := u.Path
// strip off leading slashes and trailing `.git` if present
path = regexp.MustCompile("^/+|\\.git$").ReplaceAllString(path, "")
return host + "/" + path
}
func restoreRepoLayout(fromDir string, dirEntries []string, scratchDirName string, toDir string) {
for _, dirEntry := range dirEntries {
if dirEntry != scratchDirName {
log.Printf("Restoring %s/%s to %s/%s.\n", fromDir, dirEntry, toDir, dirEntry)
err := os.Rename(filepath.Join(fromDir, dirEntry), filepath.Join(toDir, dirEntry))
if err != nil {
log.Printf("Failed to move file/directory %s from directory %s to directory %s: %s\n", dirEntry, fromDir, toDir, err.Error())
}
}
}
}
// DependencyInstallerMode is an enum describing how dependencies should be installed
type DependencyInstallerMode int
const (
// GoGetNoModules represents dependency installation using `go get` without modules
GoGetNoModules DependencyInstallerMode = iota
// GoGetWithModules represents dependency installation using `go get` with modules
GoGetWithModules
// Dep represent dependency installation using `dep ensure`
Dep
// Glide represents dependency installation using `glide install`
Glide
)
// ModMode corresponds to the possible values of the -mod flag for the Go compiler
type ModMode int
const (
ModUnset ModMode = iota
ModReadonly
ModMod
ModVendor
)
func (m ModMode) argsForGoVersion(version string) []string {
switch m {
case ModUnset:
return []string{}
case ModReadonly:
return []string{"-mod=readonly"}
case ModMod:
if !semver.IsValid(version) {
log.Fatalf("Invalid Go semver: '%s'", version)
}
if semver.Compare(version, "v1.14") < 0 {
return []string{} // -mod=mod is the default behaviour for go <= 1.13, and is not accepted as an argument
} else {
return []string{"-mod=mod"}
}
case ModVendor:
return []string{"-mod=vendor"}
}
return nil
}
// addVersionToMod add a go version directive, e.g. `go 1.14` to a `go.mod` file.
func addVersionToMod(goMod []byte, version string) bool {
cmd := exec.Command("go", "mod", "edit", "-go="+version)
return util.RunCmd(cmd)
}
// checkVendor tests to see whether a vendor directory is inconsistent according to the go frontend
func checkVendor() bool {
vendorCheckCmd := exec.Command("go", "list", "-mod=vendor", "./...")
outp, err := vendorCheckCmd.CombinedOutput()
if err != nil {
badVendorRe := regexp.MustCompile(`(?m)^go: inconsistent vendoring in .*:$`)
return !badVendorRe.Match(outp)
}
return true
}
func main() {
if len(os.Args) > 1 {
usage()
os.Exit(2)
}
log.Printf("Autobuilder was built with %s, environment has %s\n", runtime.Version(), getEnvGoVersion())
srcdir := os.Getenv("LGTM_SRC")
inLGTM := srcdir != ""
if inLGTM {
log.Printf("LGTM_SRC is %s\n", srcdir)
} else {
cwd, err := os.Getwd()
if err != nil {
log.Fatalln("Failed to get current working directory.")
}
log.Printf("LGTM_SRC is not set; defaulting to current working directory %s\n", cwd)
srcdir = cwd
}
// we set `SEMMLE_PATH_TRANSFORMER` ourselves in some cases, so blank it out first for consistency
os.Setenv("SEMMLE_PATH_TRANSFORMER", "")
// determine how to install dependencies and whether a GOPATH needs to be set up before
// extraction
depMode := GoGetNoModules
modMode := ModUnset
needGopath := true
if _, present := os.LookupEnv("GO111MODULE"); !present {
os.Setenv("GO111MODULE", "auto")
}
if util.FileExists("go.mod") {
depMode = GoGetWithModules
needGopath = false
log.Println("Found go.mod, enabling go modules")
} else if util.FileExists("Gopkg.toml") {
depMode = Dep
log.Println("Found Gopkg.toml, using dep instead of go get")
} else if util.FileExists("glide.yaml") {
depMode = Glide
log.Println("Found glide.yaml, enabling go modules")
}
if depMode == GoGetWithModules {
// if a vendor/modules.txt file exists, we assume that there are vendored Go dependencies, and
// skip the dependency installation step and run the extractor with `-mod=vendor`
if util.FileExists("vendor/modules.txt") {
modMode = ModVendor
} else if util.DirExists("vendor") {
modMode = ModMod
}
}
if modMode == ModVendor {
// fix go vendor issues with go versions >= 1.14 when no go version is specified in the go.mod
// if this is the case, and dependencies were vendored with an old go version (and therefore
// do not contain a '## explicit' annotation, the go command will fail and refuse to do any
// work
//
// we work around this by adding an explicit go version of 1.13, which is the last version
// where this is not an issue
if depMode == GoGetWithModules {
goMod, err := ioutil.ReadFile("go.mod")
if err != nil {
log.Println("Failed to read go.mod to check for missing Go version")
} else if versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+[0-9]+\.[0-9]+$`); !versionRe.Match(goMod) {
// if the go.mod does not contain a version line
modulesTxt, err := ioutil.ReadFile("vendor/modules.txt")
if err != nil {
log.Println("Failed to read vendor/modules.txt to check for mismatched Go version")
} else if explicitRe := regexp.MustCompile("(?m)^## explicit$"); !explicitRe.Match(modulesTxt) {
// and the modules.txt does not contain an explicit annotation
log.Println("Adding a version directive to the go.mod file as the modules.txt does not have explicit annotations")
if !addVersionToMod(goMod, "1.13") {
log.Println("Failed to add a version to the go.mod file to fix explicitly required package bug; not using vendored dependencies")
modMode = ModMod
}
}
}
}
}
// Go 1.16 and later won't automatically attempt to update go.mod / go.sum during package loading, so try to update them here:
if depMode == GoGetWithModules && semver.Compare(getEnvGoSemVer(), "1.16") >= 0 {
// stat go.mod and go.sum
beforeGoModFileInfo, beforeGoModErr := os.Stat("go.mod")
if beforeGoModErr != nil {
log.Println("Failed to stat go.mod before running `go mod tidy -e`")
}
beforeGoSumFileInfo, beforeGoSumErr := os.Stat("go.sum")
// run `go mod tidy -e`
res := util.RunCmd(exec.Command("go", "mod", "tidy", "-e"))
if !res {
log.Println("Failed to run `go mod tidy -e`")
} else {
if beforeGoModFileInfo != nil {
afterGoModFileInfo, afterGoModErr := os.Stat("go.mod")
if afterGoModErr != nil {
log.Println("Failed to stat go.mod after running `go mod tidy -e`")
} else if afterGoModFileInfo.ModTime().After(beforeGoModFileInfo.ModTime()) {
// if go.mod has been changed then notify the user
log.Println("We have run `go mod tidy -e` and it altered go.mod. You may wish to check these changes into version control. ")
}
}
afterGoSumFileInfo, afterGoSumErr := os.Stat("go.sum")
if afterGoSumErr != nil {
log.Println("Failed to stat go.sum after running `go mod tidy -e`")
} else {
if beforeGoSumErr != nil || afterGoSumFileInfo.ModTime().After(beforeGoSumFileInfo.ModTime()) {
// if go.sum has been changed then notify the user
log.Println("We have run `go mod tidy -e` and it altered go.sum. You may wish to check these changes into version control. ")
}
}
}
}
// if `LGTM_INDEX_NEED_GOPATH` is set, it overrides the value for `needGopath` inferred above
if needGopathOverride := os.Getenv("LGTM_INDEX_NEED_GOPATH"); needGopathOverride != "" {
inLGTM = true
if needGopathOverride == "true" {
needGopath = true
} else if needGopathOverride == "false" {
needGopath = false
} else {
log.Fatalf("Unexpected value for Boolean environment variable LGTM_NEED_GOPATH: %v.\n", needGopathOverride)
}
}
importpath := getImportPath()
if needGopath && importpath == "" {
log.Printf("Failed to determine import path, not setting up GOPATH")
needGopath = false
}
if inLGTM && needGopath {
// a temporary directory where everything is moved while the correct
// directory structure is created.
scratch, err := ioutil.TempDir(srcdir, "scratch")
if err != nil {
log.Fatalf("Failed to create temporary directory %s in directory %s: %s\n",
scratch, srcdir, err.Error())
}
log.Printf("Temporary directory is %s.\n", scratch)
// move all files in `srcdir` to `scratch`
dir, err := os.Open(srcdir)
if err != nil {
log.Fatalf("Failed to open source directory %s for reading: %s\n", srcdir, err.Error())
}
files, err := dir.Readdirnames(-1)
if err != nil {
log.Fatalf("Failed to read source directory %s: %s\n", srcdir, err.Error())
}
for _, file := range files {
if file != filepath.Base(scratch) {
log.Printf("Moving %s/%s to %s/%s.\n", srcdir, file, scratch, file)
err := os.Rename(filepath.Join(srcdir, file), filepath.Join(scratch, file))
if err != nil {
log.Fatalf("Failed to move file %s to the temporary directory: %s\n", file, err.Error())
}
}
}
// create a new folder which we will add to GOPATH below
// Note we evaluate all symlinks here for consistency: otherwise os.Chdir below
// will follow links but other references to the path may not, which can lead to
// disagreements between GOPATH and the working directory.
realSrc, err := filepath.EvalSymlinks(srcdir)
if err != nil {
log.Fatalf("Failed to evaluate symlinks in %s: %s\n", srcdir, err.Error())
}
root := filepath.Join(realSrc, "root")
// move source files to where Go expects them to be
newdir := filepath.Join(root, "src", importpath)
err = os.MkdirAll(filepath.Dir(newdir), 0755)
if err != nil {
log.Fatalf("Failed to create directory %s: %s\n", newdir, err.Error())
}
log.Printf("Moving %s to %s.\n", scratch, newdir)
err = os.Rename(scratch, newdir)
if err != nil {
log.Fatalf("Failed to rename %s to %s: %s\n", scratch, newdir, err.Error())
}
// schedule restoring the contents of newdir to their original location after this function completes:
defer restoreRepoLayout(newdir, files, filepath.Base(scratch), srcdir)
err = os.Chdir(newdir)
if err != nil {
log.Fatalf("Failed to chdir into %s: %s\n", newdir, err.Error())
}
// set up SEMMLE_PATH_TRANSFORMER to ensure paths in the source archive and the snapshot
// match the original source location, not the location we moved it to
pt, err := ioutil.TempFile("", "path-transformer")
if err != nil {
log.Fatalf("Unable to create path transformer file: %s.", err.Error())
}
defer os.Remove(pt.Name())
_, err = pt.WriteString("#" + realSrc + "\n" + newdir + "//\n")
if err != nil {
log.Fatalf("Unable to write path transformer file: %s.", err.Error())
}
err = pt.Close()
if err != nil {
log.Fatalf("Unable to close path transformer file: %s.", err.Error())
}
err = os.Setenv("SEMMLE_PATH_TRANSFORMER", pt.Name())
if err != nil {
log.Fatalf("Unable to set SEMMLE_PATH_TRANSFORMER environment variable: %s.\n", err.Error())
}
// set/extend GOPATH
oldGopath := os.Getenv("GOPATH")
var newGopath string
if oldGopath != "" {
newGopath = strings.Join(
[]string{root, oldGopath},
string(os.PathListSeparator),
)
} else {
newGopath = root
}
err = os.Setenv("GOPATH", newGopath)
if err != nil {
log.Fatalf("Unable to set GOPATH to %s: %s\n", newGopath, err.Error())
}
log.Printf("GOPATH set to %s.\n", newGopath)
}
// check whether an explicit dependency installation command was provided
inst := util.Getenv("CODEQL_EXTRACTOR_GO_BUILD_COMMAND", "LGTM_INDEX_BUILD_COMMAND")
shouldInstallDependencies := false
if inst == "" {
// try to build the project
buildSucceeded := autobuilder.Autobuild()
// Build failed or there are still dependency errors; we'll try to install dependencies
// ourselves
if !buildSucceeded {
log.Println("Build failed, continuing to install dependencies.")
shouldInstallDependencies = true
} else if util.DepErrors("./...", modMode.argsForGoVersion(getEnvGoSemVer())...) {
log.Println("Dependencies are still not resolving after the build, continuing to install dependencies.")
shouldInstallDependencies = true
}
} else {
// write custom build commands into a script, then run it
var (
ext = ""
header = ""
footer = ""
)
if runtime.GOOS == "windows" {
ext = ".cmd"
header = "@echo on\n@prompt +$S\n"
footer = "\nIF %ERRORLEVEL% NEQ 0 EXIT"
} else {
ext = ".sh"
header = "#! /bin/bash\nset -xe +u\n"
}
script, err := ioutil.TempFile("", "go-build-command-*"+ext)
if err != nil {
log.Fatalf("Unable to create temporary script holding custom build commands: %s\n", err.Error())
}
defer os.Remove(script.Name())
_, err = script.WriteString(header + inst + footer)
if err != nil {
log.Fatalf("Unable to write to temporary script holding custom build commands: %s\n", err.Error())
}
err = script.Close()
if err != nil {
log.Fatalf("Unable to close temporary script holding custom build commands: %s\n", err.Error())
}
os.Chmod(script.Name(), 0700)
log.Println("Installing dependencies using custom build command.")
util.RunCmd(exec.Command(script.Name()))
}
if modMode == ModVendor {
// test if running `go` with -mod=vendor works, and if it doesn't, try to fallback to -mod=mod
// or not set if the go version < 1.14. Note we check this post-build in case the build brings
// the vendor directory up to date.
if !checkVendor() {
modMode = ModMod
log.Println("The vendor directory is not consistent with the go.mod; not using vendored dependencies.")
}
}
if shouldInstallDependencies {
if modMode == ModVendor {
log.Printf("Skipping dependency installation because a Go vendor directory was found.")
} else {
// automatically determine command to install dependencies
var install *exec.Cmd
if depMode == Dep {
// set up the dep cache if SEMMLE_CACHE is set
cacheDir := os.Getenv("SEMMLE_CACHE")
if cacheDir != "" {
depCacheDir := filepath.Join(cacheDir, "go", "dep")
log.Printf("Attempting to create dep cache dir %s\n", depCacheDir)
err := os.MkdirAll(depCacheDir, 0755)
if err != nil {
log.Printf("Failed to create dep cache directory: %s\n", err.Error())
} else {
log.Printf("Setting dep cache directory to %s\n", depCacheDir)
err = os.Setenv("DEPCACHEDIR", depCacheDir)
if err != nil {
log.Println("Failed to set dep cache directory")
} else {
err = os.Setenv("DEPCACHEAGE", "720h") // 30 days
if err != nil {
log.Println("Failed to set dep cache age")
}
}
}
}
if util.FileExists("Gopkg.lock") {
// if Gopkg.lock exists, don't update it and only vendor dependencies
install = exec.Command("dep", "ensure", "-v", "-vendor-only")
} else {
install = exec.Command("dep", "ensure", "-v")
}
log.Println("Installing dependencies using `dep ensure`.")
} else if depMode == Glide {
install = exec.Command("glide", "install")
log.Println("Installing dependencies using `glide install`")
} else {
// explicitly set go module support
if depMode == GoGetWithModules {
os.Setenv("GO111MODULE", "on")
} else if depMode == GoGetNoModules {
os.Setenv("GO111MODULE", "off")
}
// get dependencies
install = exec.Command("go", "get", "-v", "./...")
log.Println("Installing dependencies using `go get -v ./...`.")
}
util.RunCmd(install)
}
}
// extract
extractor, err := util.GetExtractorPath()
if err != nil {
log.Fatalf("Could not determine path of extractor: %v.\n", err)
}
cwd, err := os.Getwd()
if err != nil {
log.Fatalf("Unable to determine current directory: %s\n", err.Error())
}
extractorArgs := []string{}
if depMode == GoGetWithModules {
extractorArgs = append(extractorArgs, modMode.argsForGoVersion(getEnvGoSemVer())...)
}
extractorArgs = append(extractorArgs, "./...")
log.Printf("Running extractor command '%s %v' from directory '%s'.\n", extractor, extractorArgs, cwd)
cmd := exec.Command(extractor, extractorArgs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
log.Fatalf("Extraction failed: %s\n", err.Error())
}
}

Просмотреть файл

@ -1,22 +0,0 @@
package main
import "testing"
func TestGetImportPathFromRepoURL(t *testing.T) {
tests := map[string]string{
"git@github.com:github/codeql-go.git": "github.com/github/codeql-go",
"git@github.com:github/codeql-go": "github.com/github/codeql-go",
"https://github.com/github/codeql-go.git": "github.com/github/codeql-go",
"https://github.com:12345/github/codeql-go": "github.com/github/codeql-go",
"gitolite@some.url:some/repo": "some.url/some/repo",
"file:///C:/some/path": "",
"https:///no/hostname": "",
"https://hostnameonly": "",
}
for input, expected := range tests {
actual := getImportPathFromRepoURL(input)
if actual != expected {
t.Errorf("Expected getImportPathFromRepoURL(\"%s\") to be \"%s\", but got \"%s\".", input, expected, actual)
}
}
}

Просмотреть файл

@ -1,54 +0,0 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
)
// A utility program for generating `project` and `variable` files for SemmleCore Go projects
//
// This program should not normally be run directly; it is usually executed as part of
// `odasa bootstrap`, and expects two files as arguments: a (partial) `variables` file and
// an empty file to be filled in with an `<autoupdate>` element containing build steps.
//
// The `variables` file is extended with a definition of `LGTM_SRC` and, if it defines the
// `repository` variable, `SEMMLE_REPO_URL`. The only build step is an invocation of the
// Go autobuilder.
func main() {
vars := os.Args[1]
buildSteps := os.Args[2]
haveRepo := false
content, err := ioutil.ReadFile(vars)
if err != nil {
log.Fatal(err)
}
re := regexp.MustCompile(`(^|\n)repository=`)
haveRepo = re.Find(content) != nil
additionalVars := "LGTM_SRC=${src}\n"
if haveRepo {
additionalVars += "SEMMLE_REPO_URL=${repository}\n"
}
content = append(content, []byte(additionalVars)...)
err = ioutil.WriteFile(vars, content, 0644)
if err != nil {
log.Fatal(err)
}
export := "LGTM_SRC"
if haveRepo {
export += ",SEMMLE_REPO_URL"
}
content = []byte(fmt.Sprintf(`<autoupdate>
<build export="%s">${semmle_dist}/language-packs/go/tools/platform/${semmle_platform}/bin/go-autobuilder</build>
</autoupdate>
`, export))
err = ioutil.WriteFile(buildSteps, content, 0644)
if err != nil {
log.Fatal(err)
}
}

Просмотреть файл

@ -1,36 +0,0 @@
package main
import (
"github.com/github/codeql-go/extractor/util"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"github.com/github/codeql-go/extractor/autobuilder"
)
func main() {
// check if a build command has successfully extracted something
autobuilder.CheckExtracted = true
if autobuilder.Autobuild() {
return
}
// if the autobuilder fails, invoke the extractor manually
// we cannot simply call `go build` here, because the tracer is not able to trace calls made by
// this binary
log.Printf("No build commands succeeded, falling back to go build ./...")
mypath, err := os.Executable()
if err != nil {
log.Fatalf("Could not determine path of extractor: %v.\n", err)
}
extractor := filepath.Join(filepath.Dir(mypath), "go-extractor")
if runtime.GOOS == "windows" {
extractor = extractor + ".exe"
}
util.RunCmd(exec.Command(extractor, "./..."))
}

Просмотреть файл

@ -1,132 +0,0 @@
package main
import (
"fmt"
"log"
"os"
"runtime"
"runtime/pprof"
"strings"
"github.com/github/codeql-go/extractor"
)
var cpuprofile, memprofile string
func usage() {
fmt.Fprintf(os.Stderr, "%s is a program for building a snapshot of a Go code base.\n\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Usage:\n\n %s [<flag>...] [<buildflag>...] [--] <file>...\n\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Flags:\n\n")
fmt.Fprintf(os.Stderr, "--help Print this help.\n")
}
func parseFlags(args []string, mimic bool) ([]string, []string) {
i := 0
buildFlags := []string{}
for ; i < len(args) && strings.HasPrefix(args[i], "-"); i++ {
if args[i] == "--" {
i++
break
}
if !mimic {
// we're not in mimic mode, try to parse our arguments
switch args[i] {
case "--help":
usage()
os.Exit(0)
case "--mimic":
if i+1 < len(args) {
i++
compiler := args[i]
log.Printf("Compiler: %s", compiler)
if i+1 < len(args) {
i++
command := args[i]
if command == "build" || command == "install" || command == "run" {
log.Printf("Intercepting build")
return parseFlags(args[i+1:], true)
} else {
log.Printf("Non-build command '%s'; skipping", strings.Join(args[1:], " "))
os.Exit(0)
}
} else {
log.Printf("Non-build command '%s'; skipping", strings.Join(args[1:], " "))
os.Exit(0)
}
} else {
log.Fatalf("--mimic requires an argument, e.g. --mimic go")
}
}
}
// parse go build flags
switch args[i] {
// skip `-o output` and `-i`, if applicable
case "-o":
if i+1 < len(args) {
i++
}
case "-i":
case "-p", "-asmflags", "-buildmode", "-compiler", "-gccgoflags", "-gcflags", "-installsuffix",
"-ldflags", "-mod", "-modfile", "-pkgdir", "-tags", "-toolexec", "-overlay":
if i+1 < len(args) {
buildFlags = append(buildFlags, args[i], args[i+1])
i++
} else {
buildFlags = append(buildFlags, args[i])
}
default:
if strings.HasPrefix(args[i], "-") {
buildFlags = append(buildFlags, args[i])
} else {
// stop parsing if the argument is not a flag (and so is positional)
break
}
}
}
cpuprofile = os.Getenv("CODEQL_EXTRACTOR_GO_CPU_PROFILE")
memprofile = os.Getenv("CODEQL_EXTRACTOR_GO_MEM_PROFILE")
return buildFlags, args[i:]
}
func main() {
buildFlags, patterns := parseFlags(os.Args[1:], false)
if cpuprofile != "" {
f, err := os.Create(cpuprofile)
if err != nil {
log.Fatalf("Unable to create CPU profile: %v.", err)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatalf("Unable to start CPU profile: %v.", err)
}
defer pprof.StopCPUProfile()
}
if len(patterns) == 0 {
log.Println("No packages explicitly provided, adding '.'")
patterns = []string{"."}
}
log.Printf("Build flags: '%s'; patterns: '%s'\n", strings.Join(buildFlags, " "), strings.Join(patterns, " "))
err := extractor.ExtractWithFlags(buildFlags, patterns)
if err != nil {
log.Fatalf("Error running go tooling: %s\n", err.Error())
}
if memprofile != "" {
f, err := os.Create(memprofile)
if err != nil {
log.Fatalf("Unable to create memory profile: %v", err)
}
defer f.Close()
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("Unable to write memory profile: ", err)
}
}
}

Просмотреть файл

@ -1,31 +0,0 @@
package main
import (
"fmt"
"os"
"github.com/github/codeql-go/extractor/dbscheme"
)
func usage() {
fmt.Fprintf(os.Stderr, "%s is a program for generating the dbscheme for CodeQL Go databases.\n\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Usage:\n\n %s <output file>\n\n", os.Args[0])
}
func main() {
if len(os.Args) != 2 {
usage()
os.Exit(2)
}
out := os.Args[1]
f, err := os.Create(out)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to open file %s for writing.\n", out)
os.Exit(1)
}
dbscheme.PrintDbScheme(f)
f.Close()
fmt.Printf("Dbscheme written to file %s.\n", out)
}

Просмотреть файл

@ -1,57 +0,0 @@
package main
import (
"encoding/csv"
"flag"
"fmt"
"go/scanner"
"go/token"
"io/ioutil"
"log"
"os"
"strings"
)
func main() {
flag.Parse()
fs := token.NewFileSet()
csv := csv.NewWriter(os.Stdout)
defer csv.Flush()
for _, fileName := range flag.Args() {
src, err := ioutil.ReadFile(fileName)
if err != nil {
log.Fatalf("Unable to read file %s.", fileName)
}
f := fs.AddFile(fileName, -1, len(src))
var s scanner.Scanner
s.Init(f, src, nil, 0)
for {
beginPos, tok, text := s.Scan()
if strings.TrimSpace(text) != "" {
var fuzzyText string
if tok.IsLiteral() {
fuzzyText = tok.String()
} else {
fuzzyText = text
}
endPos := f.Pos(f.Offset(beginPos) + len(text))
beginLine := fmt.Sprintf("%d", f.Position(beginPos).Line)
beginColumn := fmt.Sprintf("%d", f.Position(beginPos).Column)
endLine := fmt.Sprintf("%d", f.Position(endPos).Line)
endColumn := fmt.Sprintf("%d", f.Position(endPos).Column)
err = csv.Write([]string{text, fuzzyText, beginLine, beginColumn, endLine, endColumn})
if err != nil {
log.Fatalf("Unable to write CSV data: %v", err)
}
}
if tok == token.EOF {
break
}
}
}
}

Просмотреть файл

@ -1,426 +0,0 @@
package dbscheme
import (
"fmt"
"io"
"log"
"reflect"
"strings"
"github.com/github/codeql-go/extractor/trap"
)
// A Type represents a database type
type Type interface {
def() string
ref() string
repr() string
valid(val interface{}) bool
}
// A PrimitiveType represents a primitive dataase type
type PrimitiveType int
const (
// INT represents the primitive database type `int`
INT PrimitiveType = iota
// FLOAT represents the primitive database type `float`
FLOAT
// BOOLEAN represents the primitive database type `boolean`
BOOLEAN
// DATE represents the primitive database type `date`
DATE
// STRING represents the primitive database type `string`
STRING
)
// A PrimaryKeyType represents a database type defined by a primary key column
type PrimaryKeyType struct {
name string
}
// A UnionType represents a database type defined as the union of other database types
type UnionType struct {
name string
components []Type
}
// An AliasType represents a database type which is an alias of another database type
type AliasType struct {
name string
underlying Type
}
// A CaseType represents a database type defined by a primary key column with a supplementary kind column
type CaseType struct {
base Type
column string
branches []*BranchType
}
// A BranchType represents one branch of a case type
type BranchType struct {
idx int
name string
}
func (pt PrimitiveType) def() string {
return ""
}
func (pt PrimitiveType) ref() string {
switch pt {
case INT:
return "int"
case FLOAT:
return "float"
case BOOLEAN:
return "boolean"
case DATE:
return "date"
case STRING:
return "string"
default:
panic(fmt.Sprintf("Unexpected primitive type %d", pt))
}
}
func (pt PrimitiveType) repr() string {
switch pt {
case INT:
return "int"
case FLOAT:
return "float"
case BOOLEAN:
return "boolean"
case DATE:
return "date"
case STRING:
return "string"
default:
panic(fmt.Sprintf("Unexpected primitive type %d", pt))
}
}
func (pt PrimitiveType) valid(value interface{}) bool {
switch value.(type) {
case int:
return pt == INT
case float64:
return pt == FLOAT
case bool:
return pt == BOOLEAN
case string:
return pt == STRING
}
return false
}
func (pkt PrimaryKeyType) def() string {
return ""
}
func (pkt PrimaryKeyType) ref() string {
return pkt.name
}
func (pkt PrimaryKeyType) repr() string {
return "int"
}
func (pkt PrimaryKeyType) valid(value interface{}) bool {
_, ok := value.(trap.Label)
return ok
}
func (ut UnionType) def() string {
var b strings.Builder
nl := 0
fmt.Fprintf(&b, "%s = ", ut.name)
for i, comp := range ut.components {
if i > 0 {
if i < len(ut.components)-1 && b.Len()-nl > 100 {
fmt.Fprintf(&b, "\n%s", strings.Repeat(" ", len(ut.name)))
nl = b.Len()
}
fmt.Fprint(&b, " | ")
}
fmt.Fprint(&b, comp.ref())
}
fmt.Fprint(&b, ";")
return b.String()
}
func (ut UnionType) ref() string {
return ut.name
}
func (ut UnionType) repr() string {
return "int"
}
func (ut UnionType) valid(value interface{}) bool {
_, ok := value.(trap.Label)
return ok
}
func (at AliasType) def() string {
return at.name + " = " + at.underlying.ref() + ";"
}
func (at AliasType) ref() string {
return at.name
}
func (at AliasType) repr() string {
return at.underlying.repr()
}
func (at AliasType) valid(value interface{}) bool {
return at.underlying.valid(value)
}
func (ct CaseType) def() string {
var b strings.Builder
fmt.Fprintf(&b, "case %s.%s of", ct.base.ref(), ct.column)
sep := " "
for _, branch := range ct.branches {
fmt.Fprintf(&b, "\n%s%s", sep, branch.def())
sep = "| "
}
fmt.Fprint(&b, ";")
return b.String()
}
func (ct CaseType) ref() string {
panic("case types do not have a name")
}
func (ct CaseType) repr() string {
return "int"
}
func (ct CaseType) valid(value interface{}) bool {
_, ok := value.(trap.Label)
return ok
}
func (bt BranchType) def() string {
return fmt.Sprintf("%d = %s", bt.idx, bt.name)
}
func (bt BranchType) ref() string {
return bt.name
}
func (bt BranchType) repr() string {
return "int"
}
func (bt BranchType) valid(value interface{}) bool {
_, ok := value.(trap.Label)
return ok
}
// Index returns the numeric index of this branch type
func (bt BranchType) Index() int {
return bt.idx
}
// A Column represents a column in a database table
type Column struct {
columnName string
columnType Type
unique bool
ref bool
}
func (col Column) String() string {
var b strings.Builder
if col.unique {
fmt.Fprint(&b, "unique ")
}
fmt.Fprintf(&b, "%s %s: %s", col.columnType.repr(), col.columnName, col.columnType.ref())
if col.ref {
fmt.Fprint(&b, " ref")
}
return b.String()
}
// Key returns a new column that is the same as this column, but has the `key` flag set to `true`
func (col Column) Key() Column {
return Column{col.columnName, col.columnType, true, false}
}
// Unique returns a new column that is the same as this column, but has the `unique` flag set to `true`
func (col Column) Unique() Column {
return Column{col.columnName, col.columnType, true, col.ref}
}
// EntityColumn constructs a column with name `columnName` holding entities of type `columnType`
func EntityColumn(columnType Type, columnName string) Column {
return Column{columnName, columnType, false, true}
}
// StringColumn constructs a column with name `columnName` holding string values
func StringColumn(columnName string) Column {
return Column{columnName, STRING, false, true}
}
// IntColumn constructs a column with name `columnName` holding integer values
func IntColumn(columnName string) Column {
return Column{columnName, INT, false, true}
}
// FloatColumn constructs a column with name `columnName` holding floating point number values
func FloatColumn(columnName string) Column {
return Column{columnName, FLOAT, false, true}
}
// A Table represents a database table
type Table struct {
name string
schema []Column
keysets [][]string
}
// KeySet adds `keys` as a keyset to this table
func (tbl *Table) KeySet(keys ...string) *Table {
tbl.keysets = append(tbl.keysets, keys)
return tbl
}
func (tbl Table) String() string {
var b strings.Builder
for _, keyset := range tbl.keysets {
fmt.Fprint(&b, "#keyset[")
sep := ""
for _, key := range keyset {
fmt.Fprintf(&b, "%s%s", sep, key)
sep = ", "
}
fmt.Fprint(&b, "]\n")
}
fmt.Fprint(&b, tbl.name)
fmt.Fprint(&b, "(")
nl := 0
for i, column := range tbl.schema {
if i > 0 {
// wrap >100 char lines
if i < len(tbl.schema)-1 && b.Len()-nl > 100 {
fmt.Fprintf(&b, ",\n%s", strings.Repeat(" ", len(tbl.name)+1))
nl = b.Len()
} else {
fmt.Fprint(&b, ", ")
}
}
fmt.Fprint(&b, column.String())
}
fmt.Fprint(&b, ");")
return b.String()
}
// Emit outputs a tuple of `values` for this table using trap writer `tw`
// and panicks if the tuple does not have the right schema
func (tbl Table) Emit(tw *trap.Writer, values ...interface{}) {
if ncol, nval := len(tbl.schema), len(values); ncol != nval {
log.Fatalf("wrong number of values for table %s; expected %d, but got %d", tbl.name, ncol, nval)
}
for i, col := range tbl.schema {
if !col.columnType.valid(values[i]) {
panic(fmt.Sprintf("Invalid value for column %d of table %s; expected a %s, but got %s which is a %s", i, tbl.name, col.columnType.ref(), values[i], reflect.TypeOf(values[i])))
}
}
tw.Emit(tbl.name, values)
}
var tables = []*Table{}
var types = []Type{}
var defaultSnippets = []string{}
// NewTable constructs a new table with the given `name` and `columns`
func NewTable(name string, columns ...Column) *Table {
tbl := &Table{name, columns, [][]string{}}
tables = append(tables, tbl)
return tbl
}
// NewPrimaryKeyType constructs a new primary key type with the given `name`,
// and adds it to the union types `parents` (if any)
func NewPrimaryKeyType(name string, parents ...*UnionType) *PrimaryKeyType {
tp := &PrimaryKeyType{name}
types = append(types, tp)
for _, parent := range parents {
parent.components = append(parent.components, tp)
}
return tp
}
// NewUnionType constructs a new union type with the given `name`,
// and adds it to the union types `parents` (if any)
func NewUnionType(name string, parents ...*UnionType) *UnionType {
tp := &UnionType{name, []Type{}}
types = append(types, tp)
for _, parent := range parents {
parent.components = append(parent.components, tp)
}
return tp
}
// AddChild adds the type with given `name` to the union type.
// This is useful if a type defined in a snippet should be a child of a type defined in Go.
func (parent *UnionType) AddChild(name string) bool {
tp := &PrimaryKeyType{name}
// don't add tp to types; it's expected that it's already in the db somehow.
parent.components = append(parent.components, tp)
return true
}
// NewAliasType constructs a new alias type with the given `name` that aliases `underlying`
func NewAliasType(name string, underlying Type) *AliasType {
tp := &AliasType{name, underlying}
types = append(types, tp)
return tp
}
// NewCaseType constructs a new case type on the given `base` type whose discriminator values
// come from `column`
func NewCaseType(base Type, column string) *CaseType {
tp := &CaseType{base, column, []*BranchType{}}
types = append(types, tp)
return tp
}
// NewBranch adds a new branch with the given `name` to this case type
// and adds it to the union types `parents` (if any)
func (ct *CaseType) NewBranch(name string, parents ...*UnionType) *BranchType {
tp := &BranchType{len(ct.branches), name}
ct.branches = append(ct.branches, tp)
for _, parent := range parents {
parent.components = append(parent.components, tp)
}
return tp
}
// AddDefaultSnippet adds the given text `snippet` to the schema of this database
func AddDefaultSnippet(snippet string) bool {
defaultSnippets = append(defaultSnippets, snippet)
return true
}
// PrintDbScheme prints the schema of this database to the writer `w`
func PrintDbScheme(w io.Writer) {
fmt.Fprintf(w, "/** Auto-generated dbscheme; do not edit. */\n\n")
for _, snippet := range defaultSnippets {
fmt.Fprintf(w, "%s\n", snippet)
}
for _, table := range tables {
fmt.Fprintf(w, "%s\n\n", table.String())
}
for _, tp := range types {
def := tp.def()
if def != "" {
fmt.Fprintf(w, "%s\n\n", def)
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,201 +0,0 @@
package extractor
import (
"fmt"
"golang.org/x/mod/modfile"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/github/codeql-go/extractor/dbscheme"
"github.com/github/codeql-go/extractor/srcarchive"
"github.com/github/codeql-go/extractor/trap"
)
func (extraction *Extraction) extractGoMod(path string) error {
if normPath, err := filepath.EvalSymlinks(path); err == nil {
path = normPath
}
extraction.Lock.Lock()
if extraction.SeenGoMods[path] {
extraction.Lock.Unlock()
return nil
}
extraction.SeenGoMods[path] = true
extraction.Lock.Unlock()
tw, err := trap.NewWriter(path, nil)
if err != nil {
return err
}
defer tw.Close()
err = srcarchive.Add(path)
if err != nil {
return err
}
extraction.extractFileInfo(tw, path)
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open go.mod file %s: %s", path, err.Error())
}
data, err := ioutil.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read go.mod file %s: %s", path, err.Error())
}
modfile, err := modfile.Parse(path, data, nil)
if err != nil {
return fmt.Errorf("failed to parse go.mod file %s: %s", path, err.Error())
}
extractGoModFile(tw, modfile.Syntax)
return nil
}
type commentGroupIdxAllocator struct {
nextIdx int
}
func (cgIdxAlloc *commentGroupIdxAllocator) nextCgIdx() int {
ret := cgIdxAlloc.nextIdx
cgIdxAlloc.nextIdx++
return ret
}
func extractGoModFile(tw *trap.Writer, file *modfile.FileSyntax) {
cgIdxAlloc := commentGroupIdxAllocator{0}
for idx, stmt := range file.Stmt {
extractGoModExpr(tw, stmt, tw.Labeler.FileLabel(), idx, &cgIdxAlloc)
}
extractGoModComments(tw, file, tw.Labeler.FileLabel(), &cgIdxAlloc)
}
func extractGoModExpr(tw *trap.Writer, expr modfile.Expr, parent trap.Label, idx int, cgIdxAlloc *commentGroupIdxAllocator) {
lbl := tw.Labeler.LocalID(expr)
var kind int
switch expr := expr.(type) {
case *modfile.CommentBlock:
kind = dbscheme.ModCommentBlockType.Index()
case *modfile.LParen:
kind = dbscheme.ModLParenType.Index()
case *modfile.RParen:
kind = dbscheme.ModRParenType.Index()
case *modfile.Line:
kind = dbscheme.ModLineType.Index()
for idx, tok := range expr.Token {
dbscheme.ModTokensTable.Emit(tw, tok, lbl, idx)
}
case *modfile.LineBlock:
kind = dbscheme.ModLineBlockType.Index()
for idx, tok := range expr.Token {
dbscheme.ModTokensTable.Emit(tw, tok, lbl, idx)
}
extractGoModExpr(tw, &expr.LParen, lbl, 0, cgIdxAlloc)
for idx, line := range expr.Line {
extractGoModExpr(tw, line, lbl, idx+1, cgIdxAlloc)
}
extractGoModExpr(tw, &expr.RParen, lbl, len(expr.Line)+1, cgIdxAlloc)
default:
log.Fatalf("unknown go.mod expression of type %T", expr)
}
dbscheme.ModExprsTable.Emit(tw, lbl, kind, parent, idx)
extractGoModComments(tw, expr, lbl, cgIdxAlloc)
start, end := expr.Span()
extractLocation(tw, lbl, start.Line, start.LineRune, end.Line, end.LineRune)
}
type GoModExprCommentWrapper struct {
expr modfile.Expr
}
func minInt(a int, b int) int {
if a < b {
return a
}
return b
}
func maxInt(a int, b int) int {
if a > b {
return a
}
return b
}
func lexMin(a1 int, a2 int, b1 int, b2 int) (int, int) {
if a1 < b1 {
return a1, a2
} else if a1 > b1 {
return b1, b2
} else {
return a1, minInt(b1, b2)
}
}
func lexMax(a1 int, a2 int, b1 int, b2 int) (int, int) {
if a1 < b1 {
return b1, b2
} else if a1 > b1 {
return a1, a2
} else {
return a1, maxInt(b1, b2)
}
}
func extractGoModComments(tw *trap.Writer, expr modfile.Expr, exprlbl trap.Label, cgIdxAlloc *commentGroupIdxAllocator) {
comments := expr.Comment()
if len(comments.Before) == 0 && len(comments.Suffix) == 0 && len(comments.After) == 0 {
return
}
// extract a pseudo `@commentgroup` for each expr that contains their associated comments
grouplbl := tw.Labeler.LocalID(GoModExprCommentWrapper{expr})
dbscheme.CommentGroupsTable.Emit(tw, grouplbl, tw.Labeler.FileLabel(), cgIdxAlloc.nextCgIdx())
dbscheme.DocCommentsTable.Emit(tw, exprlbl, grouplbl)
var allComments []modfile.Comment
allComments = append(allComments, comments.Before...)
allComments = append(allComments, comments.Suffix...)
allComments = append(allComments, comments.After...)
var startLine, startCol, endLine, endCol int = 0, 0, 0, 0
var first bool = true
idx := 0
for _, comment := range allComments {
commentToken := strings.TrimSuffix(strings.TrimSuffix(comment.Token, "\n"), "\r")
extractGoModComment(tw, comment, commentToken, grouplbl, idx)
idx++
commentEndCol := comment.Start.LineRune + (len(commentToken) - 1)
if first {
startLine, startCol, endLine, endCol = comment.Start.Line, comment.Start.LineRune, comment.Start.Line, commentEndCol
first = false
} else {
startLine, startCol = lexMin(comment.Start.Line, comment.Start.LineRune, startLine, startCol)
endLine, endCol = lexMax(comment.Start.Line, commentEndCol, endLine, endCol)
}
}
extractLocation(tw, grouplbl, startLine, startCol, endLine, endCol)
}
func extractGoModComment(tw *trap.Writer, comment modfile.Comment, commentToken string, grouplbl trap.Label, idx int) {
lbl := tw.Labeler.LocalID(comment)
dbscheme.CommentsTable.Emit(tw, lbl, dbscheme.SlashSlashComment.Index(), grouplbl, idx, commentToken)
extractLocation(tw, lbl, comment.Start.Line, comment.Start.LineRune, comment.Start.Line, comment.Start.LineRune+(len(commentToken)-1))
}

Просмотреть файл

@ -1,13 +0,0 @@
package net.sourceforge.pmd.cpd;
/*
* This is a stub definition for pmd's AbstractLanguage class
* including only the API used by the GoLanguage class.
*/
public abstract class AbstractLanguage {
public AbstractLanguage(String... extensions) {}
public abstract Tokenizer getTokenizer(boolean fuzzyMatch);
}

Просмотреть файл

@ -1,68 +0,0 @@
package net.sourceforge.pmd.cpd;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.util.List;
import opencsv.CSVReader;
public class GoLanguage extends AbstractLanguage {
public GoLanguage() {
super(".go");
}
@Override
public Tokenizer getTokenizer(final boolean fuzzyMatch) {
return new Tokenizer() {
@Override
public void tokenize(SourceCode tokens, List<TokenEntry> tokenEntries) {
String fileName = tokens.getFileName();
String platform = "linux", exe = "";
String osName = System.getProperty("os.name", "unknown");
if (osName.contains("Windows")) {
platform = "win";
exe = ".exe";
} else if (osName.contains("Mac OS X")) {
platform = "osx";
}
// get tools folder from SEMMLE_DIST
String toolsDir = null;
String dist = System.getenv("SEMMLE_DIST");
if (dist != null && !dist.isEmpty()) {
toolsDir = dist + "/language-packs/go/tools/platform/" + platform;
}
String goTokenizer = toolsDir == null ? "go-tokenizer" : toolsDir + "/bin/go-tokenizer";
goTokenizer += exe;
ProcessBuilder pb = new ProcessBuilder(Paths.get(goTokenizer).toString(), fileName);
pb.redirectError(Redirect.INHERIT);
try {
Process process = pb.start();
try (
CSVReader r = new CSVReader(new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")))
) {
String[] row;
while ((row = r.readNext()) != null) {
String text = row[0];
String fuzzyText = row[1];
int beginLine = Integer.parseInt(row[2]);
int beginColumn = Integer.parseInt(row[3]);
int endLine = Integer.parseInt(row[4]);
int endColumn = Integer.parseInt(row[5]);
tokenEntries.add(new TokenEntry(fuzzyMatch ? text : fuzzyText, fileName, beginLine, beginColumn, endLine, endColumn));
}
}
int exitCode = process.waitFor();
if (exitCode != 0)
throw new RuntimeException("Tokenizing " + fileName + " returned " + exitCode + ".");
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
};
}
}

Просмотреть файл

@ -1,12 +0,0 @@
package net.sourceforge.pmd.cpd;
/*
* This is a stub definition for pmd's SourceCode class
* including only the API used by the GoLanguage class.
*/
public class SourceCode {
public String getFileName() {
return null;
}
}

Просмотреть файл

@ -1,11 +0,0 @@
package net.sourceforge.pmd.cpd;
/*
* This is a stub definition for pmd's TokenEntry class
* including only the API used by the GoLanguage class.
*/
public class TokenEntry {
public TokenEntry(String image, String tokenSrcID, int beginLine, int beginColumn, int endLine, int endColumn) {
}
}

Просмотреть файл

@ -1,12 +0,0 @@
package net.sourceforge.pmd.cpd;
/*
* This is a stub definition for pmd's Tokenizer interface
* including only the API used by the GoLanguage class.
*/
import java.util.List;
public interface Tokenizer {
void tokenize(SourceCode tokens, List<TokenEntry> tokenEntries);
}

Просмотреть файл

@ -1,207 +0,0 @@
/**
Copyright 2005 Bytecode Pty Ltd.
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.
*/
package opencsv;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A very simple CSV parser released under a commercial-friendly license.
* This just implements splitting a single line into fields.
*
* @author Glen Smith
* @author Rainer Pruy
*
*/
public class CSVParser {
private final char separator;
private final char quotechar;
private final char escape;
private final boolean strictQuotes;
private StringBuilder buf = new StringBuilder(INITIAL_READ_SIZE);
/** The default separator to use if none is supplied to the constructor. */
public static final char DEFAULT_SEPARATOR = ',';
private static final int INITIAL_READ_SIZE = 128;
/**
* The default quote character to use if none is supplied to the
* constructor.
*/
public static final char DEFAULT_QUOTE_CHARACTER = '"';
/**
* The default escape character to use if none is supplied to the
* constructor.
*/
public static final char DEFAULT_ESCAPE_CHARACTER = '"';
/**
* The default strict quote behavior to use if none is supplied to the
* constructor
*/
public static final boolean DEFAULT_STRICT_QUOTES = false;
/**
* Constructs CSVReader with supplied separator and quote char.
* Allows setting the "strict quotes" flag
* @param separator
* the delimiter to use for separating entries
* @param quotechar
* the character to use for quoted elements
* @param escape
* the character to use for escaping a separator or quote
* @param strictQuotes
* if true, characters outside the quotes are ignored
*/
CSVParser(char separator, char quotechar, char escape, boolean strictQuotes) {
this.separator = separator;
this.quotechar = quotechar;
this.escape = escape;
this.strictQuotes = strictQuotes;
}
/**
*
* @return true if something was left over from last call(s)
*/
public boolean isPending() {
return buf.length() != 0;
}
public String[] parseLineMulti(String nextLine) throws IOException {
return parseLine(nextLine, true);
}
public String[] parseLine(String nextLine) throws IOException {
return parseLine(nextLine, false);
}
/**
* Parses an incoming String and returns an array of elements.
*
* @param nextLine
* the string to parse
* @return the comma-tokenized list of elements, or null if nextLine is null
* @throws IOException if bad things happen during the read
*/
private String[] parseLine(String nextLine, boolean multi) throws IOException {
if (!multi && isPending()) {
clear();
}
if (nextLine == null) {
if (isPending()) {
String s = buf.toString();
clear();
return new String[] {s};
} else {
return null;
}
}
List<String>tokensOnThisLine = new ArrayList<String>();
boolean inQuotes = isPending();
for (int i = 0; i < nextLine.length(); i++) {
char c = nextLine.charAt(i);
if (c == this.escape && isNextCharacterEscapable(nextLine, inQuotes, i)) {
buf.append(nextLine.charAt(i+1));
i++;
} else if (c == quotechar) {
if( isNextCharacterEscapedQuote(nextLine, inQuotes, i) ){
buf.append(nextLine.charAt(i+1));
i++;
}else{
inQuotes = !inQuotes;
// the tricky case of an embedded quote in the middle: a,bc"d"ef,g
if (!strictQuotes) {
if(i>2 //not on the beginning of the line
&& nextLine.charAt(i-1) != this.separator //not at the beginning of an escape sequence
&& nextLine.length()>(i+1) &&
nextLine.charAt(i+1) != this.separator //not at the end of an escape sequence
){
buf.append(c);
}
}
}
} else if (c == separator && !inQuotes) {
tokensOnThisLine.add(buf.toString());
clear(); // start work on next token
} else {
if (!strictQuotes || inQuotes)
buf.append(c);
}
}
// line is done - check status
if (inQuotes) {
if (multi) {
// continuing a quoted section, re-append newline
buf.append('\n');
// this partial content is not to be added to field list yet
} else {
throw new IOException("Un-terminated quoted field at end of CSV line");
}
} else {
tokensOnThisLine.add(buf.toString());
clear();
}
return tokensOnThisLine.toArray(new String[tokensOnThisLine.size()]);
}
/**
* precondition: the current character is a quote or an escape
* @param nextLine the current line
* @param inQuotes true if the current context is quoted
* @param i current index in line
* @return true if the following character is a quote
*/
private boolean isNextCharacterEscapedQuote(String nextLine, boolean inQuotes, int i) {
return inQuotes // we are in quotes, therefore there can be escaped quotes in here.
&& nextLine.length() > (i+1) // there is indeed another character to check.
&& nextLine.charAt(i+1) == quotechar;
}
/**
* precondition: the current character is an escape
* @param nextLine the current line
* @param inQuotes true if the current context is quoted
* @param i current index in line
* @return true if the following character is a quote
*/
protected boolean isNextCharacterEscapable(String nextLine, boolean inQuotes, int i) {
return inQuotes // we are in quotes, therefore there can be escaped quotes in here.
&& nextLine.length() > (i+1) // there is indeed another character to check.
&& ( nextLine.charAt(i+1) == quotechar || nextLine.charAt(i+1) == this.escape);
}
/**
* Reset the buffer used for storing the current field's value
*/
private void clear() {
buf.setLength(0);
}
}

Просмотреть файл

@ -1,192 +0,0 @@
/**
Copyright 2005 Bytecode Pty Ltd.
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.
*/
package opencsv;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* A very simple CSV reader released under a commercial-friendly license.
*
* @author Glen Smith
*
*/
public class CSVReader implements Closeable {
private final BufferedReader br;
private boolean hasNext = true;
private final CSVParser parser;
private final int skipLines;
private boolean linesSkipped;
/** The line number of the last physical line read (one-based). */
private int curline = 0;
/** The physical line number at which the last logical line read started (one-based). */
private int startLine = 0;
/**
* The default line to start reading.
*/
private static final int DEFAULT_SKIP_LINES = 0;
/**
* Constructs CSVReader using a comma for the separator.
*
* @param reader
* the reader to an underlying CSV source.
*/
public CSVReader(Reader reader) {
this(reader,
CSVParser.DEFAULT_SEPARATOR, CSVParser.DEFAULT_QUOTE_CHARACTER,
CSVParser.DEFAULT_ESCAPE_CHARACTER, DEFAULT_SKIP_LINES,
CSVParser.DEFAULT_STRICT_QUOTES);
}
/**
* Constructs CSVReader with supplied separator and quote char.
*
* @param reader
* the reader to an underlying CSV source.
* @param separator
* the delimiter to use for separating entries
* @param quotechar
* the character to use for quoted elements
* @param escape
* the character to use for escaping a separator or quote
* @param line
* the line number to skip for start reading
* @param strictQuotes
* sets if characters outside the quotes are ignored
*/
private CSVReader(Reader reader, char separator, char quotechar, char escape, int line, boolean strictQuotes) {
this.br = new BufferedReader(reader);
this.parser = new CSVParser(separator, quotechar, escape, strictQuotes);
this.skipLines = line;
}
/**
* Reads the entire file into a List with each element being a String[] of
* tokens.
*
* @return a List of String[], with each String[] representing a line of the
* file.
*
* @throws IOException
* if bad things happen during the read
*/
public List<String[]> readAll() throws IOException {
List<String[]> allElements = new ArrayList<String[]>();
while (hasNext) {
String[] nextLineAsTokens = readNext();
if (nextLineAsTokens != null)
allElements.add(nextLineAsTokens);
}
return allElements;
}
/**
* Reads the next line from the buffer and converts to a string array.
*
* @return a string array with each comma-separated element as a separate
* entry, or null if there are no more lines to read.
*
* @throws IOException
* if bad things happen during the read
*/
public String[] readNext() throws IOException {
boolean first = true;
String[] result = null;
do {
String nextLine = getNextLine();
if (first) {
startLine = curline;
first = false;
}
if (!hasNext) {
return result; // should throw if still pending?
}
String[] r = parser.parseLineMulti(nextLine);
if (r.length > 0) {
if (result == null) {
result = r;
} else {
String[] t = new String[result.length+r.length];
System.arraycopy(result, 0, t, 0, result.length);
System.arraycopy(r, 0, t, result.length, r.length);
result = t;
}
}
} while (parser.isPending());
return result;
}
/**
* Reads the next line from the file.
*
* @return the next line from the file without trailing newline
* @throws IOException
* if bad things happen during the read
*/
private String getNextLine() throws IOException {
if (!this.linesSkipped) {
for (int i = 0; i < skipLines; i++) {
br.readLine();
++curline;
}
this.linesSkipped = true;
}
String nextLine = br.readLine();
if (nextLine == null) {
hasNext = false;
} else {
++curline;
}
return hasNext ? nextLine : null;
}
/**
* Closes the underlying reader.
*
* @throws IOException if the close fails
*/
@Override
public void close() throws IOException{
br.close();
}
/**
* Return the physical line number (one-based) at which the last logical line read started,
* or zero if no line has been read yet.
*/
public int getStartLine() {
return startLine;
}
}

Просмотреть файл

@ -1,42 +0,0 @@
package extractor
import (
"log"
)
type Unit struct{}
var unit = Unit{}
type semaphore struct {
counter, lock chan Unit
}
func (s *semaphore) acquire(n int) {
if s != nil {
if cap(s.counter) < n {
log.Fatalf("Tried to acquire more resources than were available.")
}
s.lock <- unit
for i := 0; i < n; i++ {
s.counter <- unit
}
<-s.lock
}
}
func (s *semaphore) release(n int) {
if s != nil {
for i := 0; i < n; i++ {
<-s.counter
}
}
}
func newSemaphore(max int) *semaphore {
if max > 0 {
return &semaphore{make(chan Unit, max), make(chan Unit, 1)}
} else {
return nil
}
}

Просмотреть файл

@ -1,105 +0,0 @@
package srcarchive
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
)
// ProjectLayout describes a very simple project layout rewriting paths starting
// with `from` to start with `to` instead.
//
// We currently only support project layouts of the form
//
// # to
// from//
type ProjectLayout struct {
from, to string
}
// normaliseSlashes adds an initial slash to `path` if there isn't one, and trims
// a final slash if there is one
func normaliseSlashes(path string) string {
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
return strings.TrimSuffix(path, "/")
}
// LoadProjectLayout loads a project layout from the given file, returning an error
// if the file does not have the right format
func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
res := ProjectLayout{}
scanner := bufio.NewScanner(file)
line := ""
for ; line == "" && scanner.Scan(); line = strings.TrimSpace(scanner.Text()) {
}
if !strings.HasPrefix(line, "#") {
return nil, fmt.Errorf("first line of project layout should start with #, but got %s", line)
}
res.to = normaliseSlashes(strings.TrimSpace(strings.TrimPrefix(line, "#")))
if !scanner.Scan() {
return nil, errors.New("empty section in project-layout file")
}
line = strings.TrimSpace(scanner.Text())
if !strings.HasSuffix(line, "//") {
return nil, errors.New("unsupported project-layout feature")
}
line = strings.TrimSuffix(line, "//")
if strings.HasPrefix(line, "-") || strings.Contains(line, "*") || strings.Contains(line, "//") {
return nil, errors.New("unsupported project-layout feature")
}
res.from = normaliseSlashes(line)
for scanner.Scan() {
if strings.TrimSpace(scanner.Text()) != "" {
return nil, errors.New("only one section with one rewrite supported")
}
}
return &res, nil
}
// transformString transforms `str` as specified by the project layout: if it starts with the `from`
// prefix, that prefix is relaced by `to`; otherwise the string is returned unchanged
func (p *ProjectLayout) transformString(str string) string {
if str == p.from {
return p.to
}
if strings.HasPrefix(str, p.from+"/") {
return p.to + "/" + str[len(p.from)+1:]
}
return str
}
// isWindowsPath checks whether the substring of `path` starting at `idx` looks like a (slashified)
// Windows path, that is, starts with a drive letter followed by a colon and a slash
func isWindowsPath(path string, idx int) bool {
return len(path) >= 3+idx &&
path[idx] != '/' &&
path[idx+1] == ':' && path[idx+2] == '/'
}
// Transform transforms the given path according to the project layout: if it starts with the `from`
// prefix, that prefix is relaced by `to`; otherwise the path is returned unchanged.
//
// Unlike the (internal) method `transformString`, this method handles Windows paths sensibly.
func (p *ProjectLayout) Transform(path string) string {
if isWindowsPath(path, 0) {
result := p.transformString("/" + path)
if isWindowsPath(result, 1) && result[0] == '/' {
return result[1:]
}
return result
} else {
return p.transformString(path)
}
}

Просмотреть файл

@ -1,136 +0,0 @@
package srcarchive
import (
"io/ioutil"
"os"
"testing"
)
func mkProjectLayout(projectLayoutSource string, t *testing.T) (*ProjectLayout, error) {
pt, err := ioutil.TempFile("", "path-transformer")
if err != nil {
t.Fatalf("Unable to create temporary file for project layout: %s", err.Error())
}
defer os.Remove(pt.Name())
_, err = pt.WriteString(projectLayoutSource)
if err != nil {
t.Fatalf("Unable to write to temporary file for project layout: %s", err.Error())
}
err = pt.Close()
if err != nil {
t.Fatalf("Unable to close path transformer file: %s.", err.Error())
}
pt, err = os.Open(pt.Name())
if err != nil {
t.Fatalf("Unable to open path transformer file: %s.", err.Error())
}
return LoadProjectLayout(pt)
}
func testTransformation(projectLayout *ProjectLayout, t *testing.T, path string, expected string) {
actual := projectLayout.Transform(path)
if actual != expected {
t.Errorf("Expected %s to be transformed to %s, but got %s", path, expected, actual)
}
}
func TestValidProjectLayout(t *testing.T) {
p, err := mkProjectLayout(`
# /opt/src
/opt/src/root/src/org/repo//
`, t)
if err != nil {
t.Fatalf("Error loading project layout: %s", err.Error())
}
testTransformation(p, t, "/opt/src/root/src/org/repo", "/opt/src")
testTransformation(p, t, "/opt/src/root/src/org/repo/", "/opt/src/")
testTransformation(p, t, "/opt/src/root/src/org/repo/main.go", "/opt/src/main.go")
testTransformation(p, t, "/opt/not/in/src", "/opt/not/in/src")
testTransformation(p, t, "/opt/src/root/srcorg/repo", "/opt/src/root/srcorg/repo")
testTransformation(p, t, "opt/src/root/src/org/repo", "opt/src/root/src/org/repo")
}
func TestWindowsPaths(t *testing.T) {
p, err := mkProjectLayout(`
# /c:/virtual
/d://
`, t)
if err != nil {
t.Fatalf("Error loading project layout: %s", err.Error())
}
testTransformation(p, t, "d:/foo", "c:/virtual/foo")
}
func TestWindowsToUnixPaths(t *testing.T) {
p, err := mkProjectLayout(`
# /opt/src
/d://
`, t)
if err != nil {
t.Fatalf("Error loading project layout: %s", err.Error())
}
testTransformation(p, t, "d:/foo", "/opt/src/foo")
}
func TestEmptyProjectLayout(t *testing.T) {
_, err := mkProjectLayout("", t)
if err == nil {
t.Error("Expected error on empty project layout")
}
}
func TestEmptyProjectLayout2(t *testing.T) {
_, err := mkProjectLayout(`
`, t)
if err == nil {
t.Error("Expected error on empty project layout")
}
}
func TestExclusion(t *testing.T) {
_, err := mkProjectLayout(`
# /opt/src
-/foo//
`, t)
if err == nil {
t.Error("Expected error on exclusion")
}
}
func TestStar(t *testing.T) {
_, err := mkProjectLayout(`
# /opt/src
/foo/**/bar//
`, t)
if err == nil {
t.Error("Expected error on star")
}
}
func TestDoubleSlash(t *testing.T) {
_, err := mkProjectLayout(`
# /opt/src
/foo//bar//
`, t)
if err == nil {
t.Error("Expected error on multiple double slashes")
}
}
func TestInternalDoubleSlash(t *testing.T) {
_, err := mkProjectLayout(`
# /opt/src
/foo//bar
`, t)
if err == nil {
t.Error("Expected error on internal double slash")
}
}

Просмотреть файл

@ -1,85 +0,0 @@
package srcarchive
import (
"errors"
"io"
"log"
"os"
"path/filepath"
"strings"
)
var pathTransformer *ProjectLayout
func init() {
pt := os.Getenv("SEMMLE_PATH_TRANSFORMER")
if pt != "" {
ptf, err := os.Open(pt)
if err != nil {
log.Fatalf("Unable to open path transformer %s: %s.\n", pt, err.Error())
}
pathTransformer, err = LoadProjectLayout(ptf)
if err != nil {
log.Fatalf("Unable to initialize path transformer: %s.\n", err.Error())
}
}
}
// Add inserts the file with the given `path` into the source archive, returning a non-nil
// error value if it fails
func Add(path string) error {
srcArchive, err := srcArchive()
if err != nil {
return err
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
archiveFilePath := filepath.Join(srcArchive, AppendablePath(path))
err = os.MkdirAll(filepath.Dir(archiveFilePath), 0755)
if err != nil {
return err
}
archiveFile, err := os.Create(archiveFilePath)
if err != nil {
return err
}
defer archiveFile.Close()
_, err = io.Copy(archiveFile, file)
return err
}
func srcArchive() (string, error) {
srcArchive := os.Getenv("CODEQL_EXTRACTOR_GO_SOURCE_ARCHIVE_DIR")
if srcArchive == "" {
srcArchive = os.Getenv("SOURCE_ARCHIVE")
}
if srcArchive == "" {
return "", errors.New("environment variable CODEQL_EXTRACTOR_GO_SOURCE_ARCHIVE_DIR not set")
}
err := os.MkdirAll(srcArchive, 0755)
if err != nil {
return "", err
}
return srcArchive, nil
}
// TransformPath applies the transformations specified by `SEMMLE_PATH_TRANSFORMER` (if any) to the
// given path
func TransformPath(path string) string {
if pathTransformer != nil {
return filepath.FromSlash(pathTransformer.Transform(filepath.ToSlash(path)))
}
return path
}
// AppendablePath transforms the given path and also replaces colons with underscores to make it
// possible to append it to a base path on Windows
func AppendablePath(path string) string {
return strings.ReplaceAll(TransformPath(path), ":", "_")
}

Просмотреть файл

@ -1,232 +0,0 @@
package trap
import (
"fmt"
"go/types"
"github.com/github/codeql-go/extractor/util"
)
// Label represents a label
type Label struct {
id string
}
// InvalidLabel represents an uninitialized or otherwise invalid label
var InvalidLabel Label
func (lbl *Label) String() string {
return lbl.id
}
// Labeler is used to represent labels for a file. It is used to write
// associate objects with labels.
type Labeler struct {
tw *Writer
nextid int
fileLabel Label
nodeLabels map[interface{}]Label // labels associated with AST nodes
scopeLabels map[*types.Scope]Label // labels associated with scopes
objectLabels map[types.Object]Label // labels associated with objects (that is, declared entities)
TypeLabels map[types.Type]Label // labels associated with types
keyLabels map[string]Label
}
func newLabeler(tw *Writer) *Labeler {
return &Labeler{
tw,
10000,
InvalidLabel,
make(map[interface{}]Label),
make(map[*types.Scope]Label),
make(map[types.Object]Label),
make(map[types.Type]Label),
make(map[string]Label),
}
}
func (l *Labeler) nextID() string {
var id = l.nextid
l.nextid++
return fmt.Sprintf("#%d", id)
}
// GlobalID associates a label with the given `key` and returns it
func (l *Labeler) GlobalID(key string) Label {
label, exists := l.keyLabels[key]
if !exists {
id := l.nextID()
fmt.Fprintf(l.tw.zip, "%s=@\"%s\"\n", id, escapeString(key))
label = Label{id}
l.keyLabels[key] = label
}
return label
}
// FileLabel returns the label for a file with path `path`.
func (l *Labeler) FileLabel() Label {
if l.fileLabel == InvalidLabel {
l.fileLabel = l.FileLabelFor(l.tw.path)
}
return l.fileLabel
}
// FileLabelFor returns the label for the file for which the trap writer `tw` is associated
func (l *Labeler) FileLabelFor(path string) Label {
return l.GlobalID(util.EscapeTrapSpecialChars(path) + ";sourcefile")
}
// LocalID associates a label with the given AST node `nd` and returns it
func (l *Labeler) LocalID(nd interface{}) Label {
label, exists := l.nodeLabels[nd]
if !exists {
label = l.FreshID()
l.nodeLabels[nd] = label
}
return label
}
// FreshID creates a fresh label and returns it
func (l *Labeler) FreshID() Label {
id := l.nextID()
fmt.Fprintf(l.tw.zip, "%s=*\n", id)
return Label{id}
}
// ScopeID associates a label with the given scope and returns it
func (l *Labeler) ScopeID(scope *types.Scope, pkg *types.Package) Label {
label, exists := l.scopeLabels[scope]
if !exists {
if scope == types.Universe {
label = l.GlobalID("universe;scope")
} else {
if pkg != nil && pkg.Scope() == scope {
// if this scope is the package scope
pkgLabel := l.GlobalID(util.EscapeTrapSpecialChars(pkg.Path()) + ";package")
label = l.GlobalID("{" + pkgLabel.String() + "};scope")
} else {
label = l.FreshID()
}
}
l.scopeLabels[scope] = label
}
return label
}
// LookupObjectID looks up the label associated with the given object and returns it; if the object does not have
// a label yet, it tries to construct one based on its scope and/or name, and otherwise returns InvalidLabel
func (l *Labeler) LookupObjectID(object types.Object, typelbl Label) (Label, bool) {
label, exists := l.objectLabels[object]
if !exists {
if object.Parent() == nil {
// blank identifiers and the pseudo-package `.` (from `import . "..."` imports) can only be referenced
// once, so we can use a fresh label for them
if object.Name() == "_" || object.Name() == "." {
label = l.FreshID()
l.objectLabels[object] = label
return label, false
}
label = InvalidLabel
} else {
label, exists = l.ScopedObjectID(object, func() Label { return typelbl })
}
}
return label, exists
}
// ScopedObjectID associates a label with the given object and returns it,
// together with a flag indicating whether the object already had a label
// associated with it; the object must have a scope, since the scope's label is
// used to construct the label of the object.
//
// There is a special case for variables that are method receivers. When this is
// detected, we must construct a special label, as the variable can be reached
// from several files via the method. As the type label is required to construct
// the receiver object id, it is also required here.
func (l *Labeler) ScopedObjectID(object types.Object, getTypeLabel func() Label) (Label, bool) {
label, exists := l.objectLabels[object]
if !exists {
scope := object.Parent()
if scope == nil {
panic(fmt.Sprintf("Object has no scope: %v :: %v.\n", object,
l.tw.Package.Fset.Position(object.Pos())))
} else {
// associate method receiver objects to special keys, because those can be
// referenced from other files via their method
meth := findMethodWithGivenReceiver(object.Type(), object)
if meth == nil {
if pointerType, ok := object.Type().(*types.Pointer); ok {
meth = findMethodWithGivenReceiver(pointerType.Elem(), object)
}
}
if meth != nil {
methlbl, _ := l.MethodID(meth, getTypeLabel())
label, _ = l.ReceiverObjectID(object, methlbl)
} else {
scopeLbl := l.ScopeID(scope, object.Pkg())
label = l.GlobalID(fmt.Sprintf("{%v},%s;object", scopeLbl, object.Name()))
}
}
l.objectLabels[object] = label
}
return label, exists
}
func findMethodWithGivenReceiver(tp types.Type, object types.Object) *types.Func {
if namedType, ok := tp.(*types.Named); ok {
for i := 0; i < namedType.NumMethods(); i++ {
meth := namedType.Method(i)
if object == meth.Type().(*types.Signature).Recv() {
return meth
}
}
}
return nil
}
// ReceiverObjectID associates a label with the given object and returns it, together with a flag indicating whether
// the object already had a label associated with it; the object must be the receiver of `methlbl`, since that label
// is used to construct the label of the object
func (l *Labeler) ReceiverObjectID(object types.Object, methlbl Label) (Label, bool) {
label, exists := l.objectLabels[object]
if !exists {
// if we can't, construct a special label
label = l.GlobalID(fmt.Sprintf("{%v},%s;receiver", methlbl, object.Name()))
l.objectLabels[object] = label
}
return label, exists
}
// FieldID associates a label with the given field and returns it, together with
// a flag indicating whether the field already had a label associated with it;
// the field must belong to `structlbl`, since that label is used to construct
// the label of the field. When the field name is the blank identifier `_`,
// `idx` is used to generate a unique name.
func (l *Labeler) FieldID(field *types.Var, idx int, structlbl Label) (Label, bool) {
label, exists := l.objectLabels[field]
if !exists {
name := field.Name()
// there can be multiple fields with the blank identifier, so use index to
// distinguish them
if field.Name() == "_" {
name = fmt.Sprintf("_%d", idx)
}
label = l.GlobalID(fmt.Sprintf("{%v},%s;field", structlbl, name))
l.objectLabels[field] = label
}
return label, exists
}
// MethodID associates a label with the given method and returns it, together with a flag indicating whether
// the method already had a label associated with it; the method must belong to `recvtyplbl`, since that label
// is used to construct the label of the method
func (l *Labeler) MethodID(method types.Object, recvtyplbl Label) (Label, bool) {
label, exists := l.objectLabels[method]
if !exists {
label = l.GlobalID(fmt.Sprintf("{%v},%s;method", recvtyplbl, method.Name()))
l.objectLabels[method] = label
}
return label, exists
}

Просмотреть файл

@ -1,168 +0,0 @@
package trap
import (
"bufio"
"compress/gzip"
"errors"
"fmt"
"go/ast"
"go/types"
"io/ioutil"
"os"
"path/filepath"
"unicode/utf8"
"github.com/github/codeql-go/extractor/srcarchive"
"golang.org/x/tools/go/packages"
)
// A Writer provides methods for writing data to a TRAP file
type Writer struct {
zip *gzip.Writer
w *bufio.Writer
file *os.File
Labeler *Labeler
path string
trapFilePath string
Package *packages.Package
TypesOverride map[ast.Expr]types.Type
ObjectsOverride map[types.Object]types.Object
}
func FileFor(path string) (string, error) {
trapFolder, err := trapFolder()
if err != nil {
return "", err
}
return filepath.Join(trapFolder, srcarchive.AppendablePath(path)+".trap.gz"), nil
}
// NewWriter creates a TRAP file for the given path and returns a writer for
// writing to it
func NewWriter(path string, pkg *packages.Package) (*Writer, error) {
trapFilePath, err := FileFor(path)
if err != nil {
return nil, err
}
trapFileDir := filepath.Dir(trapFilePath)
err = os.MkdirAll(trapFileDir, 0755)
if err != nil {
return nil, err
}
tmpFile, err := ioutil.TempFile(trapFileDir, filepath.Base(trapFilePath))
if err != nil {
return nil, err
}
bufioWriter := bufio.NewWriter(tmpFile)
zipWriter := gzip.NewWriter(bufioWriter)
tw := &Writer{
zipWriter,
bufioWriter,
tmpFile,
nil,
path,
trapFilePath,
pkg,
make(map[ast.Expr]types.Type),
make(map[types.Object]types.Object),
}
tw.Labeler = newLabeler(tw)
return tw, nil
}
func trapFolder() (string, error) {
trapFolder := os.Getenv("CODEQL_EXTRACTOR_GO_TRAP_DIR")
if trapFolder == "" {
trapFolder = os.Getenv("TRAP_FOLDER")
}
if trapFolder == "" {
return "", errors.New("environment variable CODEQL_EXTRACTOR_GO_TRAP_DIR not set")
}
err := os.MkdirAll(trapFolder, 0755)
if err != nil {
return "", err
}
return trapFolder, nil
}
// Close the underlying file writer
func (tw *Writer) Close() error {
err := tw.zip.Close()
if err != nil {
// return zip-close error, but ignore file-close error
tw.file.Close()
return err
}
err = tw.w.Flush()
if err != nil {
// throw away close error because write errors are likely to be more important
tw.file.Close()
return err
}
err = tw.file.Close()
if err != nil {
return err
}
return os.Rename(tw.file.Name(), tw.trapFilePath)
}
// ForEachObject iterates over all objects labeled by this labeler, and invokes
// the provided callback with a writer for the trap file, the object, and its
// label. It returns true if any extra objects were labeled and false otherwise.
func (tw *Writer) ForEachObject(cb func(*Writer, types.Object, Label)) bool {
// copy the objects into an array so that our behaviour is deterministic even
// if `cb` adds any new objects
i := 0
objects := make([]types.Object, len(tw.Labeler.objectLabels))
for k := range tw.Labeler.objectLabels {
objects[i] = k
i++
}
for _, object := range objects {
cb(tw, object, tw.Labeler.objectLabels[object])
}
return len(tw.Labeler.objectLabels) != len(objects)
}
const max_strlen = 1024 * 1024
func capStringLength(s string) string {
// if the UTF8-encoded string is longer than 1MiB, we truncate it
if len(s) > max_strlen {
// to ensure that the truncated string is valid UTF-8, we find the last byte at or
// before index max_strlen that starts a UTF-8 encoded character, and then cut off
// right before that byte
end := max_strlen
for ; !utf8.RuneStart(s[end]); end-- {
}
return s[0:end]
}
return s
}
// Emit writes out a tuple of values for the given `table`
func (tw *Writer) Emit(table string, values []interface{}) error {
fmt.Fprintf(tw.zip, "%s(", table)
for i, value := range values {
if i > 0 {
fmt.Fprint(tw.zip, ", ")
}
switch value := value.(type) {
case Label:
fmt.Fprint(tw.zip, value.id)
case string:
fmt.Fprintf(tw.zip, "\"%s\"", escapeString(capStringLength(value)))
case int:
fmt.Fprintf(tw.zip, "%d", value)
case float64:
fmt.Fprintf(tw.zip, "%e", value)
default:
return errors.New("Cannot emit value")
}
}
fmt.Fprintf(tw.zip, ")\n")
return nil
}

Просмотреть файл

@ -1,68 +0,0 @@
package trap
import (
"strings"
"testing"
)
const (
asciiChar = "*"
bmpChar = "\u2028"
nonBmpChar = "\U000101d0"
)
func TestCapStringLength(t *testing.T) {
// test simple cases only involving ASCII characters
short := strings.Repeat(asciiChar, max_strlen-1)
if capStringLength(short) != short {
t.Errorf("Strings shorter than maximum length should not be truncated")
}
short = strings.Repeat(asciiChar, max_strlen)
if capStringLength(short) != short {
t.Errorf("Strings no longer than maximum length should not be truncated")
}
long := strings.Repeat(asciiChar, max_strlen+1)
if capStringLength(long) != long[0:max_strlen] {
t.Errorf("Strings longer than maximum length should be truncated")
}
// test chopping off non-ASCII characters
prefix := strings.Repeat(asciiChar, max_strlen)
long = prefix + bmpChar
if capStringLength(long) != prefix {
t.Errorf("BMP character after max_strlen should be correctly chopped off")
}
prefix = strings.Repeat(asciiChar, max_strlen)
long = prefix + nonBmpChar
if capStringLength(long) != prefix {
t.Errorf("Non-BMP character after max_strlen should be correctly chopped off")
}
prefix = strings.Repeat(asciiChar, max_strlen-(len(bmpChar)-1))
long = prefix + bmpChar
if capStringLength(long) != prefix {
t.Errorf("BMP character straddling max_strlen should be correctly chopped off")
}
prefix = strings.Repeat(asciiChar, max_strlen-(len(nonBmpChar)-1))
long = prefix + nonBmpChar
if capStringLength(long) != prefix {
t.Errorf("Non-BMP character straddling max_strlen should be correctly chopped off")
}
// test preserving non-ASCII characters that just about fit
prefix = strings.Repeat(asciiChar, max_strlen-len(bmpChar))
short = prefix + bmpChar
if capStringLength(short) != short {
t.Errorf("BMP character before max_strlen should be correctly preserved")
}
prefix = strings.Repeat(asciiChar, max_strlen-len(nonBmpChar))
short = prefix + nonBmpChar
if capStringLength(short) != short {
t.Errorf("Non-BMP character before max_strlen should be correctly preserved")
}
}

Просмотреть файл

@ -1,9 +0,0 @@
package trap
import (
"strings"
)
func escapeString(s string) string {
return strings.Replace(s, "\"", "\"\"", -1)
}

Просмотреть файл

@ -1,210 +0,0 @@
package util
import (
"errors"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
)
var extractorPath string
// Getenv retrieves the value of the environment variable named by the key.
// If that variable is not present, it iterates over the given aliases until
// it finds one that is. If none are present, the empty string is returned.
func Getenv(key string, aliases ...string) string {
val := os.Getenv(key)
if val != "" {
return val
}
for _, alias := range aliases {
val = os.Getenv(alias)
if val != "" {
return val
}
}
return ""
}
// runGoList is a helper function for running go list with format `format` and flags `flags` on
// package `pkgpath`.
func runGoList(format string, pkgpath string, flags ...string) (string, error) {
return runGoListWithEnv(format, pkgpath, nil, flags...)
}
func runGoListWithEnv(format string, pkgpath string, additionalEnv []string, flags ...string) (string, error) {
args := append([]string{"list", "-e", "-f", format}, flags...)
args = append(args, pkgpath)
cmd := exec.Command("go", args...)
cmd.Env = append(os.Environ(), additionalEnv...)
out, err := cmd.Output()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
log.Printf("Warning: go list command failed, output below:\nstdout:\n%s\nstderr:\n%s\n", out, err.Stderr)
} else {
log.Printf("Warning: Failed to run go list: %s", err.Error())
}
return "", err
}
return strings.TrimSpace(string(out)), nil
}
// GetModDir gets the absolute directory of the module containing the package with path
// `pkgpath`. It passes the `go list` the flags specified by `flags`.
func GetModDir(pkgpath string, flags ...string) string {
// enable module mode so that we can find a module root if it exists, even if go module support is
// disabled by a build
mod, err := runGoListWithEnv("{{.Module}}", pkgpath, []string{"GO111MODULE=on"}, flags...)
if err != nil || mod == "<nil>" {
// if the command errors or modules aren't being used, return the empty string
return ""
}
modDir, err := runGoListWithEnv("{{.Module.Dir}}", pkgpath, []string{"GO111MODULE=on"}, flags...)
if err != nil {
return ""
}
abs, err := filepath.Abs(modDir)
if err != nil {
log.Printf("Warning: unable to make %s absolute: %s", modDir, err.Error())
return ""
}
return abs
}
// GetPkgDir gets the absolute directory containing the package with path `pkgpath`. It passes the
// `go list` command the flags specified by `flags`.
func GetPkgDir(pkgpath string, flags ...string) string {
pkgDir, err := runGoList("{{.Dir}}", pkgpath, flags...)
if err != nil {
return ""
}
abs, err := filepath.Abs(pkgDir)
if err != nil {
log.Printf("Warning: unable to make %s absolute: %s", pkgDir, err.Error())
return ""
}
return abs
}
// DepErrors checks there are any errors resolving dependencies for `pkgpath`. It passes the `go
// list` command the flags specified by `flags`.
func DepErrors(pkgpath string, flags ...string) bool {
out, err := runGoList("{{if .DepsErrors}}{{else}}error{{end}}", pkgpath, flags...)
if err != nil {
// if go list failed, assume dependencies are broken
return false
}
return out != ""
}
// FileExists tests whether the file at `filename` exists and is not a directory.
func FileExists(filename string) bool {
info, err := os.Stat(filename)
if err != nil && !os.IsNotExist(err) {
log.Printf("Unable to stat %s: %s\n", filename, err.Error())
}
return err == nil && !info.IsDir()
}
// DirExists tests whether `filename` exists and is a directory.
func DirExists(filename string) bool {
info, err := os.Stat(filename)
if err != nil && !os.IsNotExist(err) {
log.Printf("Unable to stat %s: %s\n", filename, err.Error())
}
return err == nil && info.IsDir()
}
func RunCmd(cmd *exec.Cmd) bool {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
in, _ := cmd.StdinPipe()
err := cmd.Start()
if err != nil {
log.Printf("Running %s failed, continuing anyway: %s\n", cmd.Path, err.Error())
return false
}
in.Close()
err = cmd.Wait()
if err != nil {
log.Printf("Running %s failed, continuing anyway: %s\n", cmd.Path, err.Error())
return false
}
return true
}
func getOsToolsSubdir() (string, error) {
platform, set := os.LookupEnv("CODEQL_PLATFORM")
if set && platform != "" {
return platform, nil
}
switch runtime.GOOS {
case "darwin":
return "osx64", nil
case "linux":
return "linux64", nil
case "windows":
return "win64", nil
}
return "", errors.New("Unsupported OS: " + runtime.GOOS)
}
func getExtractorDir() (string, error) {
extractorRoot := os.Getenv("CODEQL_EXTRACTOR_GO_ROOT")
if extractorRoot == "" {
log.Print("CODEQL_EXTRACTOR_GO_ROOT not set.\nThis binary should not be run manually; instead, use the CodeQL CLI or VSCode extension. See https://securitylab.github.com/tools/codeql.\n")
log.Print("Falling back to guess the root based on this executable's path.\n")
mypath, err := os.Executable()
if err == nil {
return filepath.Dir(mypath), nil
} else {
return "", errors.New("CODEQL_EXTRACTOR_GO_ROOT not set, and could not determine path of this executable: " + err.Error())
}
}
osSubdir, err := getOsToolsSubdir()
if err != nil {
return "", err
}
return filepath.Join(extractorRoot, "tools", osSubdir), nil
}
func GetExtractorPath() (string, error) {
if extractorPath != "" {
return extractorPath, nil
}
dirname, err := getExtractorDir()
if err != nil {
return "", err
}
extractorPath := filepath.Join(dirname, "go-extractor")
if runtime.GOOS == "windows" {
extractorPath = extractorPath + ".exe"
}
return extractorPath, nil
}
func EscapeTrapSpecialChars(s string) string {
// Replace TRAP special characters with their HTML entities, as well as '&' to avoid ambiguity.
s = strings.ReplaceAll(s, "&", "&amp;")
s = strings.ReplaceAll(s, "{", "&lbrace;")
s = strings.ReplaceAll(s, "}", "&rbrace;")
s = strings.ReplaceAll(s, "\"", "&quot;")
s = strings.ReplaceAll(s, "@", "&commat;")
s = strings.ReplaceAll(s, "#", "&num;")
return s
}

13
go.mod
Просмотреть файл

@ -1,13 +0,0 @@
module github.com/github/codeql-go
go 1.18
require (
golang.org/x/mod v0.5.0
golang.org/x/tools v0.1.5
)
require (
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

28
go.sum
Просмотреть файл

@ -1,28 +0,0 @@
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

Просмотреть файл

@ -1,15 +0,0 @@
# Improvements to Go analysis
## New queries
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------|----------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| Clear-text logging of sensitive information (`go/clear-text-logging`) | security, external/cwe/cwe-312, external/cwe/cwe-315, external/cwe/cwe-359 | Highlights code that writes sensitive information to a log file, or to the console, without encryption or hashing. Results are shown on LGTM by default. |
| Open URL redirect (`go/unvalidated-url-redirection`) | security, external/cwe/cwe-601 | Highlights code that redirects to a URL that may be controlled by an attacker. Results are shown on LGTM by default. |
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|-----------------------------------------------------|------------------------------|-----------------------------------------------------------|
| Expression has no effect (`go/useless-expression`) | Fewer false positive results | This query no longer flags calls to empty stub functions. |
| Hard-coded credentials (`go/hardcoded-credentials`) | Fewer false positive results | This query now recognizes more placeholder credentials. |

Просмотреть файл

@ -1,39 +0,0 @@
# Improvements to Go analysis
## General improvements
* You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
* Analysis of flow through fields and elements of arrays and slices has been improved, which may lead to more results from the security queries.
* Detection of test code has been improved. LGTM will not show alerts in test code by default.
* Go 1.14 library changes have been modeled.
* More sources of untrusted input as well as vulnerable sinks are modeled, which may lead to more results from the security queries.
## New queries
The CodeQL library for Go now contains a folder of simple "cookbook" queries that show how to access basic Go elements using the predicates defined by the standard library. They're intended to give you a starting point for your own experiments and to help you work out the best way to frame your questions using CodeQL. You can find them in the `examples/snippets` folder in the [CodeQL for Go repository](https://github.com/github/codeql-go/tree/main/ql/examples/snippets).
| **Query** | **Tags** | **Purpose** |
|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bad check of redirect URL (`go/bad-redirect-check`) | correctness, security, external/cwe/cwe-601 | Highlights checks that ensure redirect URLs start with `/` but don't check for `//` or `/\`. Results are shown on LGTM by default. |
| Constant length comparison (`go/constant-length-comparison`) | correctness | Highlights code that checks the length of an array or slice against a constant before indexing it using a variable, suggesting a logic error. Results are shown on LGTM by default. |
| Disabled TLS certificate check (`go/disabled-certificate-check`) | security, external/cwe/295 | Highlights code that disables TLS certificate checking. Results are shown on LGTM by default. |
| Impossible interface nil check (`go/impossible-interface-nil-check`) | correctness | Highlights code that compares an interface value that cannot be `nil` to `nil`, suggesting a logic error. Results are shown on LGTM by default. |
| Incomplete URL scheme check (`go/incomplete-url-scheme-check`) | correctness, security, external/cwe/cwe-020 | Highlights checks for `javascript` URLs that do not take `data` or `vbscript` URLs into account. Results are shown on LGTM by default. |
| Potentially unsafe quoting (`go/unsafe-quoting`) | correctness, security, external/cwe/cwe-078, external/cwe/cwe-089, external/cwe/cwe-094 | Highlights code that constructs a quoted string literal containing data that may itself contain quotes. Results are shown on LGTM by default. |
| Size computation for allocation may overflow (`go/allocation-size-overflow`) | correctness, security, external/cwe/cwe-190 | Highlights code that computes the size of an allocation based on the size of a potentially large object. Results are shown on LGTM by default. |
| Uncontrolled data used in network request (`go/request-forgery`) | correctness, security, external/cwe/cwe-918 | Highlights code that uses uncontrolled user input to make a request. Results are shown on LGTM by default. |
| XPath injection (`go/xml/xpath-injection`) | security, external/cwe/cwe-643 | Highlights code that uses remote input in an XPath expression. Results are shown on LGTM by default. |
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|-------------------------------------------------------------------------------|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Arbitrary file write during zip extraction ("zip slip") (`go/zipslip`) | Fewer false positive results | The query now excludes more cases where it is safe to use a path extractor from an archive. |
| Bitwise exclusive-or used like exponentiation (`go/mistyped-exponentiation`) | Fewer false positive results | The query now identifies when the value of an xor is assigned to a mask object, and excludes such results. |
| Command built from user-controlled sources (`go/command-injection`) | More results | The library models used by the query have been improved, allowing it to flag more potentially problematic cases, including sources that flow into shells, sudo, or programming-language interpreters as arguments. |
| Database query built from user-controlled sources (`go/sql-injection`) | More results | The library models used by the query have been improved, allowing it to flag more potentially problematic cases. |
| Identical operands (`go/redundant-operation`) | Fewer false positive results | The query no longer flags cases where the operands have the same value but are syntactically distinct, since this is usually intentional. |
| Incomplete regular expression for hostnames (`go/incomplete-hostname-regexp`) | More results | The query now flags unescaped dots before the TLD in a hostname regex. |
| Open URL redirect (`go/unvalidated-url-redirection`) | Fewer false positive results | The query now identifies some sources that are not attacker-controlled, and excludes results with such sources. |
| Reflected cross-site scripting (`go/reflected-xss`) | Fewer results | Untrusted input flowing into an HTTP header definition or into an `fmt.Fprintf` call with a constant prefix is no longer flagged, since it is in both cases often harmless. |
| Useless assignment to field (`go/useless-assignment-to-field`) | Fewer false positive results | The query now conservatively handles fields promoted through embedded pointer types. |

Просмотреть файл

@ -1,19 +0,0 @@
[[ condition: enterprise-only ]]
# Improvements to Go analysis
## Improvements to the autobuilder
* When Makefiles or custom build scripts are present in the codebase, the autobuilder uses them to install dependencies. The build command
to invoke can be configured via `lgtm.yml`, or by setting the environment variable `CODEQL_EXTRACTOR_GO_BUILD_COMMAND`.
* The autobuilder now attempts to automatically detect when dependencies have been vendored and use `-mod=vendor` appropriately.
## Changes to code extraction
* The extractor now supports Go 1.14.
* In resource-constrained environments, the environment variable `CODEQL_EXTRACTOR_GO_MAX_GOROUTINES` can be used to limit the
number of parallel goroutines started by the extractor, which reduces CPU and memory requirements. The default value for this
variable is 32.
* The extractor now uses buffered i/o for writing database files, which reduces the amount of time taken for extraction.
* The extractor now compresses intermediate files used for constructing databases, which reduces the amount of disk space it requires.
* The extractor now supports extracting `go.mod` files, enabling queries on dependencies and their versions.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Command built from user-controlled sources" has been improved to recognize methods from the `syscall` library, which may lead to more alerts.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Bad redirect check" (`go/bad-redirect-check`) now requires that the checked variable is actually used in a redirect as opposed to relying on a name-based heuristic. This eliminates some false positive results, and adds more true positive results.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* Basic support for the [Macaron](https://go-macaron.com/) HTTP library has been added, which may lead to more results from the security queries.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Clear-text logging of sensitive information" has been improved to recognize more logging APIs, which may lead to more alerts.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* Basic support for the [Mux](https://github.com/gorilla/mux/) HTTP library has been added, which
may lead to more results from the security queries.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* The data-flow library has been improved, which affects and improves most security queries. In particular,
flow through functions involving nested field reads and writes is now modeled more fully.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* The query "Reflected cross-site scripting" has been improved to recognize more cases where the
value should be considered to be safe, which should lead to fewer false positive results.

Просмотреть файл

@ -1,4 +0,0 @@
lgtm,codescanning
* The queries "Uncontrolled data used in path expression" and "Arbitrary file write during zip
extraction ("zip slip")" have been improved to recognize more file APIs, which may lead to more
alerts.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* Modeling of the standard `io` library has been improved, which may lead to more results from the
security queries.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* A new query "Redundant call to recover" (`go/redundant-recover`) has been added. The query detects calls to `recover` that have no effect.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* Modeling of the `go.mongodb.org/mongo-driver/mongo` package has been added, which may lead to more
results from the security queries.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Uncontrolled data used in network request" is now more precise, which may reduce the number of false positives.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* Modeling of several WebSocket libraries has been added, which may lead to more results from the
security queries.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Open URL redirect" (`go/unvalidated-url-redirection`) now recognizes values returned by method `http.Request.FormValue` as possibly user controlled, allowing it to flag more true positive results.

Просмотреть файл

@ -1,5 +0,0 @@
lgtm,codescanning
* The Go extractor now supports build tracing, allowing users to supply a build command when
creating databases with the CodeQL CLI or via configuration. It currently only supports projects
that use Go modules. To opt-in, set the environment variable `CODEQL_EXTRACTOR_GO_BUILD_TRACING`
to `on`, or supply a build command.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The extractor now attempts to extract the AST of all dependencies that are related to the packages passed explicitly on the commandline, which is determined by using the module root or, if not using modules, the directory containing the source for those packages. In particular, this means if a package passed to the extractor depends on another package inside the same module, the dependency's AST will now be extracted.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* The query "Email injection" (`go/email-injection`) has been moved out of the experimental folder. The query detects when untrusted input can be incorporated directly into an email.

Просмотреть файл

@ -1,3 +0,0 @@
lgtm,codescanning
* The query "Reflected cross-site scripting" has been improved to more correctly determine whether
an HTML mime type will be sniffed, which should lead to more accurate results.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* Resolution of method calls through interfaces has been improved, resulting in more precise call-graph information, which in turn may eliminate false positives from the security queries.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* A bug has been fixed that could cause the analysis not to terminate in the presence of cycles through embedded struct fields.

Просмотреть файл

@ -1,2 +0,0 @@
lgtm,codescanning
* A bug has been fixed that could cause the incorrect analysis of control flow around switch statements.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше