mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
Merge branch 'main' into formatTaint
This commit is contained in:
8
.github/labeler.yml
vendored
8
.github/labeler.yml
vendored
@@ -43,3 +43,11 @@ documentation:
|
|||||||
"QL-for-QL":
|
"QL-for-QL":
|
||||||
- ql/**/*
|
- ql/**/*
|
||||||
- .github/workflows/ql-for-ql*
|
- .github/workflows/ql-for-ql*
|
||||||
|
|
||||||
|
# Since these are all shared files that need to be synced, just pick _one_ copy of each.
|
||||||
|
"DataFlow Library":
|
||||||
|
- "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll"
|
||||||
|
- "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll"
|
||||||
|
- "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
|
||||||
|
- "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll"
|
||||||
|
- "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll"
|
||||||
|
|||||||
56
.github/workflows/atm-check-queries-run.yml
vendored
Normal file
56
.github/workflows/atm-check-queries-run.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
name: ATM Check Queries Run
|
||||||
|
|
||||||
|
env:
|
||||||
|
DB_PATH: test_db
|
||||||
|
ATM_MODEL_PACK: javascript/ql/experimental/adaptivethreatmodeling/src
|
||||||
|
QUERY_SUITE: codeql-suites/javascript-atm-code-scanning.qls
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/atm-check-queries-run.yml"
|
||||||
|
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-atm-queries:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install CodeQL CLI
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh extensions install github/gh-codeql
|
||||||
|
gh codeql download
|
||||||
|
|
||||||
|
- name: Install ATM model pack
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -exu
|
||||||
|
|
||||||
|
# Install ATM model pack
|
||||||
|
gh codeql pack install ${ATM_MODEL_PACK}
|
||||||
|
|
||||||
|
# Retrieve model checksum
|
||||||
|
model_checksum=$(gh codeql resolve extensions ${ATM_MODEL_PACK}/${QUERY_SUITE} | jq -r '.models[0].checksum')
|
||||||
|
|
||||||
|
# Trust the model so that we can use it in the ATM boosted queries
|
||||||
|
mkdir -p "$HOME/.config/codeql"
|
||||||
|
echo "--insecurely-execute-ml-model-checksums ${model_checksum}" >> "$HOME/.config/codeql/config"
|
||||||
|
|
||||||
|
- name: Create test DB
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh codeql database create ${RUNNER_TEMP}/${DB_PATH} --source-root config/atm/ --language javascript
|
||||||
|
|
||||||
|
- name: Run ATM query suite
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh codeql database run-queries -vv -- ${RUNNER_TEMP}/${DB_PATH} ${ATM_MODEL_PACK}/${QUERY_SUITE}
|
||||||
|
|
||||||
4
.github/workflows/ruby-build.yml
vendored
4
.github/workflows/ruby-build.yml
vendored
@@ -96,8 +96,8 @@ jobs:
|
|||||||
- name: Build Query Pack
|
- name: Build Query Pack
|
||||||
run: |
|
run: |
|
||||||
codeql pack create ../shared/ssa --output target/packs
|
codeql pack create ../shared/ssa --output target/packs
|
||||||
|
codeql pack create ../misc/suite-helpers --output target/packs
|
||||||
codeql pack create ql/lib --output target/packs
|
codeql pack create ql/lib --output target/packs
|
||||||
codeql pack install ql/src
|
|
||||||
codeql pack create ql/src --output target/packs
|
codeql pack create ql/src --output target/packs
|
||||||
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
|
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
|
||||||
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
|
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
|
||||||
@@ -202,7 +202,7 @@ jobs:
|
|||||||
echo 'name: sample-tests
|
echo 'name: sample-tests
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
codeql/ruby-all: 0.0.1
|
codeql/ruby-all: "*"
|
||||||
extractor: ruby
|
extractor: ruby
|
||||||
tests: .
|
tests: .
|
||||||
' > qlpack.yml
|
' > qlpack.yml
|
||||||
|
|||||||
13
.github/workflows/swift-qltest.yml
vendored
13
.github/workflows/swift-qltest.yml
vendored
@@ -23,12 +23,23 @@ jobs:
|
|||||||
- uses: ./.github/actions/fetch-codeql
|
- uses: ./.github/actions/fetch-codeql
|
||||||
- name: Check QL formatting
|
- name: Check QL formatting
|
||||||
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
||||||
|
qltest-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: bazelbuild/setup-bazelisk@v2
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version-file: 'swift/.python-version'
|
||||||
|
- name: Test qltest.sh
|
||||||
|
run: |
|
||||||
|
bazel test //swift/tools/test/qltest
|
||||||
qltest:
|
qltest:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os : [ubuntu-20.04, macos-latest]
|
os: [ ubuntu-20.04, macos-latest ]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/fetch-codeql
|
- uses: ./.github/actions/fetch-codeql
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
| Unneeded defensive code | More true positive and fewer false positive results | This query now recognizes additional defensive code patterns. |
|
| Unneeded defensive code | More true positive and fewer false positive results | This query now recognizes additional defensive code patterns. |
|
||||||
| Unsafe dynamic method access | Fewer false positive results | This query no longer flags concatenated strings as unsafe method names. |
|
| Unsafe dynamic method access | Fewer false positive results | This query no longer flags concatenated strings as unsafe method names. |
|
||||||
| Unused parameter | Fewer false positive results | This query no longer flags parameters with leading underscore. |
|
| Unused parameter | Fewer false positive results | This query no longer flags parameters with leading underscore. |
|
||||||
| Unused variable, import, function or class | Fewer false positive results | This query now flags fewer variables that are implictly used by JSX elements. It no longer flags variables with a leading underscore and variables in dead code. |
|
| Unused variable, import, function or class | Fewer false positive results | This query now flags fewer variables that are implicitly used by JSX elements. It no longer flags variables with a leading underscore and variables in dead code. |
|
||||||
| Unvalidated dynamic method call | More true positive results | This query now flags concatenated strings as unvalidated method names in more cases. |
|
| Unvalidated dynamic method call | More true positive results | This query now flags concatenated strings as unvalidated method names in more cases. |
|
||||||
| Useless assignment to property. | Fewer false positive results | This query now treats assignments with complex right-hand sides correctly. |
|
| Useless assignment to property. | Fewer false positive results | This query now treats assignments with complex right-hand sides correctly. |
|
||||||
| Useless conditional | Fewer results | Additional defensive coding patterns are now ignored. |
|
| Useless conditional | Fewer results | Additional defensive coding patterns are now ignored. |
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
|
|||||||
| Hard-coded Japanese era start date in call (`cpp/japanese-era/constructor-or-method-with-exact-era-date`) | Deprecated | This query has been deprecated. Use the new combined query Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) instead. |
|
| Hard-coded Japanese era start date in call (`cpp/japanese-era/constructor-or-method-with-exact-era-date`) | Deprecated | This query has been deprecated. Use the new combined query Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) instead. |
|
||||||
| Hard-coded Japanese era start date in struct (`cpp/japanese-era/struct-with-exact-era-date`) | Deprecated | This query has been deprecated. Use the new combined query Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) instead. |
|
| Hard-coded Japanese era start date in struct (`cpp/japanese-era/struct-with-exact-era-date`) | Deprecated | This query has been deprecated. Use the new combined query Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) instead. |
|
||||||
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | More correct results | This query now checks for the beginning date of the Reiwa era (1st May 2019). |
|
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | More correct results | This query now checks for the beginning date of the Reiwa era (1st May 2019). |
|
||||||
| Non-constant format string (`cpp/non-constant-format`) | Fewer false positive results | Fixed false positive results triggrered by mismatching declarations of a formatting function. |
|
| Non-constant format string (`cpp/non-constant-format`) | Fewer false positive results | Fixed false positive results triggered by mismatching declarations of a formatting function. |
|
||||||
| Sign check of bitwise operation (`cpp/bitwise-sign-check`) | Fewer false positive results | Results involving `>=` or `<=` are no longer reported. |
|
| Sign check of bitwise operation (`cpp/bitwise-sign-check`) | Fewer false positive results | Results involving `>=` or `<=` are no longer reported. |
|
||||||
| Too few arguments to formatting function (`cpp/wrong-number-format-arguments`) | Fewer false positive results | Fixed false positive results triggered by mismatching declarations of a formatting function. |
|
| Too few arguments to formatting function (`cpp/wrong-number-format-arguments`) | Fewer false positive results | Fixed false positive results triggered by mismatching declarations of a formatting function. |
|
||||||
| Too many arguments to formatting function (`cpp/too-many-format-arguments`) | Fewer false positive results | Fixed false positive results triggered by mismatching declarations of a formatting function. |
|
| Too many arguments to formatting function (`cpp/too-many-format-arguments`) | Fewer false positive results | Fixed false positive results triggered by mismatching declarations of a formatting function. |
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
|
|
||||||
## Changes to libraries
|
## Changes to libraries
|
||||||
|
|
||||||
* The predicates `RegExpTerm.getSuccessor` and `RegExpTerm.getPredecessor` have been changed to reflect textual, not operational, matching order. This only makes a difference in lookbehind assertions, which are operationally matched backwards. Previously, `getSuccessor` would mimick this, so in an assertion `(?<=ab)` the term `b` would be considered the predecessor, not the successor, of `a`. Textually, however, `a` is still matched before `b`, and this is the order we now follow.
|
* The predicates `RegExpTerm.getSuccessor` and `RegExpTerm.getPredecessor` have been changed to reflect textual, not operational, matching order. This only makes a difference in lookbehind assertions, which are operationally matched backwards. Previously, `getSuccessor` would mimic this, so in an assertion `(?<=ab)` the term `b` would be considered the predecessor, not the successor, of `a`. Textually, however, `a` is still matched before `b`, and this is the order we now follow.
|
||||||
* An extensible model of the `EventEmitter` pattern has been implemented.
|
* An extensible model of the `EventEmitter` pattern has been implemented.
|
||||||
* Taint-tracking configurations now interact differently with the `data` flow label, which may affect queries
|
* Taint-tracking configurations now interact differently with the `data` flow label, which may affect queries
|
||||||
that combine taint-tracking and flow labels.
|
that combine taint-tracking and flow labels.
|
||||||
|
|||||||
21
config/atm/ml-powered-queries-repo/add-note.js
Normal file
21
config/atm/ml-powered-queries-repo/add-note.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
Logger = require('./logger').Logger;
|
||||||
|
Note = require('./models/note').Note;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
if (process.argv.length != 5) {
|
||||||
|
Logger.log("Creates a private note. Usage: node add-note.js <token> <title> <body>")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the default mongoose connection
|
||||||
|
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
|
||||||
|
|
||||||
|
const [userToken, title, body] = process.argv.slice(2);
|
||||||
|
await Note.create({ title, body, userToken });
|
||||||
|
|
||||||
|
Logger.log(`Created private note with title ${title} and body ${body} belonging to user with token ${userToken}.`);
|
||||||
|
|
||||||
|
await mongoose.connection.close();
|
||||||
|
})();
|
||||||
68
config/atm/ml-powered-queries-repo/app.js
Normal file
68
config/atm/ml-powered-queries-repo/app.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const express = require('express');
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const notesApi = require('./notes-api');
|
||||||
|
const usersApi = require('./users-api');
|
||||||
|
|
||||||
|
const addSampleData = module.exports.addSampleData = async () => {
|
||||||
|
const [userA, userB] = await User.create([
|
||||||
|
{
|
||||||
|
name: "A",
|
||||||
|
token: "tokenA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "B",
|
||||||
|
token: "tokenB"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await Note.create([
|
||||||
|
{
|
||||||
|
title: "Public note belonging to A",
|
||||||
|
body: "This is a public note belonging to A",
|
||||||
|
isPublic: true,
|
||||||
|
ownerToken: userA.token
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Public note belonging to B",
|
||||||
|
body: "This is a public note belonging to B",
|
||||||
|
isPublic: true,
|
||||||
|
ownerToken: userB.token
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Private note belonging to A",
|
||||||
|
body: "This is a private note belonging to A",
|
||||||
|
ownerToken: userA.token
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Private note belonging to B",
|
||||||
|
body: "This is a private note belonging to B",
|
||||||
|
ownerToken: userB.token
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.startApp = async () => {
|
||||||
|
// Open the default mongoose connection
|
||||||
|
await mongoose.connect('mongodb://mongo:27017/notes', { useFindAndModify: false });
|
||||||
|
// Drop contents of DB
|
||||||
|
mongoose.connection.dropDatabase();
|
||||||
|
// Add some sample data
|
||||||
|
await addSampleData();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.use(bodyParser.urlencoded());
|
||||||
|
|
||||||
|
app.get('/', async (_req, res) => {
|
||||||
|
res.send('Hello World');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use('/api/notes', notesApi.router);
|
||||||
|
app.use('/api/users', usersApi.router);
|
||||||
|
|
||||||
|
app.listen(3000);
|
||||||
|
Logger.log('Express started on port 3000');
|
||||||
|
};
|
||||||
7
config/atm/ml-powered-queries-repo/index.js
Normal file
7
config/atm/ml-powered-queries-repo/index.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const startApp = require('./app').startApp;
|
||||||
|
|
||||||
|
Logger = require('./logger').Logger;
|
||||||
|
Note = require('./models/note').Note;
|
||||||
|
User = require('./models/user').User;
|
||||||
|
|
||||||
|
startApp();
|
||||||
5
config/atm/ml-powered-queries-repo/logger.js
Normal file
5
config/atm/ml-powered-queries-repo/logger.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports.Logger = class {
|
||||||
|
log(message, ...objs) {
|
||||||
|
console.log(message, objs);
|
||||||
|
}
|
||||||
|
};
|
||||||
8
config/atm/ml-powered-queries-repo/models/note.js
Normal file
8
config/atm/ml-powered-queries-repo/models/note.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
module.exports.Note = mongoose.model('Note', new mongoose.Schema({
|
||||||
|
title: String,
|
||||||
|
body: String,
|
||||||
|
ownerToken: String,
|
||||||
|
isPublic: Boolean
|
||||||
|
}));
|
||||||
6
config/atm/ml-powered-queries-repo/models/user.js
Normal file
6
config/atm/ml-powered-queries-repo/models/user.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
module.exports.User = mongoose.model('User', new mongoose.Schema({
|
||||||
|
name: String,
|
||||||
|
token: String
|
||||||
|
}));
|
||||||
44
config/atm/ml-powered-queries-repo/notes-api.js
Normal file
44
config/atm/ml-powered-queries-repo/notes-api.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
const express = require('express')
|
||||||
|
|
||||||
|
const router = module.exports.router = express.Router();
|
||||||
|
|
||||||
|
function serializeNote(note) {
|
||||||
|
return {
|
||||||
|
title: note.title,
|
||||||
|
body: note.body
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post('/find', async (req, res) => {
|
||||||
|
const notes = await Note.find({
|
||||||
|
ownerToken: req.body.token
|
||||||
|
}).exec();
|
||||||
|
res.json({
|
||||||
|
notes: notes.map(serializeNote)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/findPublic', async (_req, res) => {
|
||||||
|
const notes = await Note.find({
|
||||||
|
isPublic: true
|
||||||
|
}).exec();
|
||||||
|
res.json({
|
||||||
|
notes: notes.map(serializeNote)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/findVisible', async (req, res) => {
|
||||||
|
const notes = await Note.find({
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
isPublic: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ownerToken: req.body.token
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).exec();
|
||||||
|
res.json({
|
||||||
|
notes: notes.map(serializeNote)
|
||||||
|
});
|
||||||
|
});
|
||||||
37
config/atm/ml-powered-queries-repo/read-notes.js
Normal file
37
config/atm/ml-powered-queries-repo/read-notes.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
Logger = require('./logger').Logger;
|
||||||
|
Note = require('./models/note').Note;
|
||||||
|
User = require('./models/user').User;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
if (process.argv.length != 3) {
|
||||||
|
Logger.log("Outputs all notes visible to a user. Usage: node read-notes.js <token>")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the default mongoose connection
|
||||||
|
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
|
||||||
|
|
||||||
|
const ownerToken = process.argv[2];
|
||||||
|
|
||||||
|
const user = await User.findOne({
|
||||||
|
token: ownerToken
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
const notes = await Note.find({
|
||||||
|
$or: [
|
||||||
|
{ isPublic: true },
|
||||||
|
{ ownerToken }
|
||||||
|
]
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
notes.map(note => {
|
||||||
|
Logger.log("Title:" + note.title);
|
||||||
|
Logger.log("By:" + user.name);
|
||||||
|
Logger.log("Body:" + note.body);
|
||||||
|
Logger.log();
|
||||||
|
});
|
||||||
|
|
||||||
|
await mongoose.connection.close();
|
||||||
|
})();
|
||||||
25
config/atm/ml-powered-queries-repo/users-api.js
Normal file
25
config/atm/ml-powered-queries-repo/users-api.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const express = require('express')
|
||||||
|
|
||||||
|
Logger = require('./logger').Logger;
|
||||||
|
const router = module.exports.router = express.Router();
|
||||||
|
|
||||||
|
router.post('/updateName', async (req, res) => {
|
||||||
|
Logger.log("/updateName called with new name", req.body.name);
|
||||||
|
await User.findOneAndUpdate({
|
||||||
|
token: req.body.token
|
||||||
|
}, {
|
||||||
|
name: req.body.name
|
||||||
|
}).exec();
|
||||||
|
res.json({
|
||||||
|
name: req.body.name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/getName', async (req, res) => {
|
||||||
|
const user = await User.findOne({
|
||||||
|
token: req.body.token
|
||||||
|
}).exec();
|
||||||
|
res.json({
|
||||||
|
name: user.name
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
No user-facing changes.
|
No user-facing changes.
|
||||||
|
|||||||
4
cpp/ql/lib/change-notes/2022-10-22-format-literal.md
Normal file
4
cpp/ql/lib/change-notes/2022-10-22-format-literal.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Fixed bugs in the `FormatLiteral` class that were causing `getMaxConvertedLength` and related predicates to return no results when the format literal was `%e`, `%f` or `%g` and an explicit precision was specified.
|
||||||
3
cpp/ql/lib/change-notes/released/0.4.2.md
Normal file
3
cpp/ql/lib/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.4.1
|
lastReleaseVersion: 0.4.2
|
||||||
|
|||||||
@@ -4,6 +4,12 @@
|
|||||||
* variable), and `v` is an integer in the range `[0 .. m-1]`.
|
* variable), and `v` is an integer in the range `[0 .. m-1]`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The main recursion has base cases in both `ssaModulus` (for guarded reads) and `semExprModulus`
|
||||||
|
* (for constant values). The most interesting recursive case is `phiModulusRankStep`, which
|
||||||
|
* handles phi inputs.
|
||||||
|
*/
|
||||||
|
|
||||||
private import ModulusAnalysisSpecific::Private
|
private import ModulusAnalysisSpecific::Private
|
||||||
private import experimental.semmle.code.cpp.semantic.Semantic
|
private import experimental.semmle.code.cpp.semantic.Semantic
|
||||||
private import ConstantAnalysis
|
private import ConstantAnalysis
|
||||||
@@ -162,6 +168,11 @@ private predicate phiModulusInit(SemSsaPhiNode phi, SemBound b, int val, int mod
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
|
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
|
||||||
|
/*
|
||||||
|
* base case. If any phi input is equal to `b + val` modulo `mod`, that's a potential congruence
|
||||||
|
* class for the phi node.
|
||||||
|
*/
|
||||||
|
|
||||||
rix = 0 and
|
rix = 0 and
|
||||||
phiModulusInit(phi, b, val, mod)
|
phiModulusInit(phi, b, val, mod)
|
||||||
or
|
or
|
||||||
@@ -169,6 +180,12 @@ private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int
|
|||||||
mod != 1 and
|
mod != 1 and
|
||||||
val = remainder(v1, mod)
|
val = remainder(v1, mod)
|
||||||
|
|
|
|
||||||
|
/*
|
||||||
|
* Recursive case. If `inp` = `b + v2` mod `m2`, we combine that with the preceding potential
|
||||||
|
* congruence class `b + v1` mod `m1`. The result will be the congruence class of `v1` modulo
|
||||||
|
* the greatest common denominator of `m1`, `m2`, and `v1 - v2`.
|
||||||
|
*/
|
||||||
|
|
||||||
exists(int v2, int m2 |
|
exists(int v2, int m2 |
|
||||||
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
|
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
|
||||||
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
||||||
@@ -176,6 +193,12 @@ private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int
|
|||||||
mod = m1.gcd(m2).gcd(v1 - v2)
|
mod = m1.gcd(m2).gcd(v1 - v2)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
/*
|
||||||
|
* Recursive case. If `inp` = `phi` mod `m2`, we combine that with the preceding potential
|
||||||
|
* congruence class `b + v1` mod `m1`. The result will be a congruence class modulo the greatest
|
||||||
|
* common denominator of `m1` and `m2`.
|
||||||
|
*/
|
||||||
|
|
||||||
exists(int m2 |
|
exists(int m2 |
|
||||||
rankedPhiInput(phi, inp, edge, rix) and
|
rankedPhiInput(phi, inp, edge, rix) and
|
||||||
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.4.2-dev
|
version: 0.4.3-dev
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -1124,13 +1124,13 @@ class FormatLiteral extends Literal {
|
|||||||
this.getConversionChar(n).toLowerCase() = "f" and
|
this.getConversionChar(n).toLowerCase() = "f" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
||||||
(
|
|
||||||
(
|
(
|
||||||
if this.hasExplicitPrecision(n)
|
if this.hasExplicitPrecision(n)
|
||||||
then afterdot = this.getPrecision(n)
|
then afterdot = this.getPrecision(n)
|
||||||
else not this.hasImplicitPrecision(n)
|
else (
|
||||||
) and
|
not this.hasImplicitPrecision(n) and
|
||||||
afterdot = 6
|
afterdot = 6
|
||||||
|
)
|
||||||
) and
|
) and
|
||||||
len = 1 + 309 + dot + afterdot
|
len = 1 + 309 + dot + afterdot
|
||||||
) and
|
) and
|
||||||
@@ -1139,13 +1139,13 @@ class FormatLiteral extends Literal {
|
|||||||
this.getConversionChar(n).toLowerCase() = "e" and
|
this.getConversionChar(n).toLowerCase() = "e" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
||||||
(
|
|
||||||
(
|
(
|
||||||
if this.hasExplicitPrecision(n)
|
if this.hasExplicitPrecision(n)
|
||||||
then afterdot = this.getPrecision(n)
|
then afterdot = this.getPrecision(n)
|
||||||
else not this.hasImplicitPrecision(n)
|
else (
|
||||||
) and
|
not this.hasImplicitPrecision(n) and
|
||||||
afterdot = 6
|
afterdot = 6
|
||||||
|
)
|
||||||
) and
|
) and
|
||||||
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
|
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
|
||||||
) and
|
) and
|
||||||
@@ -1154,13 +1154,13 @@ class FormatLiteral extends Literal {
|
|||||||
this.getConversionChar(n).toLowerCase() = "g" and
|
this.getConversionChar(n).toLowerCase() = "g" and
|
||||||
exists(int dot, int afterdot |
|
exists(int dot, int afterdot |
|
||||||
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
|
||||||
(
|
|
||||||
(
|
(
|
||||||
if this.hasExplicitPrecision(n)
|
if this.hasExplicitPrecision(n)
|
||||||
then afterdot = this.getPrecision(n)
|
then afterdot = this.getPrecision(n)
|
||||||
else not this.hasImplicitPrecision(n)
|
else (
|
||||||
) and
|
not this.hasImplicitPrecision(n) and
|
||||||
afterdot = 6
|
afterdot = 6
|
||||||
|
)
|
||||||
) and
|
) and
|
||||||
// note: this could be displayed in the style %e or %f;
|
// note: this could be displayed in the style %e or %f;
|
||||||
// however %f is only used when 'P > X >= -4'
|
// however %f is only used when 'P > X >= -4'
|
||||||
|
|||||||
@@ -16,15 +16,36 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.commons.Exclusions
|
import semmle.code.cpp.commons.Exclusions
|
||||||
|
|
||||||
/** Gets the sub-expression of 'e' with the earliest-starting Location */
|
/**
|
||||||
|
* Gets a child of `e`, including conversions but excluding call arguments.
|
||||||
|
*/
|
||||||
|
pragma[inline]
|
||||||
|
Expr getAChildWithConversions(Expr e) {
|
||||||
|
result.getParentWithConversions() = e and
|
||||||
|
not result = any(Call c).getAnArgument()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the left-most column position of any transitive child of `e` (including
|
||||||
|
* conversions but excluding call arguments).
|
||||||
|
*/
|
||||||
|
int getCandidateColumn(Expr e) {
|
||||||
|
result = e.getLocation().getStartColumn() or
|
||||||
|
result = getCandidateColumn(getAChildWithConversions(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the transitive child of `e` (including conversions but excluding call
|
||||||
|
* arguments) at the left-most column position, preferring less deeply nested
|
||||||
|
* expressions if there is a choice.
|
||||||
|
*/
|
||||||
Expr normalizeExpr(Expr e) {
|
Expr normalizeExpr(Expr e) {
|
||||||
result =
|
e.getLocation().getStartColumn() = min(getCandidateColumn(e)) and
|
||||||
min(Expr child |
|
result = e
|
||||||
child.getParentWithConversions*() = e.getFullyConverted() and
|
or
|
||||||
not child.getParentWithConversions*() = any(Call c).getAnArgument()
|
not e.getLocation().getStartColumn() = min(getCandidateColumn(e)) and
|
||||||
|
|
result = normalizeExpr(getAChildWithConversions(e)) and
|
||||||
child order by child.getLocation().getStartColumn(), count(child.getParentWithConversions*())
|
result.getLocation().getStartColumn() = min(getCandidateColumn(e))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isParenthesized(CommaExpr ce) {
|
predicate isParenthesized(CommaExpr ce) {
|
||||||
@@ -43,8 +64,8 @@ from CommaExpr ce, Expr left, Expr right, Location leftLoc, Location rightLoc
|
|||||||
where
|
where
|
||||||
ce.fromSource() and
|
ce.fromSource() and
|
||||||
not isFromMacroDefinition(ce) and
|
not isFromMacroDefinition(ce) and
|
||||||
left = normalizeExpr(ce.getLeftOperand()) and
|
left = normalizeExpr(ce.getLeftOperand().getFullyConverted()) and
|
||||||
right = normalizeExpr(ce.getRightOperand()) and
|
right = normalizeExpr(ce.getRightOperand().getFullyConverted()) and
|
||||||
leftLoc = left.getLocation() and
|
leftLoc = left.getLocation() and
|
||||||
rightLoc = right.getLocation() and
|
rightLoc = right.getLocation() and
|
||||||
not isParenthesized(ce) and
|
not isParenthesized(ce) and
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
### New Queries
|
||||||
|
|
||||||
|
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
||||||
|
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
||||||
|
|
||||||
## 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: minorAnalysis
|
|
||||||
---
|
|
||||||
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: newQuery
|
|
||||||
---
|
|
||||||
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: minorAnalysis
|
|
||||||
---
|
|
||||||
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
|
||||||
10
cpp/ql/src/change-notes/released/0.4.2.md
Normal file
10
cpp/ql/src/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
### New Queries
|
||||||
|
|
||||||
|
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
||||||
|
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.4.1
|
lastReleaseVersion: 0.4.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 0.4.2-dev
|
version: 0.4.3-dev
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
||||||
exists(ActualResult actualResult |
|
exists(ActualResult actualResult |
|
||||||
actualResult.getTest() = this and
|
actualResult.getTest() = this and
|
||||||
|
actualResult.getTag() = this.getARelevantTag() and
|
||||||
element = actualResult and
|
element = actualResult and
|
||||||
(
|
(
|
||||||
exists(FalseNegativeExpectation falseNegative |
|
exists(FalseNegativeExpectation falseNegative |
|
||||||
@@ -150,9 +151,18 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
exists(ActualResult actualResult |
|
||||||
|
actualResult.getTest() = this and
|
||||||
|
not actualResult.getTag() = this.getARelevantTag() and
|
||||||
|
element = actualResult and
|
||||||
|
message =
|
||||||
|
"Tag mismatch: Actual result with tag '" + actualResult.getTag() +
|
||||||
|
"' that is not part of getARelevantTag()"
|
||||||
|
)
|
||||||
|
or
|
||||||
exists(ValidExpectation expectation |
|
exists(ValidExpectation expectation |
|
||||||
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
||||||
expectation.getTag() = getARelevantTag() and
|
expectation.getTag() = this.getARelevantTag() and
|
||||||
element = expectation and
|
element = expectation and
|
||||||
(
|
(
|
||||||
expectation instanceof GoodExpectation and
|
expectation instanceof GoodExpectation and
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
typedef void *va_list;
|
||||||
|
|
||||||
|
int myPrintf(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
int mySprintf(char *buffer, const char *format, ...) __attribute__((format(__printf__, 2, 3)));
|
||||||
|
int myVprintf(const char *format, va_list arg) __attribute__((format(printf, 1, 0)));
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
| AttributeFormattingFunction.cpp:4:5:4:12 | myPrintf | 0 | char | wchar_t | wchar_t |
|
||||||
|
| AttributeFormattingFunction.cpp:5:5:5:13 | mySprintf | 1 | char | wchar_t | wchar_t |
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import cpp
|
||||||
|
|
||||||
|
from AttributeFormattingFunction f
|
||||||
|
select f, f.getFormatParameterIndex(), concat(f.getDefaultCharType().toString(), ", "),
|
||||||
|
concat(f.getWideCharType().toString(), ", "), concat(f.getNonDefaultCharType().toString(), ", ")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
| AttributeFormattingFunction.cpp:4:54:4:59 | format | printf | 0 | 1 |
|
||||||
|
| AttributeFormattingFunction.cpp:5:69:5:74 | format | __printf__ | 1 | 2 |
|
||||||
|
| AttributeFormattingFunction.cpp:6:63:6:68 | format | printf | 0 | |
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import cpp
|
||||||
|
|
||||||
|
from FormatAttribute fa
|
||||||
|
select fa, fa.getArchetype(), concat(fa.getFormatIndex().toString(), ", "),
|
||||||
|
concat(fa.getFirstFormatArgIndex().toString(), ", ")
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
| test.c:14:9:14:10 | | 1 |
|
||||||
|
| test.c:15:9:15:14 | | 2 |
|
||||||
|
| test.c:16:9:16:12 | \t | 2 |
|
||||||
|
| test.c:17:9:17:12 | %% | 2 |
|
||||||
|
| test.c:20:9:20:12 | %c | 2 |
|
||||||
|
| test.c:21:9:21:16 | %c%c%c | 4 |
|
||||||
|
| test.c:24:9:24:23 | Hello, world! | 14 |
|
||||||
|
| test.c:25:9:25:12 | %s | 14 |
|
||||||
|
| test.c:26:9:26:14 | %.4s | 5 |
|
||||||
|
| test.c:27:9:27:16 | %s, %s | 14 |
|
||||||
|
| test.c:30:9:30:12 | %i | 12 |
|
||||||
|
| test.c:31:9:31:14 | %lli | 12 |
|
||||||
|
| test.c:32:9:32:12 | %i | 12 |
|
||||||
|
| test.c:33:9:33:14 | %lli | 21 |
|
||||||
|
| test.c:34:9:34:12 | %d | 12 |
|
||||||
|
| test.c:35:9:35:12 | %u | 11 |
|
||||||
|
| test.c:36:9:36:12 | %x | 9 |
|
||||||
|
| test.c:37:9:37:12 | %X | 9 |
|
||||||
|
| test.c:38:9:38:13 | %#x | 11 |
|
||||||
|
| test.c:39:9:39:12 | %o | 12 |
|
||||||
|
| test.c:40:9:40:13 | %#o | 13 |
|
||||||
|
| test.c:43:9:43:12 | %f | 318 |
|
||||||
|
| test.c:44:9:44:14 | %.2f | 314 |
|
||||||
|
| test.c:45:9:45:12 | %e | 15 |
|
||||||
|
| test.c:59:10:59:14 | %Ii | 12 |
|
||||||
|
| test.c:66:10:66:14 | %zu | 21 |
|
||||||
|
| test.c:67:10:67:14 | %Zu | 21 |
|
||||||
|
| test.c:74:10:74:14 | %lc | 2 |
|
||||||
|
| test.c:78:9:78:20 | %2$i, %1$i | 5 |
|
||||||
|
| test.c:79:9:79:20 | %2$i, %1$i | 25 |
|
||||||
|
| test.c:81:9:81:24 | %2$02i %1$4.2f | |
|
||||||
|
| test.c:85:10:85:18 | %2$*1$d | |
|
||||||
|
| test.c:86:10:86:19 | %2$0*1$d | |
|
||||||
|
| test.c:92:10:92:19 | %2$.*1$f | |
|
||||||
|
| test.c:99:10:99:12 | # | 2 |
|
||||||
|
| test.c:100:10:100:13 | %% | 2 |
|
||||||
|
| test.c:101:10:101:15 | %%%% | 3 |
|
||||||
|
| test.c:102:10:102:15 | %%%f | 319 |
|
||||||
|
| test.c:103:10:103:17 | %%%%%f | 320 |
|
||||||
|
| test.c:104:10:104:18 | %4.2f%% | 315 |
|
||||||
|
| test.c:105:10:105:17 | %%%f%% | 320 |
|
||||||
|
| test.c:112:10:112:13 | %f | 318 |
|
||||||
|
| test.c:113:10:113:15 | %.1f | 313 |
|
||||||
|
| test.c:114:10:114:14 | %1f | 318 |
|
||||||
|
| test.c:115:10:115:16 | %1.1f | 313 |
|
||||||
|
| test.c:116:10:116:13 | %e | 15 |
|
||||||
|
| test.c:117:10:117:15 | %.2e | 11 |
|
||||||
|
| test.c:118:10:118:14 | %3e | 15 |
|
||||||
|
| test.c:119:10:119:16 | %3.2e | 11 |
|
||||||
|
| test.c:120:10:120:13 | %g | 15 |
|
||||||
|
| test.c:121:10:121:15 | %.1g | 10 |
|
||||||
|
| test.c:122:10:122:14 | %4g | 15 |
|
||||||
|
| test.c:123:10:123:16 | %4.1g | 10 |
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import semmle.code.cpp.commons.Printf
|
||||||
|
|
||||||
|
from FormatLiteral fl
|
||||||
|
select fl, concat(fl.getMaxConvertedLength().toString(), ", ")
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
| test.c:20:9:20:12 | %c | 0 | | c | | file://:0:0:0:0 | char |
|
||||||
|
| test.c:21:9:21:16 | %c%c%c | 0 | | c | | file://:0:0:0:0 | char |
|
||||||
|
| test.c:21:9:21:16 | %c%c%c | 1 | | c | | file://:0:0:0:0 | char |
|
||||||
|
| test.c:21:9:21:16 | %c%c%c | 2 | | c | | file://:0:0:0:0 | char |
|
||||||
|
| test.c:25:9:25:12 | %s | 0 | | s | | file://:0:0:0:0 | char * |
|
||||||
|
| test.c:26:9:26:14 | %.4s | 0 | | s | | file://:0:0:0:0 | char * |
|
||||||
|
| test.c:27:9:27:16 | %s, %s | 0 | | s | | file://:0:0:0:0 | char * |
|
||||||
|
| test.c:27:9:27:16 | %s, %s | 1 | | s | | file://:0:0:0:0 | char * |
|
||||||
|
| test.c:30:9:30:12 | %i | 0 | | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:31:9:31:14 | %lli | 0 | | i | ll | file://:0:0:0:0 | long long |
|
||||||
|
| test.c:32:9:32:12 | %i | 0 | | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:33:9:33:14 | %lli | 0 | | i | ll | file://:0:0:0:0 | long long |
|
||||||
|
| test.c:34:9:34:12 | %d | 0 | | d | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:35:9:35:12 | %u | 0 | | u | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:36:9:36:12 | %x | 0 | | x | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:37:9:37:12 | %X | 0 | | X | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:38:9:38:13 | %#x | 0 | | x | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:39:9:39:12 | %o | 0 | | o | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:40:9:40:13 | %#o | 0 | | o | | file://:0:0:0:0 | unsigned int |
|
||||||
|
| test.c:43:9:43:12 | %f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:44:9:44:14 | %.2f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:45:9:45:12 | %e | 0 | | e | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:59:10:59:14 | %Ii | 0 | | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:66:10:66:14 | %zu | 0 | | u | z | test.c:50:27:50:32 | size_t |
|
||||||
|
| test.c:67:10:67:14 | %Zu | 0 | | u | Z | test.c:50:27:50:32 | size_t |
|
||||||
|
| test.c:74:10:74:14 | %lc | 0 | | c | l | file://:0:0:0:0 | wchar_t |
|
||||||
|
| test.c:78:9:78:20 | %2$i, %1$i | 0 | 2$ | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:78:9:78:20 | %2$i, %1$i | 1 | 1$ | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:79:9:79:20 | %2$i, %1$i | 0 | 2$ | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:79:9:79:20 | %2$i, %1$i | 1 | 1$ | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:81:9:81:24 | %2$02i %1$4.2f | 0 | 2$ | i | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:81:9:81:24 | %2$02i %1$4.2f | 1 | 1$ | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:85:10:85:18 | %2$*1$d | 0 | 2$ | d | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:86:10:86:19 | %2$0*1$d | 0 | 2$ | d | | file://:0:0:0:0 | int |
|
||||||
|
| test.c:92:10:92:19 | %2$.*1$f | 0 | 2$ | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:102:10:102:15 | %%%f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:103:10:103:17 | %%%%%f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:104:10:104:18 | %4.2f%% | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:105:10:105:17 | %%%f%% | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:112:10:112:13 | %f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:113:10:113:15 | %.1f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:114:10:114:14 | %1f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:115:10:115:16 | %1.1f | 0 | | f | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:116:10:116:13 | %e | 0 | | e | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:117:10:117:15 | %.2e | 0 | | e | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:118:10:118:14 | %3e | 0 | | e | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:119:10:119:16 | %3.2e | 0 | | e | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:120:10:120:13 | %g | 0 | | g | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:121:10:121:15 | %.1g | 0 | | g | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:122:10:122:14 | %4g | 0 | | g | | file://:0:0:0:0 | double |
|
||||||
|
| test.c:123:10:123:16 | %4.1g | 0 | | g | | file://:0:0:0:0 | double |
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import semmle.code.cpp.commons.Printf
|
||||||
|
|
||||||
|
from FormatLiteral fl, int i
|
||||||
|
select fl, i, concat(fl.getParameterField(i).toString(), ", "), fl.getConversionChar(i),
|
||||||
|
fl.getLength(i), concat(fl.getConversionType(i).getLocation().toString(), ", "),
|
||||||
|
concat(fl.getConversionType(i).toString(), ", ")
|
||||||
125
cpp/ql/test/library-tests/printf/formatLiteral/test.c
Normal file
125
cpp/ql/test/library-tests/printf/formatLiteral/test.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/** standard printf functions */
|
||||||
|
|
||||||
|
int printf(const char *format, ...);
|
||||||
|
|
||||||
|
/** test program */
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
long long int lli;
|
||||||
|
double d;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// constant expressions
|
||||||
|
printf("");
|
||||||
|
printf("\x20");
|
||||||
|
printf("\t");
|
||||||
|
printf("%%");
|
||||||
|
|
||||||
|
// characters
|
||||||
|
printf("%c", 'a');
|
||||||
|
printf("%c%c%c", 'a', 'b', 'c');
|
||||||
|
|
||||||
|
// strings
|
||||||
|
printf("Hello, world!");
|
||||||
|
printf("%s", "Hello, world!");
|
||||||
|
printf("%.4s", "Hello, world!");
|
||||||
|
printf("%s, %s", "Hello", "world!");
|
||||||
|
|
||||||
|
// integers
|
||||||
|
printf("%i", i);
|
||||||
|
printf("%lli", i);
|
||||||
|
printf("%i", lli);
|
||||||
|
printf("%lli", lli);
|
||||||
|
printf("%d", i);
|
||||||
|
printf("%u", i);
|
||||||
|
printf("%x", i);
|
||||||
|
printf("%X", i);
|
||||||
|
printf("%#x", i);
|
||||||
|
printf("%o", i);
|
||||||
|
printf("%#o", i);
|
||||||
|
|
||||||
|
// doubles
|
||||||
|
printf("%f", d);
|
||||||
|
printf("%.2f", d);
|
||||||
|
printf("%e", d);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef long unsigned int size_t;
|
||||||
|
typedef unsigned int wint_t;
|
||||||
|
|
||||||
|
void more_cases(int a, int b)
|
||||||
|
{
|
||||||
|
// integers
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("%Ii", i); // glibc 2.2 'I' prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// size_t
|
||||||
|
{
|
||||||
|
size_t st;
|
||||||
|
|
||||||
|
printf("%zu", st); // size_t
|
||||||
|
printf("%Zu", st); // non-standard synonym for 'z'
|
||||||
|
}
|
||||||
|
|
||||||
|
// wint_t
|
||||||
|
{
|
||||||
|
wint_t wt;
|
||||||
|
|
||||||
|
printf("%lc", wt); // wide character
|
||||||
|
}
|
||||||
|
|
||||||
|
// posix indexed format arguments
|
||||||
|
printf("%2$i, %1$i", 1, 2); // '2, 1'
|
||||||
|
printf("%2$i, %1$i", a, b);
|
||||||
|
|
||||||
|
printf("%2$02i %1$4.2f", 3.3333f, 6); // 06, 3.33
|
||||||
|
{
|
||||||
|
int width, num;
|
||||||
|
|
||||||
|
printf("%2$*1$d", width, num);
|
||||||
|
printf("%2$0*1$d", width, num);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int precision;
|
||||||
|
float num;
|
||||||
|
|
||||||
|
printf("%2$.*1$f", precision, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// %%
|
||||||
|
{
|
||||||
|
float num;
|
||||||
|
|
||||||
|
printf("#");
|
||||||
|
printf("%%");
|
||||||
|
printf("%%%%");
|
||||||
|
printf("%%%f", num);
|
||||||
|
printf("%%%%%f", num);
|
||||||
|
printf("%4.2f%%", num);
|
||||||
|
printf("%%%f%%", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// more tests of width and precision
|
||||||
|
{
|
||||||
|
float num;
|
||||||
|
|
||||||
|
printf("%f", num);
|
||||||
|
printf("%.1f", num);
|
||||||
|
printf("%1f", num);
|
||||||
|
printf("%1.1f", num);
|
||||||
|
printf("%e", num);
|
||||||
|
printf("%.2e", num);
|
||||||
|
printf("%3e", num);
|
||||||
|
printf("%3.2e", num);
|
||||||
|
printf("%g", num);
|
||||||
|
printf("%.1g", num);
|
||||||
|
printf("%4g", num);
|
||||||
|
printf("%4.1g", num);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
| test.cpp:4:26:4:26 | c<<expression>> |
|
| test.cpp:4:26:4:26 | c<<expression>> |
|
||||||
| test.cpp:4:26:4:26 | c<<unnamed>> |
|
| test.cpp:4:26:4:26 | c<<unnamed>> |
|
||||||
| test.cpp:5:29:5:29 | e |
|
| test.cpp:5:29:5:29 | e |
|
||||||
|
| test.cpp:6:24:6:24 | f |
|
||||||
| test.cpp:6:26:6:26 | (unnamed parameter 0) |
|
| test.cpp:6:26:6:26 | (unnamed parameter 0) |
|
||||||
| test.cpp:6:29:6:31 | (unnamed parameter 1) |
|
| test.cpp:6:29:6:31 | (unnamed parameter 1) |
|
||||||
| test.cpp:7:20:7:20 | f |
|
| test.cpp:7:20:7:20 | f |
|
||||||
|
|||||||
@@ -3,19 +3,20 @@
|
|||||||
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
|
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
|
||||||
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
||||||
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:50:10:50:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:51:10:51:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:56:12:56:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:57:12:57:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:59:12:59:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:60:12:60:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:60:12:60:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:61:12:61:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:61:12:61:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:62:12:62:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:62:12:62:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:63:12:63:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:63:12:63:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:64:12:64:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:64:12:64:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:65:12:65:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:66:10:66:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:67:10:67:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:69:12:69:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:70:12:70:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:75:12:75:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:76:12:76:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:81:12:81:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:82:12:82:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:87:12:87:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:88:12:88:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:92:12:92:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:93:12:93:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:109:12:109:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:110:12:110:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
| test.cpp:129:20:129:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
|
| test.cpp:130:20:130:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
|
||||||
|
| test.cpp:157:12:157:15 | data | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
extern "C" int printf(const char *fmt, ...);
|
extern "C" int printf(const char *fmt, ...);
|
||||||
extern "C" int sprintf(char *buf, const char *fmt, ...);
|
extern "C" int sprintf(char *buf, const char *fmt, ...);
|
||||||
extern "C" char *gettext (const char *);
|
extern "C" char *gettext(const char *);
|
||||||
|
extern "C" char *strcpy(char *dst, const char *src);
|
||||||
|
|
||||||
#define MYSPRINTF sprintf
|
#define MYSPRINTF sprintf
|
||||||
|
|
||||||
@@ -150,3 +151,8 @@ void print_ith_message() {
|
|||||||
set_value_of(&i);
|
set_value_of(&i);
|
||||||
printf(messages[i], 1U); // GOOD
|
printf(messages[i], 1U); // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt_via_strcpy(char *data) {
|
||||||
|
strcpy(data, "some string");
|
||||||
|
printf(data); // BAD
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 1.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 1.3.1
|
## 1.3.1
|
||||||
|
|
||||||
No user-facing changes.
|
No user-facing changes.
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
## 1.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 1.3.1
|
lastReleaseVersion: 1.3.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-all
|
name: codeql/csharp-solorigate-all
|
||||||
version: 1.3.2-dev
|
version: 1.3.3-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 1.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 1.3.1
|
## 1.3.1
|
||||||
|
|
||||||
No user-facing changes.
|
No user-facing changes.
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
## 1.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 1.3.1
|
lastReleaseVersion: 1.3.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-queries
|
name: codeql/csharp-solorigate-queries
|
||||||
version: 1.3.2-dev
|
version: 1.3.3-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
libraryPathDependencies:
|
dependencies:
|
||||||
- codeql-csharp
|
codeql/csharp-all: '*'
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
|
|||||||
3
csharp/ql/lib/change-notes/released/0.4.2.md
Normal file
3
csharp/ql/lib/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.4.1
|
lastReleaseVersion: 0.4.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-all
|
name: codeql/csharp-all
|
||||||
version: 0.4.2-dev
|
version: 0.4.3-dev
|
||||||
groups: csharp
|
groups: csharp
|
||||||
dbscheme: semmlecode.csharp.dbscheme
|
dbscheme: semmlecode.csharp.dbscheme
|
||||||
extractor: csharp
|
extractor: csharp
|
||||||
|
|||||||
@@ -1067,6 +1067,59 @@ private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::Sou
|
|||||||
capturedReadIn(bb, i, v, _, _, _)
|
capturedReadIn(bb, i, v, _, _, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[noinline]
|
||||||
|
private predicate adjacentDefRead(
|
||||||
|
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
|
||||||
|
SsaInput::SourceVariable v
|
||||||
|
) {
|
||||||
|
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||||
|
v = def.getSourceVariable()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate adjacentDefReachesRead(
|
||||||
|
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
|
||||||
|
) {
|
||||||
|
exists(SsaInput::SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||||
|
def.definesAt(v, bb1, i1)
|
||||||
|
or
|
||||||
|
SsaInput::variableRead(bb1, i1, v, true)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(SsaInput::BasicBlock bb3, int i3 |
|
||||||
|
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
|
||||||
|
SsaInput::variableRead(bb3, i3, _, false) and
|
||||||
|
adjacentDefRead(def, bb3, i3, bb2, i2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Same as `adjacentDefRead`, but skips uncertain reads. */
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate adjacentDefSkipUncertainReads(
|
||||||
|
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
|
||||||
|
) {
|
||||||
|
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
|
||||||
|
SsaInput::variableRead(bb2, i2, _, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate adjacentDefReachesUncertainRead(
|
||||||
|
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
|
||||||
|
) {
|
||||||
|
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
|
||||||
|
SsaInput::variableRead(bb2, i2, _, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Same as `lastRefRedef`, but skips uncertain reads. */
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) {
|
||||||
|
lastRef(def, bb, i) and
|
||||||
|
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
|
||||||
|
or
|
||||||
|
exists(SsaInput::BasicBlock bb0, int i0 |
|
||||||
|
lastRef(def, bb0, i0) and
|
||||||
|
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
private module Cached {
|
private module Cached {
|
||||||
cached
|
cached
|
||||||
@@ -1237,7 +1290,7 @@ private module Cached {
|
|||||||
predicate firstReadSameVar(Definition def, ControlFlow::Node cfn) {
|
predicate firstReadSameVar(Definition def, ControlFlow::Node cfn) {
|
||||||
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
|
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
|
||||||
def.definesAt(_, bb1, i1) and
|
def.definesAt(_, bb1, i1) and
|
||||||
adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and
|
adjacentDefSkipUncertainReads(def, bb1, i1, bb2, i2) and
|
||||||
cfn = bb2.getNode(i2)
|
cfn = bb2.getNode(i2)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1252,20 +1305,27 @@ private module Cached {
|
|||||||
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
|
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
|
||||||
cfn1 = bb1.getNode(i1) and
|
cfn1 = bb1.getNode(i1) and
|
||||||
variableReadActual(bb1, i1, _) and
|
variableReadActual(bb1, i1, _) and
|
||||||
adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and
|
adjacentDefSkipUncertainReads(def, bb1, i1, bb2, i2) and
|
||||||
cfn2 = bb2.getNode(i2)
|
cfn2 = bb2.getNode(i2)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Same as `lastRefRedef`, but skips uncertain reads. */
|
||||||
cached
|
cached
|
||||||
predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) {
|
predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) {
|
||||||
lastRefRedefNoUncertainReads(def, bb, i, next)
|
lastRefRedef(def, bb, i, next) and
|
||||||
|
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
|
||||||
|
or
|
||||||
|
exists(SsaInput::BasicBlock bb0, int i0 |
|
||||||
|
lastRefRedef(def, bb0, i0, next) and
|
||||||
|
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) {
|
predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) {
|
||||||
exists(ControlFlow::BasicBlock bb, int i |
|
exists(ControlFlow::BasicBlock bb, int i |
|
||||||
lastRefNoUncertainReads(def, bb, i) and
|
lastRefSkipUncertainReads(def, bb, i) and
|
||||||
variableReadActual(bb, i, _) and
|
variableReadActual(bb, i, _) and
|
||||||
cfn = bb.getNode(i)
|
cfn = bb.getNode(i)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 0.4.1
|
## 0.4.1
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
|
|||||||
3
csharp/ql/src/change-notes/released/0.4.2.md
Normal file
3
csharp/ql/src/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 0.4.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.4.1
|
lastReleaseVersion: 0.4.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-queries
|
name: codeql/csharp-queries
|
||||||
version: 0.4.2-dev
|
version: 0.4.3-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
||||||
exists(ActualResult actualResult |
|
exists(ActualResult actualResult |
|
||||||
actualResult.getTest() = this and
|
actualResult.getTest() = this and
|
||||||
|
actualResult.getTag() = this.getARelevantTag() and
|
||||||
element = actualResult and
|
element = actualResult and
|
||||||
(
|
(
|
||||||
exists(FalseNegativeExpectation falseNegative |
|
exists(FalseNegativeExpectation falseNegative |
|
||||||
@@ -150,9 +151,18 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
exists(ActualResult actualResult |
|
||||||
|
actualResult.getTest() = this and
|
||||||
|
not actualResult.getTag() = this.getARelevantTag() and
|
||||||
|
element = actualResult and
|
||||||
|
message =
|
||||||
|
"Tag mismatch: Actual result with tag '" + actualResult.getTag() +
|
||||||
|
"' that is not part of getARelevantTag()"
|
||||||
|
)
|
||||||
|
or
|
||||||
exists(ValidExpectation expectation |
|
exists(ValidExpectation expectation |
|
||||||
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
||||||
expectation.getTag() = getARelevantTag() and
|
expectation.getTag() = this.getARelevantTag() and
|
||||||
element = expectation and
|
element = expectation and
|
||||||
(
|
(
|
||||||
expectation instanceof GoodExpectation and
|
expectation instanceof GoodExpectation and
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ The valid YAML properties in the metadata are:
|
|||||||
After the `---` line following the metadata, the rest of the markdown file is the user-visible content of the change note. This should usually be a single markdown bullet list entry (starting with `*`), although it is acceptable to have multiple bullet entries in the same change note if there are multiple changes that are closely related and have the same category metadata.
|
After the `---` line following the metadata, the rest of the markdown file is the user-visible content of the change note. This should usually be a single markdown bullet list entry (starting with `*`), although it is acceptable to have multiple bullet entries in the same change note if there are multiple changes that are closely related and have the same category metadata.
|
||||||
|
|
||||||
## Change categories
|
## Change categories
|
||||||
Each change note must specifiy a `category` property in its metadata. This category servers two purposes: It determines how the change affects the version number of the next release of the pack, and it is used to group related changes in the final changelog. There is one set of available categories for query packs, and another set of available categories for library packs.
|
Each change note must specify a `category` property in its metadata. This category servers two purposes: It determines how the change affects the version number of the next release of the pack, and it is used to group related changes in the final changelog. There is one set of available categories for query packs, and another set of available categories for library packs.
|
||||||
|
|
||||||
### Query pack change categories
|
### Query pack change categories
|
||||||
| Category | SemVer effect | Description |
|
| Category | SemVer effect | Description |
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Running path queries in VS Code
|
|||||||
#. Once the query has finished running, you can see the results in the Results view as usual (under ``alerts`` in the dropdown menu). Each query result describes the flow of information between a source and a sink.
|
#. Once the query has finished running, you can see the results in the Results view as usual (under ``alerts`` in the dropdown menu). Each query result describes the flow of information between a source and a sink.
|
||||||
#. Expand the result to see the individual steps that the data follows.
|
#. Expand the result to see the individual steps that the data follows.
|
||||||
#. Click each step to jump to it in the source code and investigate the problem further.
|
#. Click each step to jump to it in the source code and investigate the problem further.
|
||||||
#. To navigate the path from your keyboard, you can bind shortcuts to the **CodeQL: Show Previous Step on Path** and **CodeQL: Show Next Step on Path** commands.
|
#. To navigate the results from your keyboard, you can bind shortcuts to the **CodeQL: Navigate Up/Down/Left/Right in Result Viewer** commands.
|
||||||
|
|
||||||
Further reading
|
Further reading
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
@@ -274,3 +274,70 @@ reference. For more information, see ":ref:`name-resolution`."
|
|||||||
|
|
||||||
For information about how import statements are looked up, see "`Module resolution <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#module-resolution>`__"
|
For information about how import statements are looked up, see "`Module resolution <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#module-resolution>`__"
|
||||||
in the QL language specification.
|
in the QL language specification.
|
||||||
|
|
||||||
|
Built-in modules
|
||||||
|
****************
|
||||||
|
|
||||||
|
QL defines a ``QlBuiltins`` module that is always in scope.
|
||||||
|
Currently, it defines a single parameterized sub-module
|
||||||
|
``EquivalenceRelation``, that provides an efficient abstraction for working with
|
||||||
|
(partial) equivalence relations in QL.
|
||||||
|
|
||||||
|
Equivalence relations
|
||||||
|
=====================
|
||||||
|
|
||||||
|
The built-in ``EquivalenceRelation`` module is parameterized by a type ``T`` and a
|
||||||
|
binary base relation ``base`` on ``T``. The symmetric and transitive closure of ``base``
|
||||||
|
induces a partial equivalence relation on ``T``. If every value of ``T`` appears in
|
||||||
|
``base``, then the induced relation is an equivalence relation on ``T``.
|
||||||
|
|
||||||
|
The ``EquivalenceRelation`` module exports a ``getEquivalenceClass`` predicate that
|
||||||
|
gets the equivalence class, if any, associated with a given ``T`` element by the
|
||||||
|
(partial) equivalence relation induced by ``base``.
|
||||||
|
|
||||||
|
The following example illustrates an application of the ``EquivalenceRelation``
|
||||||
|
module to generate a custom equivalence relation:
|
||||||
|
|
||||||
|
.. code-block:: ql
|
||||||
|
|
||||||
|
class Node extends int {
|
||||||
|
Node() { this in [1 .. 6] }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate base(Node x, Node y) {
|
||||||
|
x = 1 and y = 2
|
||||||
|
or
|
||||||
|
x = 3 and y = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
module Equiv = QlBuiltins::EquivalenceRelation<Node, base/2>;
|
||||||
|
|
||||||
|
from int x, int y
|
||||||
|
where Equiv::getEquivalenceClass(x) = Equiv::getEquivalenceClass(y)
|
||||||
|
select x, y
|
||||||
|
|
||||||
|
Since ``base`` does not relate ``5`` or ``6`` to any nodes, the induced
|
||||||
|
relation is a partial equivalence relation on ``Node`` and does not relate ``5``
|
||||||
|
or ``6`` to any nodes either.
|
||||||
|
|
||||||
|
The above select clause returns the following partial equivalence relation:
|
||||||
|
|
||||||
|
+---+---+
|
||||||
|
| x | y |
|
||||||
|
+===+===+
|
||||||
|
| 1 | 1 |
|
||||||
|
+---+---+
|
||||||
|
| 1 | 2 |
|
||||||
|
+---+---+
|
||||||
|
| 2 | 1 |
|
||||||
|
+---+---+
|
||||||
|
| 2 | 2 |
|
||||||
|
+---+---+
|
||||||
|
| 3 | 3 |
|
||||||
|
+---+---+
|
||||||
|
| 3 | 4 |
|
||||||
|
+---+---+
|
||||||
|
| 4 | 3 |
|
||||||
|
+---+---+
|
||||||
|
| 4 | 4 |
|
||||||
|
+---+---+
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ Various kinds of syntax can have *annotations* applied to them. Annotations are
|
|||||||
| "override"
|
| "override"
|
||||||
| "query"
|
| "query"
|
||||||
|
|
||||||
argsAnnotation ::= "pragma" "[" ("inline" | "noinline" | "nomagic" | "noopt") "]"
|
argsAnnotation ::= "pragma" "[" ("inline" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]"
|
||||||
| "language" "[" "monotonicAggregates" "]"
|
| "language" "[" "monotonicAggregates" "]"
|
||||||
| "bindingset" "[" (variable ( "," variable)*)? "]"
|
| "bindingset" "[" (variable ( "," variable)*)? "]"
|
||||||
|
|
||||||
@@ -687,17 +687,19 @@ Parameterized annotations take some additional arguments.
|
|||||||
|
|
||||||
The parameterized annotation ``pragma`` supplies compiler pragmas, and may be applied in various contexts depending on the pragma in question.
|
The parameterized annotation ``pragma`` supplies compiler pragmas, and may be applied in various contexts depending on the pragma in question.
|
||||||
|
|
||||||
+--------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
| Pragma | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases |
|
| Pragma | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases |
|
||||||
+==============+=========+============+===================+=======================+=========+========+=========+=========+
|
+===========================+=========+============+===================+=======================+=========+========+=========+=========+
|
||||||
| ``inline`` | | yes | yes | yes | | | | |
|
| ``inline`` | | yes | yes | yes | | | | |
|
||||||
+--------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
| ``noinline`` | | yes | yes | yes | | | | |
|
| ``noinline`` | | yes | yes | yes | | | | |
|
||||||
+--------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
| ``nomagic`` | | yes | yes | yes | | | | |
|
| ``nomagic`` | | yes | yes | yes | | | | |
|
||||||
+--------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
| ``noopt`` | | yes | yes | yes | | | | |
|
| ``noopt`` | | yes | yes | yes | | | | |
|
||||||
+--------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
|
| ``assume_small_delta`` | | yes | yes | yes | | | | |
|
||||||
|
+---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+
|
||||||
|
|
||||||
The parameterized annotation ``language`` supplies language pragmas which change the behavior of the language. Language pragmas apply at the scope level, and are inherited by nested scopes.
|
The parameterized annotation ``language`` supplies language pragmas which change the behavior of the language. Language pragmas apply at the scope level, and are inherited by nested scopes.
|
||||||
|
|
||||||
@@ -2048,7 +2050,7 @@ The complete grammar for QL is as follows:
|
|||||||
| "override"
|
| "override"
|
||||||
| "query"
|
| "query"
|
||||||
|
|
||||||
argsAnnotation ::= "pragma" "[" ("noinline" | "nomagic" | "noopt") "]"
|
argsAnnotation ::= "pragma" "[" ("inline" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]"
|
||||||
| "language" "[" "monotonicAggregates" "]"
|
| "language" "[" "monotonicAggregates" "]"
|
||||||
| "bindingset" "[" (variable ( "," variable)*)? "]"
|
| "bindingset" "[" (variable ( "," variable)*)? "]"
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,11 @@ Type signatures
|
|||||||
===============
|
===============
|
||||||
|
|
||||||
Type signatures declare module parameters that will be substituted with types when the module is instantiated.
|
Type signatures declare module parameters that will be substituted with types when the module is instantiated.
|
||||||
Type signatures are used to specify supertypes and are the simplest category of signatures.
|
Type signatures may specify supertypes and required member predicates (in addition to those member predicates that are
|
||||||
|
implied by the supertypes).
|
||||||
|
|
||||||
The substitution of type signatures relies on structural typing. That is, types do not have to be explicitly defined as
|
The substitution of type signatures relies on structural typing. That is, types do not have to be explicitly defined as
|
||||||
implementing a type signature - they just need to have the specified (transitive) supertypes.
|
implementing a type signature - they just need to have the specified (transitive) supertypes and member predicates.
|
||||||
|
|
||||||
In detail, a type signature definition consists of:
|
In detail, a type signature definition consists of:
|
||||||
|
|
||||||
@@ -52,7 +53,8 @@ In detail, a type signature definition consists of:
|
|||||||
#. The name of the type signature. This is an `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
|
#. The name of the type signature. This is an `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
|
||||||
starting with a uppercase letter.
|
starting with a uppercase letter.
|
||||||
#. Optionally, the keyword ``extends`` followed by a list of types, separated by commas.
|
#. Optionally, the keyword ``extends`` followed by a list of types, separated by commas.
|
||||||
#. A semicolon ``;``.
|
#. Either a semicolon ``;`` or a list of predicate signatures enclosed in braces.
|
||||||
|
The ``signature`` keyword is omitted for these contained signatures.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@@ -60,6 +62,10 @@ For example:
|
|||||||
|
|
||||||
signature class ExtendsInt extends int;
|
signature class ExtendsInt extends int;
|
||||||
|
|
||||||
|
signature class CanBePrinted {
|
||||||
|
string toString();
|
||||||
|
}
|
||||||
|
|
||||||
Module signatures
|
Module signatures
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
|||||||
@@ -294,8 +294,8 @@ through an additional step targeting a `PostUpdateNode`).
|
|||||||
|
|
||||||
It is recommended to introduce `PostUpdateNode`s for all `ArgumentNode`s (this
|
It is recommended to introduce `PostUpdateNode`s for all `ArgumentNode`s (this
|
||||||
can be skipped for immutable arguments), and all field qualifiers for both
|
can be skipped for immutable arguments), and all field qualifiers for both
|
||||||
reads and stores. Note also that in the case of compund arguments, such as
|
reads and stores. Note also that in the case of compound arguments, such as
|
||||||
`b ? x : y`, it is recommented to have post-update nodes for `x` and `y` (and
|
`b ? x : y`, it is recommended to have post-update nodes for `x` and `y` (and
|
||||||
not the compound argument itself), and let `[post update] x` have both `x`
|
not the compound argument itself), and let `[post update] x` have both `x`
|
||||||
and `b ? x : y` as pre-update nodes (and similarly for `[post update] y`).
|
and `b ? x : y` as pre-update nodes (and similarly for `[post update] y`).
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
lgtm,codescanning
|
lgtm,codescanning
|
||||||
* Improved recongition of sanitizer functions for the `go/zipslip` query. This may reduce false-positives (but also perhaps false-negatives) when application code attempts to check a zip header entry does not contain an illegal path traversal attempt.
|
* Improved recognition of sanitizer functions for the `go/zipslip` query. This may reduce false-positives (but also perhaps false-negatives) when application code attempts to check a zip header entry does not contain an illegal path traversal attempt.
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
lgtm,codescanning
|
lgtm,codescanning
|
||||||
* Added support for [the offical Couchbase Go SDK library](https://github.com/couchbase/gocb), v1 and v2. The `go/sql-injection` query (which also handles non-SQL databases such as Couchbase) will now identify Couchbase queries built from untrusted external input.
|
* Added support for [the official Couchbase Go SDK library](https://github.com/couchbase/gocb), v1 and v2. The `go/sql-injection` query (which also handles non-SQL databases such as Couchbase) will now identify Couchbase queries built from untrusted external input.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
name: legacy-libraries-go
|
name: legacy-libraries-go
|
||||||
version: 0.0.0
|
version: 0.0.0
|
||||||
|
# Note libraryPathDependencies is obsolete and should not be used in new qlpacks.
|
||||||
libraryPathDependencies: codeql-go
|
libraryPathDependencies: codeql-go
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
|
|
||||||
## 0.3.1
|
## 0.3.1
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
|
|||||||
3
go/ql/lib/change-notes/released/0.3.2.md
Normal file
3
go/ql/lib/change-notes/released/0.3.2.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 0.3.2
|
||||||
|
|
||||||
|
No user-facing changes.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.3.1
|
lastReleaseVersion: 0.3.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/go-all
|
name: codeql/go-all
|
||||||
version: 0.3.2-dev
|
version: 0.3.3-dev
|
||||||
groups: go
|
groups: go
|
||||||
dbscheme: go.dbscheme
|
dbscheme: go.dbscheme
|
||||||
extractor: go
|
extractor: go
|
||||||
|
|||||||
@@ -123,21 +123,21 @@ module Protobuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A `Get` method of a protobuf `Message` type. */
|
/** A `Get` method of a protobuf `Message` type. */
|
||||||
private class GetMethod extends DataFlow::FunctionModel, Method {
|
class GetMethod extends TaintTracking::FunctionModel, Method {
|
||||||
GetMethod() {
|
GetMethod() {
|
||||||
exists(string name | name.matches("Get%") | this = any(MessageType msg).getMethod(name))
|
exists(string name | name.matches("Get%") | this = any(MessageType msg).getMethod(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasDataFlow(FunctionInput inp, FunctionOutput outp) {
|
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||||
inp.isReceiver() and outp.isResult()
|
inp.isReceiver() and outp.isResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A `ProtoReflect` method of a protobuf `Message` type. */
|
/** A `ProtoReflect` method of a protobuf `Message` type. */
|
||||||
private class ProtoReflectMethod extends DataFlow::FunctionModel, Method {
|
private class ProtoReflectMethod extends TaintTracking::FunctionModel, Method {
|
||||||
ProtoReflectMethod() { this = any(MessageType msg).getMethod("ProtoReflect") }
|
ProtoReflectMethod() { this = any(MessageType msg).getMethod("ProtoReflect") }
|
||||||
|
|
||||||
override predicate hasDataFlow(FunctionInput inp, FunctionOutput outp) {
|
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||||
inp.isReceiver() and outp.isResult()
|
inp.isReceiver() and outp.isResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,12 @@ module CleartextLogging {
|
|||||||
write.writesField(trg.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, src)
|
write.writesField(trg.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, src)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
// taint steps that do not include flow through fields
|
// taint steps that do not include flow through fields. Field reads would produce FPs due to
|
||||||
TaintTracking::localTaintStep(src, trg) and not TaintTracking::fieldReadStep(src, trg)
|
// the additional taint step above that taints whole structs from individual field writes.
|
||||||
|
TaintTracking::localTaintStep(src, trg) and
|
||||||
|
not TaintTracking::fieldReadStep(src, trg) and
|
||||||
|
// Also exclude protobuf field fetches, since they amount to single field reads.
|
||||||
|
not any(Protobuf::GetMethod gm).taintStep(src, trg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
## 0.3.2
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The alert messages of many queries were changed to better follow the style guide and make the messages consistent with other languages.
|
||||||
|
|
||||||
## 0.3.1
|
## 0.3.1
|
||||||
|
|
||||||
No user-facing changes.
|
No user-facing changes.
|
||||||
|
|||||||
@@ -9,5 +9,7 @@
|
|||||||
import go
|
import go
|
||||||
|
|
||||||
from File f
|
from File f
|
||||||
where not exists(Error e | e.getFile() = f)
|
where
|
||||||
select f.getRelativePath()
|
not exists(Error e | e.getFile() = f) and
|
||||||
|
exists(f.getRelativePath())
|
||||||
|
select f, ""
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Query `go/clear-text-logging` now excludes `GetX` methods of protobuf `Message` structs, except where taint is specifically known to belong to the right field. This is to avoid FPs where taint is written to one field and then spuriously read from another.
|
||||||
5
go/ql/src/change-notes/released/0.3.2.md
Normal file
5
go/ql/src/change-notes/released/0.3.2.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## 0.3.2
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The alert messages of many queries were changed to better follow the style guide and make the messages consistent with other languages.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.3.1
|
lastReleaseVersion: 0.3.2
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
dependencies:
|
dependencies: {}
|
||||||
codeql/suite-helpers:
|
|
||||||
version: 0.0.2
|
|
||||||
compiled: false
|
compiled: false
|
||||||
lockVersion: 1.0.0
|
lockVersion: 1.0.0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/go-queries
|
name: codeql/go-queries
|
||||||
version: 0.3.2-dev
|
version: 0.3.3-dev
|
||||||
groups:
|
groups:
|
||||||
- go
|
- go
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
||||||
exists(ActualResult actualResult |
|
exists(ActualResult actualResult |
|
||||||
actualResult.getTest() = this and
|
actualResult.getTest() = this and
|
||||||
|
actualResult.getTag() = this.getARelevantTag() and
|
||||||
element = actualResult and
|
element = actualResult and
|
||||||
(
|
(
|
||||||
exists(FalseNegativeExpectation falseNegative |
|
exists(FalseNegativeExpectation falseNegative |
|
||||||
@@ -150,9 +151,18 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
exists(ActualResult actualResult |
|
||||||
|
actualResult.getTest() = this and
|
||||||
|
not actualResult.getTag() = this.getARelevantTag() and
|
||||||
|
element = actualResult and
|
||||||
|
message =
|
||||||
|
"Tag mismatch: Actual result with tag '" + actualResult.getTag() +
|
||||||
|
"' that is not part of getARelevantTag()"
|
||||||
|
)
|
||||||
|
or
|
||||||
exists(ValidExpectation expectation |
|
exists(ValidExpectation expectation |
|
||||||
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
||||||
expectation.getTag() = getARelevantTag() and
|
expectation.getTag() = this.getARelevantTag() and
|
||||||
element = expectation and
|
element = expectation and
|
||||||
(
|
(
|
||||||
expectation instanceof GoodExpectation and
|
expectation instanceof GoodExpectation and
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
dependencies:
|
dependencies: {}
|
||||||
codeql/suite-helpers:
|
|
||||||
version: 0.0.2
|
|
||||||
compiled: false
|
compiled: false
|
||||||
lockVersion: 1.0.0
|
lockVersion: 1.0.0
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| query-tests/Diagnostics/util.go |
|
| util.go:0:0:0:0 | util.go | |
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ edges
|
|||||||
| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config |
|
| passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config |
|
||||||
| passwords.go:126:14:126:19 | config [x] : string | passwords.go:126:14:126:21 | selection of x |
|
| passwords.go:126:14:126:19 | config [x] : string | passwords.go:126:14:126:21 | selection of x |
|
||||||
| passwords.go:127:14:127:19 | config [y] : string | passwords.go:127:14:127:21 | selection of y |
|
| passwords.go:127:14:127:19 | config [y] : string | passwords.go:127:14:127:21 | selection of y |
|
||||||
|
| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | protobuf.go:12:2:12:6 | query [pointer, Description] : string |
|
||||||
|
| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | protobuf.go:14:14:14:18 | query [pointer, Description] : string |
|
||||||
|
| protobuf.go:12:2:12:6 | implicit dereference [Description] : string | protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string |
|
||||||
|
| protobuf.go:12:2:12:6 | query [pointer, Description] : string | protobuf.go:12:2:12:6 | implicit dereference [Description] : string |
|
||||||
|
| protobuf.go:12:22:12:29 | password : string | protobuf.go:12:2:12:6 | implicit dereference [Description] : string |
|
||||||
|
| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protobuf.go:14:14:14:35 | call to GetDescription |
|
||||||
|
| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string |
|
||||||
|
| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string |
|
||||||
|
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string |
|
||||||
|
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string |
|
||||||
| util.go:16:9:16:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword |
|
| util.go:16:9:16:18 | selection of password : string | passwords.go:28:14:28:28 | call to getPassword |
|
||||||
nodes
|
nodes
|
||||||
| klog.go:20:30:20:37 | selection of Header : Header | semmle.label | selection of Header : Header |
|
| klog.go:20:30:20:37 | selection of Header : Header | semmle.label | selection of Header : Header |
|
||||||
@@ -77,8 +87,19 @@ nodes
|
|||||||
| passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x |
|
| passwords.go:126:14:126:21 | selection of x | semmle.label | selection of x |
|
||||||
| passwords.go:127:14:127:19 | config [y] : string | semmle.label | config [y] : string |
|
| passwords.go:127:14:127:19 | config [y] : string | semmle.label | config [y] : string |
|
||||||
| passwords.go:127:14:127:21 | selection of y | semmle.label | selection of y |
|
| passwords.go:127:14:127:21 | selection of y | semmle.label | selection of y |
|
||||||
|
| protobuf.go:11:2:11:6 | definition of query [pointer, Description] : string | semmle.label | definition of query [pointer, Description] : string |
|
||||||
|
| protobuf.go:12:2:12:6 | implicit dereference [Description] : string | semmle.label | implicit dereference [Description] : string |
|
||||||
|
| protobuf.go:12:2:12:6 | query [pointer, Description] : string | semmle.label | query [pointer, Description] : string |
|
||||||
|
| protobuf.go:12:22:12:29 | password : string | semmle.label | password : string |
|
||||||
|
| protobuf.go:14:14:14:18 | query [pointer, Description] : string | semmle.label | query [pointer, Description] : string |
|
||||||
|
| protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription |
|
||||||
|
| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | semmle.label | definition of x [pointer, Description] : string |
|
||||||
|
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] : string | semmle.label | implicit dereference [Description] : string |
|
||||||
|
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] : string | semmle.label | x [pointer, Description] : string |
|
||||||
|
| protos/query/query.pb.go:119:10:119:22 | selection of Description : string | semmle.label | selection of Description : string |
|
||||||
| util.go:16:9:16:18 | selection of password : string | semmle.label | selection of password : string |
|
| util.go:16:9:16:18 | selection of password : string | semmle.label | selection of password : string |
|
||||||
subpaths
|
subpaths
|
||||||
|
| protobuf.go:14:14:14:18 | query [pointer, Description] : string | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] : string | protos/query/query.pb.go:119:10:119:22 | selection of Description : string | protobuf.go:14:14:14:35 | call to GetDescription : string |
|
||||||
#select
|
#select
|
||||||
| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers |
|
| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header : Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers |
|
||||||
| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers |
|
| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header : Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers |
|
||||||
@@ -111,3 +132,4 @@ subpaths
|
|||||||
| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:125:14:125:19 | config | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:125:14:125:19 | config | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password : string | passwords.go:126:14:126:21 | selection of x | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password |
|
| passwords.go:126:14:126:21 | selection of x | passwords.go:121:13:121:20 | password : string | passwords.go:126:14:126:21 | selection of x | $@ flows to a logging call. | passwords.go:121:13:121:20 | password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword : string | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
|
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password : string | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password |
|
||||||
|
|||||||
@@ -6,4 +6,6 @@ require (
|
|||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
github.com/sirupsen/logrus v1.5.0
|
github.com/sirupsen/logrus v1.5.0
|
||||||
k8s.io/klog v1.0.0
|
k8s.io/klog v1.0.0
|
||||||
|
github.com/golang/protobuf v1.4.2
|
||||||
|
google.golang.org/protobuf v1.23.0
|
||||||
)
|
)
|
||||||
|
|||||||
16
go/ql/test/query-tests/Security/CWE-312/protobuf.go
Normal file
16
go/ql/test/query-tests/Security/CWE-312/protobuf.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"main/protos/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testProtobuf() {
|
||||||
|
password := "P@ssw0rd"
|
||||||
|
|
||||||
|
query := &query.Query{}
|
||||||
|
query.Description = password
|
||||||
|
|
||||||
|
log.Println(query.GetDescription()) // NOT OK
|
||||||
|
log.Println(query.GetId()) // OK
|
||||||
|
}
|
||||||
25
go/ql/test/query-tests/Security/CWE-312/protos/query.proto
Normal file
25
go/ql/test/query-tests/Security/CWE-312/protos/query.proto
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
option go_package = "protos/query";
|
||||||
|
|
||||||
|
message Query {
|
||||||
|
string description = 1;
|
||||||
|
string id = 2;
|
||||||
|
|
||||||
|
enum Severity {
|
||||||
|
ERROR = 0;
|
||||||
|
WARNING = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Alert {
|
||||||
|
string msg = 1;
|
||||||
|
int64 loc = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated Alert alerts = 4;
|
||||||
|
|
||||||
|
map<int32, string> keyValuePairs = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message QuerySuite {
|
||||||
|
repeated Query queries = 1;
|
||||||
|
}
|
||||||
371
go/ql/test/query-tests/Security/CWE-312/protos/query/query.pb.go
Normal file
371
go/ql/test/query-tests/Security/CWE-312/protos/query/query.pb.go
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.25.0-devel
|
||||||
|
// protoc v3.12.4
|
||||||
|
// source: query.proto
|
||||||
|
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
proto "github.com/golang/protobuf/proto"
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||||
|
// of the legacy proto package is being used.
|
||||||
|
const _ = proto.ProtoPackageIsVersion4
|
||||||
|
|
||||||
|
type Query_Severity int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Query_ERROR Query_Severity = 0
|
||||||
|
Query_WARNING Query_Severity = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for Query_Severity.
|
||||||
|
var (
|
||||||
|
Query_Severity_name = map[int32]string{
|
||||||
|
0: "ERROR",
|
||||||
|
1: "WARNING",
|
||||||
|
}
|
||||||
|
Query_Severity_value = map[string]int32{
|
||||||
|
"ERROR": 0,
|
||||||
|
"WARNING": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x Query_Severity) Enum() *Query_Severity {
|
||||||
|
p := new(Query_Severity)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Query_Severity) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Query_Severity) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_query_proto_enumTypes[0].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Query_Severity) Type() protoreflect.EnumType {
|
||||||
|
return &file_query_proto_enumTypes[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Query_Severity) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Query_Severity.Descriptor instead.
|
||||||
|
func (Query_Severity) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_query_proto_rawDescGZIP(), []int{0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
|
||||||
|
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
|
Alerts []*Query_Alert `protobuf:"bytes,4,rep,name=alerts,proto3" json:"alerts,omitempty"`
|
||||||
|
KeyValuePairs map[int32]string `protobuf:"bytes,5,rep,name=keyValuePairs,proto3" json:"keyValuePairs,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) Reset() {
|
||||||
|
*x = Query{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_query_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Query) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Query) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_query_proto_msgTypes[0]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Query.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Query) Descriptor() ([]byte, []int) {
|
||||||
|
return file_query_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) GetDescription() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Description
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) GetId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) GetAlerts() []*Query_Alert {
|
||||||
|
if x != nil {
|
||||||
|
return x.Alerts
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query) GetKeyValuePairs() map[int32]string {
|
||||||
|
if x != nil {
|
||||||
|
return x.KeyValuePairs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuerySuite struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Queries []*Query `protobuf:"bytes,1,rep,name=queries,proto3" json:"queries,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *QuerySuite) Reset() {
|
||||||
|
*x = QuerySuite{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_query_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *QuerySuite) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*QuerySuite) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *QuerySuite) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_query_proto_msgTypes[1]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use QuerySuite.ProtoReflect.Descriptor instead.
|
||||||
|
func (*QuerySuite) Descriptor() ([]byte, []int) {
|
||||||
|
return file_query_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *QuerySuite) GetQueries() []*Query {
|
||||||
|
if x != nil {
|
||||||
|
return x.Queries
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query_Alert struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
|
||||||
|
Loc int64 `protobuf:"varint,2,opt,name=loc,proto3" json:"loc,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query_Alert) Reset() {
|
||||||
|
*x = Query_Alert{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_query_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query_Alert) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Query_Alert) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Query_Alert) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_query_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Query_Alert.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Query_Alert) Descriptor() ([]byte, []int) {
|
||||||
|
return file_query_proto_rawDescGZIP(), []int{0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query_Alert) GetMsg() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Msg
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Query_Alert) GetLoc() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Loc
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_query_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_query_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x02,
|
||||||
|
0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
|
||||||
|
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
|
||||||
|
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||||
|
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x06, 0x61, 0x6c, 0x65,
|
||||||
|
0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x51, 0x75, 0x65, 0x72,
|
||||||
|
0x79, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x52, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12,
|
||||||
|
0x3f, 0x0a, 0x0d, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73,
|
||||||
|
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4b,
|
||||||
|
0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||||
|
0x79, 0x52, 0x0d, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73,
|
||||||
|
0x1a, 0x2b, 0x0a, 0x05, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67,
|
||||||
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6c,
|
||||||
|
0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6c, 0x6f, 0x63, 0x1a, 0x40, 0x0a,
|
||||||
|
0x12, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x45, 0x6e,
|
||||||
|
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
||||||
|
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
||||||
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
|
||||||
|
0x22, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x45,
|
||||||
|
0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e,
|
||||||
|
0x47, 0x10, 0x01, 0x22, 0x2e, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x75, 0x69, 0x74,
|
||||||
|
0x65, 0x12, 0x20, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||||
|
0x28, 0x0b, 0x32, 0x06, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72,
|
||||||
|
0x69, 0x65, 0x73, 0x42, 0x0e, 0x5a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x71, 0x75,
|
||||||
|
0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_query_proto_rawDescOnce sync.Once
|
||||||
|
file_query_proto_rawDescData = file_query_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_query_proto_rawDescGZIP() []byte {
|
||||||
|
file_query_proto_rawDescOnce.Do(func() {
|
||||||
|
file_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_query_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_query_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_query_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||||
|
var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||||
|
var file_query_proto_goTypes = []interface{}{
|
||||||
|
(Query_Severity)(0), // 0: Query.Severity
|
||||||
|
(*Query)(nil), // 1: Query
|
||||||
|
(*QuerySuite)(nil), // 2: QuerySuite
|
||||||
|
(*Query_Alert)(nil), // 3: Query.Alert
|
||||||
|
nil, // 4: Query.KeyValuePairsEntry
|
||||||
|
}
|
||||||
|
var file_query_proto_depIdxs = []int32{
|
||||||
|
3, // 0: Query.alerts:type_name -> Query.Alert
|
||||||
|
4, // 1: Query.keyValuePairs:type_name -> Query.KeyValuePairsEntry
|
||||||
|
1, // 2: QuerySuite.queries:type_name -> Query
|
||||||
|
3, // [3:3] is the sub-list for method output_type
|
||||||
|
3, // [3:3] is the sub-list for method input_type
|
||||||
|
3, // [3:3] is the sub-list for extension type_name
|
||||||
|
3, // [3:3] is the sub-list for extension extendee
|
||||||
|
0, // [0:3] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_query_proto_init() }
|
||||||
|
func file_query_proto_init() {
|
||||||
|
if File_query_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Query); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*QuerySuite); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Query_Alert); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_query_proto_rawDesc,
|
||||||
|
NumEnums: 1,
|
||||||
|
NumMessages: 4,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_query_proto_goTypes,
|
||||||
|
DependencyIndexes: file_query_proto_depIdxs,
|
||||||
|
EnumInfos: file_query_proto_enumTypes,
|
||||||
|
MessageInfos: file_query_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_query_proto = out.File
|
||||||
|
file_query_proto_rawDesc = nil
|
||||||
|
file_query_proto_goTypes = nil
|
||||||
|
file_query_proto_depIdxs = nil
|
||||||
|
}
|
||||||
28
go/ql/test/query-tests/Security/CWE-312/vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
28
go/ql/test/query-tests/Security/CWE-312/vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
29
go/ql/test/query-tests/Security/CWE-312/vendor/github.com/golang/protobuf/proto/stub.go
generated
vendored
Normal file
29
go/ql/test/query-tests/Security/CWE-312/vendor/github.com/golang/protobuf/proto/stub.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// This is a simple stub for github.com/golang/protobuf/proto, strictly for use in testing.
|
||||||
|
|
||||||
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
|
// Source: github.com/golang/protobuf/proto (exports: Message; functions: Marshal,Unmarshal,ProtoPackageIsVersion4)
|
||||||
|
|
||||||
|
// Package proto is a stub of github.com/golang/protobuf/proto
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Marshal(_ interface{}) ([]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message = protoiface.MessageV1
|
||||||
|
|
||||||
|
const ProtoPackageIsVersion4 bool = false
|
||||||
|
|
||||||
|
func Unmarshal(_ []byte, _ interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clone(_ Message) Message {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Merge(_, _ Message) {}
|
||||||
27
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/LICENSE
generated
vendored
Normal file
27
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2018 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
132
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/internal/impl/stub.go
generated
vendored
Normal file
132
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/internal/impl/stub.go
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// This is a simple stub for google.golang.org/protobuf/internal/impl, strictly for use in testing.
|
||||||
|
|
||||||
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
|
// Source: google.golang.org/protobuf/internal/impl (exports: MessageState,Pointer; functions: )
|
||||||
|
|
||||||
|
// Package impl is a stub of google.golang.org/protobuf/internal/impl.
|
||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MessageState struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
DoNotCompare interface{}
|
||||||
|
DoNotCopy interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pointer interface{}
|
||||||
|
|
||||||
|
type MessageInfo struct {
|
||||||
|
Exporter interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*MessageInfo) MessageOf(_ interface{}) protoreflect.Message { return nil }
|
||||||
|
|
||||||
|
type EnumInfo struct{}
|
||||||
|
|
||||||
|
func (_ *EnumInfo) Descriptor() protoreflect.EnumDescriptor { return nil }
|
||||||
|
func (_ *EnumInfo) New(_ protoreflect.EnumNumber) protoreflect.Enum { return nil }
|
||||||
|
|
||||||
|
type DescBuilder struct {
|
||||||
|
GoPackagePath string
|
||||||
|
RawDescriptor []byte
|
||||||
|
NumEnums int
|
||||||
|
NumMessages int
|
||||||
|
NumExtensions int
|
||||||
|
NumServices int
|
||||||
|
}
|
||||||
|
|
||||||
|
type TypeBuilder struct {
|
||||||
|
File DescBuilder
|
||||||
|
GoTypes []interface{}
|
||||||
|
DependencyIndexes []int32
|
||||||
|
EnumInfos []EnumInfo
|
||||||
|
MessageInfos []MessageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type BuilderOut struct {
|
||||||
|
File protoreflect.FileDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tb TypeBuilder) Build() BuilderOut {
|
||||||
|
return BuilderOut{nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *MessageState) LoadMessageInfo() *MessageInfo { return nil }
|
||||||
|
func (ms *MessageState) StoreMessageInfo(mi *MessageInfo) {}
|
||||||
|
|
||||||
|
func (ms *MessageState) Clear(_ protoreflect.FieldDescriptor) {}
|
||||||
|
func (ms *MessageState) Descriptor() protoreflect.MessageDescriptor { return nil }
|
||||||
|
func (ms *MessageState) Get(_ protoreflect.FieldDescriptor) protoreflect.Value {
|
||||||
|
return protoreflect.Value{}
|
||||||
|
}
|
||||||
|
func (ms *MessageState) GetUnknown() protoreflect.RawFields { return nil }
|
||||||
|
func (ms *MessageState) Has(_ protoreflect.FieldDescriptor) bool { return false }
|
||||||
|
func (ms *MessageState) Interface() protoreflect.ProtoMessage { return nil }
|
||||||
|
func (ms *MessageState) IsValid() bool { return false }
|
||||||
|
func (ms *MessageState) Mutable(_ protoreflect.FieldDescriptor) protoreflect.Value {
|
||||||
|
return protoreflect.Value{}
|
||||||
|
}
|
||||||
|
func (ms *MessageState) New() protoreflect.Message { return nil }
|
||||||
|
func (ms *MessageState) NewField(_ protoreflect.FieldDescriptor) protoreflect.Value {
|
||||||
|
return protoreflect.Value{}
|
||||||
|
}
|
||||||
|
func (ms *MessageState) ProtoMethods() *struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags uint64
|
||||||
|
Size func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message protoreflect.Message
|
||||||
|
Flags byte
|
||||||
|
}) struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Size int
|
||||||
|
}
|
||||||
|
Marshal func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message protoreflect.Message
|
||||||
|
Buf []byte
|
||||||
|
Flags byte
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Buf []byte
|
||||||
|
}, error)
|
||||||
|
Unmarshal func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message protoreflect.Message
|
||||||
|
Buf []byte
|
||||||
|
Flags byte
|
||||||
|
Resolver interface {
|
||||||
|
FindExtensionByName(_ protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||||
|
FindExtensionByNumber(_ protoreflect.FullName, _ interface{}) (protoreflect.ExtensionType, error)
|
||||||
|
}
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags byte
|
||||||
|
}, error)
|
||||||
|
Merge func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Source protoreflect.Message
|
||||||
|
Destination protoreflect.Message
|
||||||
|
}) struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags byte
|
||||||
|
}
|
||||||
|
CheckInitialized func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message protoreflect.Message
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
}, error)
|
||||||
|
} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (ms *MessageState) Range(_ func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {}
|
||||||
|
func (ms *MessageState) Set(_ protoreflect.FieldDescriptor, _ protoreflect.Value) {}
|
||||||
|
func (ms *MessageState) SetUnknown(_ protoreflect.RawFields) {}
|
||||||
|
func (ms *MessageState) Type() protoreflect.MessageType { return nil }
|
||||||
|
func (ms *MessageState) WhichOneof(_ protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
68
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/proto/stub.go
generated
vendored
Normal file
68
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/proto/stub.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// This is a simple stub for github.com/golang/protobuf/proto, strictly for use in testing.
|
||||||
|
|
||||||
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
|
// Source: github.com/golang/protobuf/proto (exports: Message; functions: Marshal,Unmarshal,ProtoPackageIsVersion4)
|
||||||
|
|
||||||
|
// Package proto is a stub of github.com/golang/protobuf/proto.
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Marshal(_ interface{}) ([]byte, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message = protoreflect.ProtoMessage
|
||||||
|
|
||||||
|
var ProtoPackageIsVersion4 bool = false
|
||||||
|
|
||||||
|
func Unmarshal(_ []byte, _ interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MarshalOptions struct {
|
||||||
|
AllowPartial bool
|
||||||
|
Deterministic bool
|
||||||
|
UseCachedSize bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MarshalOptions) Marshal(_ Message) ([]byte, error) { return nil, nil }
|
||||||
|
func (_ MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) { return nil, nil }
|
||||||
|
func (_ MarshalOptions) MarshalState(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
|
||||||
|
return protoiface.MarshalOutput{nil}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnmarshalOptions struct {
|
||||||
|
// Merge merges the input into the destination message.
|
||||||
|
// The default behavior is to always reset the message before unmarshaling,
|
||||||
|
// unless Merge is specified.
|
||||||
|
Merge bool
|
||||||
|
|
||||||
|
// AllowPartial accepts input for messages that will result in missing
|
||||||
|
// required fields. If AllowPartial is false (the default), Unmarshal will
|
||||||
|
// return an error if there are any missing required fields.
|
||||||
|
AllowPartial bool
|
||||||
|
|
||||||
|
// If DiscardUnknown is set, unknown fields are ignored.
|
||||||
|
DiscardUnknown bool
|
||||||
|
|
||||||
|
// Resolver is used for looking up types when unmarshaling extension fields.
|
||||||
|
// If nil, this defaults to using protoregistry.GlobalTypes.
|
||||||
|
Resolver interface {
|
||||||
|
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||||
|
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clone(_ Message) Message {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Merge(_, _ Message) {}
|
||||||
683
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/reflect/protoreflect/stub.go
generated
vendored
Normal file
683
go/ql/test/query-tests/Security/CWE-312/vendor/google.golang.org/protobuf/reflect/protoreflect/stub.go
generated
vendored
Normal file
@@ -0,0 +1,683 @@
|
|||||||
|
// Code generated by depstubber. DO NOT EDIT.
|
||||||
|
// This is a simple stub for google.golang.org/protobuf/reflect/protoreflect, strictly for use in testing.
|
||||||
|
|
||||||
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
|
// Source: google.golang.org/protobuf/reflect/protoreflect (exports: EnumDescriptor,EnumType,EnumNumber,Message,FileDescriptor; functions: )
|
||||||
|
|
||||||
|
// Package protoreflect is a stub of google.golang.org/protobuf/reflect/protoreflect, generated by depstubber.
|
||||||
|
package protoreflect
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
type Cardinality int8
|
||||||
|
|
||||||
|
func (_ Cardinality) GoString() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Cardinality) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Cardinality) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type Descriptor interface {
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type Enum interface {
|
||||||
|
Descriptor() EnumDescriptor
|
||||||
|
Number() EnumNumber
|
||||||
|
Type() EnumType
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumDescriptor interface {
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ EnumDescriptor)
|
||||||
|
ReservedNames() Names
|
||||||
|
ReservedRanges() EnumRanges
|
||||||
|
Syntax() Syntax
|
||||||
|
Values() EnumValueDescriptors
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumDescriptors interface {
|
||||||
|
ByName(_ Name) EnumDescriptor
|
||||||
|
Get(_ int) EnumDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumNumber int32
|
||||||
|
|
||||||
|
type EnumRanges interface {
|
||||||
|
Get(_ int) [2]EnumNumber
|
||||||
|
Has(_ EnumNumber) bool
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumType interface {
|
||||||
|
Descriptor() EnumDescriptor
|
||||||
|
New(_ EnumNumber) Enum
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumValueDescriptor interface {
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Name() Name
|
||||||
|
Number() EnumNumber
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ EnumValueDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnumValueDescriptors interface {
|
||||||
|
ByName(_ Name) EnumValueDescriptor
|
||||||
|
ByNumber(_ EnumNumber) EnumValueDescriptor
|
||||||
|
Get(_ int) EnumValueDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExtensionDescriptors interface {
|
||||||
|
ByName(_ Name) FieldDescriptor
|
||||||
|
Get(_ int) FieldDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExtensionType interface {
|
||||||
|
InterfaceOf(_ Value) interface{}
|
||||||
|
IsValidInterface(_ interface{}) bool
|
||||||
|
IsValidValue(_ Value) bool
|
||||||
|
New() Value
|
||||||
|
TypeDescriptor() ExtensionTypeDescriptor
|
||||||
|
ValueOf(_ interface{}) Value
|
||||||
|
Zero() Value
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExtensionTypeDescriptor interface {
|
||||||
|
Cardinality() Cardinality
|
||||||
|
ContainingMessage() MessageDescriptor
|
||||||
|
ContainingOneof() OneofDescriptor
|
||||||
|
Default() Value
|
||||||
|
DefaultEnumValue() EnumValueDescriptor
|
||||||
|
Descriptor() FieldDescriptor
|
||||||
|
Enum() EnumDescriptor
|
||||||
|
FullName() FullName
|
||||||
|
HasDefault() bool
|
||||||
|
HasJSONName() bool
|
||||||
|
HasOptionalKeyword() bool
|
||||||
|
HasPresence() bool
|
||||||
|
Index() int
|
||||||
|
IsExtension() bool
|
||||||
|
IsList() bool
|
||||||
|
IsMap() bool
|
||||||
|
IsPacked() bool
|
||||||
|
IsPlaceholder() bool
|
||||||
|
IsWeak() bool
|
||||||
|
JSONName() string
|
||||||
|
Kind() Kind
|
||||||
|
MapKey() FieldDescriptor
|
||||||
|
MapValue() FieldDescriptor
|
||||||
|
Message() MessageDescriptor
|
||||||
|
Name() Name
|
||||||
|
Number() interface{}
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ FieldDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
Type() ExtensionType
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldDescriptor interface {
|
||||||
|
Cardinality() Cardinality
|
||||||
|
ContainingMessage() MessageDescriptor
|
||||||
|
ContainingOneof() OneofDescriptor
|
||||||
|
Default() Value
|
||||||
|
DefaultEnumValue() EnumValueDescriptor
|
||||||
|
Enum() EnumDescriptor
|
||||||
|
FullName() FullName
|
||||||
|
HasDefault() bool
|
||||||
|
HasJSONName() bool
|
||||||
|
HasOptionalKeyword() bool
|
||||||
|
HasPresence() bool
|
||||||
|
Index() int
|
||||||
|
IsExtension() bool
|
||||||
|
IsList() bool
|
||||||
|
IsMap() bool
|
||||||
|
IsPacked() bool
|
||||||
|
IsPlaceholder() bool
|
||||||
|
IsWeak() bool
|
||||||
|
JSONName() string
|
||||||
|
Kind() Kind
|
||||||
|
MapKey() FieldDescriptor
|
||||||
|
MapValue() FieldDescriptor
|
||||||
|
Message() MessageDescriptor
|
||||||
|
Name() Name
|
||||||
|
Number() interface{}
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ FieldDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldDescriptors interface {
|
||||||
|
ByJSONName(_ string) FieldDescriptor
|
||||||
|
ByName(_ Name) FieldDescriptor
|
||||||
|
ByNumber(_ interface{}) FieldDescriptor
|
||||||
|
Get(_ int) FieldDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldNumber int32
|
||||||
|
|
||||||
|
type FieldNumbers interface {
|
||||||
|
Get(_ int) interface{}
|
||||||
|
Has(_ interface{}) bool
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldRanges interface {
|
||||||
|
Get(_ int) [2]interface{}
|
||||||
|
Has(_ interface{}) bool
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileDescriptor interface {
|
||||||
|
Enums() EnumDescriptors
|
||||||
|
Extensions() ExtensionDescriptors
|
||||||
|
FullName() FullName
|
||||||
|
Imports() FileImports
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Messages() MessageDescriptors
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Package() FullName
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
Path() string
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ FileDescriptor)
|
||||||
|
Services() ServiceDescriptors
|
||||||
|
SourceLocations() SourceLocations
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileImport struct {
|
||||||
|
FileDescriptor FileDescriptor
|
||||||
|
IsPublic bool
|
||||||
|
IsWeak bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Enums() EnumDescriptors {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Extensions() ExtensionDescriptors {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) FullName() FullName {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Imports() FileImports {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Index() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) IsPlaceholder() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Messages() MessageDescriptors {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Name() Name {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Options() ProtoMessage {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Package() FullName {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Parent() Descriptor {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) ParentFile() FileDescriptor {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Path() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) ProtoInternal(_ interface{}) {}
|
||||||
|
|
||||||
|
func (_ FileImport) ProtoType(_ FileDescriptor) {}
|
||||||
|
|
||||||
|
func (_ FileImport) Services() ServiceDescriptors {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) SourceLocations() SourceLocations {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FileImport) Syntax() Syntax {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileImports interface {
|
||||||
|
Get(_ int) FileImport
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FullName string
|
||||||
|
|
||||||
|
func (_ FullName) Append(_ Name) FullName {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FullName) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FullName) Name() Name {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ FullName) Parent() FullName {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type Kind int8
|
||||||
|
|
||||||
|
func (_ Kind) GoString() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Kind) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Kind) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type List interface {
|
||||||
|
Append(_ Value)
|
||||||
|
AppendMutable() Value
|
||||||
|
Get(_ int) Value
|
||||||
|
IsValid() bool
|
||||||
|
Len() int
|
||||||
|
NewElement() Value
|
||||||
|
Set(_ int, _ Value)
|
||||||
|
Truncate(_ int)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Map interface {
|
||||||
|
Clear(_ MapKey)
|
||||||
|
Get(_ MapKey) Value
|
||||||
|
Has(_ MapKey) bool
|
||||||
|
IsValid() bool
|
||||||
|
Len() int
|
||||||
|
Mutable(_ MapKey) Value
|
||||||
|
NewValue() Value
|
||||||
|
Range(_ func(MapKey, Value) bool)
|
||||||
|
Set(_ MapKey, _ Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MapKey struct {
|
||||||
|
DoNotCompare interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) Bool() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) Int() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) Interface() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) Uint() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ MapKey) Value() Value {
|
||||||
|
return Value{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message interface {
|
||||||
|
Clear(_ FieldDescriptor)
|
||||||
|
Descriptor() MessageDescriptor
|
||||||
|
Get(_ FieldDescriptor) Value
|
||||||
|
GetUnknown() RawFields
|
||||||
|
Has(_ FieldDescriptor) bool
|
||||||
|
Interface() ProtoMessage
|
||||||
|
IsValid() bool
|
||||||
|
Mutable(_ FieldDescriptor) Value
|
||||||
|
New() Message
|
||||||
|
NewField(_ FieldDescriptor) Value
|
||||||
|
ProtoMethods() *struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags uint64
|
||||||
|
Size func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message Message
|
||||||
|
Flags byte
|
||||||
|
}) struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Size int
|
||||||
|
}
|
||||||
|
Marshal func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message Message
|
||||||
|
Buf []byte
|
||||||
|
Flags byte
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Buf []byte
|
||||||
|
}, error)
|
||||||
|
Unmarshal func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message Message
|
||||||
|
Buf []byte
|
||||||
|
Flags byte
|
||||||
|
Resolver interface {
|
||||||
|
FindExtensionByName(_ FullName) (ExtensionType, error)
|
||||||
|
FindExtensionByNumber(_ FullName, _ interface{}) (ExtensionType, error)
|
||||||
|
}
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags byte
|
||||||
|
}, error)
|
||||||
|
Merge func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Source Message
|
||||||
|
Destination Message
|
||||||
|
}) struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Flags byte
|
||||||
|
}
|
||||||
|
CheckInitialized func(struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
Message Message
|
||||||
|
}) (struct {
|
||||||
|
NoUnkeyedLiterals interface{}
|
||||||
|
}, error)
|
||||||
|
}
|
||||||
|
Range(_ func(FieldDescriptor, Value) bool)
|
||||||
|
Set(_ FieldDescriptor, _ Value)
|
||||||
|
SetUnknown(_ RawFields)
|
||||||
|
Type() MessageType
|
||||||
|
WhichOneof(_ OneofDescriptor) FieldDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageDescriptor interface {
|
||||||
|
Enums() EnumDescriptors
|
||||||
|
ExtensionRangeOptions(_ int) ProtoMessage
|
||||||
|
ExtensionRanges() FieldRanges
|
||||||
|
Extensions() ExtensionDescriptors
|
||||||
|
Fields() FieldDescriptors
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsMapEntry() bool
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Messages() MessageDescriptors
|
||||||
|
Name() Name
|
||||||
|
Oneofs() OneofDescriptors
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ MessageDescriptor)
|
||||||
|
RequiredNumbers() FieldNumbers
|
||||||
|
ReservedNames() Names
|
||||||
|
ReservedRanges() FieldRanges
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageDescriptors interface {
|
||||||
|
ByName(_ Name) MessageDescriptor
|
||||||
|
Get(_ int) MessageDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageType interface {
|
||||||
|
Descriptor() MessageDescriptor
|
||||||
|
New() Message
|
||||||
|
Zero() Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type MethodDescriptor interface {
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
Input() MessageDescriptor
|
||||||
|
IsPlaceholder() bool
|
||||||
|
IsStreamingClient() bool
|
||||||
|
IsStreamingServer() bool
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Output() MessageDescriptor
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ MethodDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type MethodDescriptors interface {
|
||||||
|
ByName(_ Name) MethodDescriptor
|
||||||
|
Get(_ int) MethodDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Name string
|
||||||
|
|
||||||
|
func (_ Name) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type Names interface {
|
||||||
|
Get(_ int) Name
|
||||||
|
Has(_ Name) bool
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneofDescriptor interface {
|
||||||
|
Fields() FieldDescriptors
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
IsSynthetic() bool
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ OneofDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneofDescriptors interface {
|
||||||
|
ByName(_ Name) OneofDescriptor
|
||||||
|
Get(_ int) OneofDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProtoMessage interface {
|
||||||
|
ProtoReflect() Message
|
||||||
|
}
|
||||||
|
|
||||||
|
type RawFields []byte
|
||||||
|
|
||||||
|
func (_ RawFields) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceDescriptor interface {
|
||||||
|
FullName() FullName
|
||||||
|
Index() int
|
||||||
|
IsPlaceholder() bool
|
||||||
|
Methods() MethodDescriptors
|
||||||
|
Name() Name
|
||||||
|
Options() ProtoMessage
|
||||||
|
Parent() Descriptor
|
||||||
|
ParentFile() FileDescriptor
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
ProtoType(_ ServiceDescriptor)
|
||||||
|
Syntax() Syntax
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceDescriptors interface {
|
||||||
|
ByName(_ Name) ServiceDescriptor
|
||||||
|
Get(_ int) ServiceDescriptor
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type SourceLocation struct {
|
||||||
|
Path SourcePath
|
||||||
|
StartLine int
|
||||||
|
StartColumn int
|
||||||
|
EndLine int
|
||||||
|
EndColumn int
|
||||||
|
LeadingDetachedComments []string
|
||||||
|
LeadingComments string
|
||||||
|
TrailingComments string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SourceLocations interface {
|
||||||
|
Get(_ int) SourceLocation
|
||||||
|
Len() int
|
||||||
|
ProtoInternal(_ interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type SourcePath []int32
|
||||||
|
|
||||||
|
type Syntax int8
|
||||||
|
|
||||||
|
func (_ Syntax) GoString() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Syntax) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Syntax) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type Value struct {
|
||||||
|
DoNotCompare interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Bool() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Bytes() []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Enum() EnumNumber {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Float() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Int() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Interface() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) IsValid() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) List() List {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Map() Map {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) MapKey() MapKey {
|
||||||
|
return MapKey{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Message() Message {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ Value) Uint() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user