Compare commits

..

9 Commits

Author SHA1 Message Date
Asger F
47d299e93b Add parse diagnostics support via getSyntacticDiagnostics API
Fetch syntactic diagnostics from the tsgo API after parsing each file.
Only genuine parse errors (diagnostic codes 1000-1999) are included;
higher codes like 2880 (import assertion deprecation) are filtered out
since they don't indicate actual parse failures.

The Java extractor uses parseDiagnostics to report syntax errors and
skip full AST extraction for broken files, matching TS5 behavior.

TRAP test results: 495/495 passing (100%)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 15:27:47 +02:00
Asger F
fbaf648e4f Fix nodeFlags: bit 6 is ExportContext, not GlobalAugmentation
TS7 binary AST uses bit 6 for ExportContext (set on all nodes inside
`declare module` contexts), not GlobalAugmentation as previously assumed.
GlobalAugmentation is not a flag in the TS7 binary format at all.

Fix by using a synthetic flag bit (1<<30) for GlobalAugmentation that the
converter sets on `declare global {}` nodes based on the name identifier
being "global". This lets the Java extractor correctly distinguish
`declare global {}` from regular namespace declarations.

Also corrects the flag shift: ExportContext=64 (bit 6), ContainsThis=128
(bit 7), etc., matching the actual TS7 binary layout.

TRAP test results: 494/495 passing (99.8%)
Remaining: badimport.ts (TS7 binary API doesn't report parse diagnostics)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 15:22:58 +02:00
Asger F
637ce99e44 TypeScript Go extractor: metadata fixes, NestedNamespace inference, and scanner improvements
- Fix TS7 nodeFlags: remove Synthesized (shifted in TS7), add GlobalAugmentation=64,
  correct OptionalChain=32, Namespace=16, shift subsequent flags
- Add 33 missing operator/punctuation token kinds to syntaxKinds metadata
- Infer NestedNamespace flag for dotted namespace declarations (TS7 binary
  doesn't set it, but Java extractor needs it)
- Fix shebang handling: emit ShebangTrivia (kind 6) instead of SingleLineCommentTrivia
- Fix token kinds for regex/template rescans to match TS5 pre-rescan behavior
  (SlashToken for regexes, CloseBraceToken for template continuations)
- Fix augmentPos to correctly skip comments (matching TS5's trivia-skipping regex)
- Resolve native tsgo binary from npm wrapper to avoid Node.js dependency
- Update project-layout glob for worktree support

TRAP test results: 493/495 passing (99.6%)
Remaining: badimport.ts (missing diagnostics), externalmodule.ts (structural diff)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 15:11:48 +02:00
Asger F
bd9d6b1962 Add Go TypeScript parser wrapper integration to Java extractor
Wire the Go-based TypeScript parser wrapper as an alternative to the
Node.js wrapper. Enabled via SEMMLE_TYPESCRIPT_USE_GO_PARSER=true.

When enabled:
- Skips Node.js installation verification
- Launches the Go binary directly (no Node.js required)
- Uses the same newline-delimited JSON protocol over stdin/stdout
- Go binary path configurable via SEMMLE_TYPESCRIPT_GO_PARSER_WRAPPER
- tsgo binary path passed through via SEMMLE_TYPESCRIPT_TSGO_BINARY

The Go wrapper implements all protocol commands: get-metadata, parse,
prepare-files, reset, and quit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 15:44:55 +02:00
Asger F
bd5e4761bd Fix broader validation: 52/57 tests pass
Key fixes:
- UTF-16 offset conversion for positions (buildOffsetTables, byteToUTF16, utf16ToByte)
- Unicode identifier scanning (support ID_Start/ID_Continue categories)
- Filter zero-width synthetic modifiers from nested namespaces
- Add ImportAttributes to childprops (elements property)
- Emit isTypeOf:false for ImportType nodes
- Always emit empty statements array for SourceFile
- Emit empty arrays for remaining array properties when no children
- Non-greedy > scanning (always single GreaterThanToken)
- Ignore parseDiagnostics in structural comparison

Remaining 5 failures are binary/UTF-16-BOM encoded files (not real TypeScript).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 15:19:49 +02:00
Asger F
93deb33a2a Fix validation script to tolerate expected TS7 kind/flags diffsTS5
The shell validation script now uses a structural comparison that
ignores expected numeric differences in kind/flags/token/operator
values between TS5 and TS7. Only truly structural diffs cause failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 14:54:19 +02:00
Asger F
f3b27a56b1 TypeScript-Go wrapper: binary AST decoder, JSON converter, and tokenizer
Implement the core components for translating tsgo's binary AST format
into the JSON format expected by the Java extractor:

- decoder.go: Binary AST format parser with random-access node accessors
  (kind, pos, end, flags, children, strings, extended data)
- converter.go: Walks decoded AST and produces JSON matching Node.js
  wrapper output (augmented , , , ,
  isTypeOnly, HeritageClause token, TypeOperator operator)
- childprops.go: Maps ~100 SyntaxKind names to ordered child property
  name lists for correct bitmask-to-property assignment
- scanner.go: TypeScript tokenizer producing  array with rescan
  support for regex, template, and greater-than disambiguation

Update metadata.go with correct TS7 SyntaxKind iota values and export
metadata functions. Wire decoder+converter through TsgoParser.Parse().

Validation test passes: all 421 diffs are expected TS5-vs-TS7 numeric
kind/flags/token/operator value differences. Zero structural diffs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 14:36:00 +02:00
Asger F
37852aa1d3 JS: Fix validation script to use stdin protocol with timeouts
The script was calling wrappers in single-file CLI mode, but neither
wrapper supports that (they read commands from stdin). Now sends
parse + quit commands via stdin and uses `timeout` to avoid hangs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 13:46:39 +02:00
Asger F
78b1651596 JS: Add Go-based TypeScript parser wrapper scaffolding
Add initial scaffolding for a Go process that will replace the Node.js
TypeScript parser wrapper, preparing for TypeScript 7's Go-based compiler.

The Go wrapper implements the same stdin/stdout line-delimited JSON
protocol as the existing Node.js wrapper (lib/typescript/src/main.ts),
making it a drop-in replacement from the Java extractor's perspective.

Key components:
- Protocol handler matching the Node.js wrapper's command set
  (get-metadata, prepare-files, parse, reset, quit)
- Parser backend interface with tsgo subprocess implementation
  using the tsgo --api --async JSON-RPC mode (LSP Content-Length framing)
- AST property whitelist matching the ~90 properties from the Node.js wrapper
- Static TS7 SyntaxKind and NodeFlags metadata mappings
- Validation framework for comparing JSON output between wrappers
- Integration tests demonstrating successful tsgo API communication:
  initialize, updateSnapshot (project opening), getSourceFile

Key finding: the tsgo API returns binary-encoded ASTs (not JSON),
requiring a decoder for the custom flat-node-array format. See
microsoft/typescript-go/internal/api/encoder/ for the format spec.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 13:11:17 +02:00
1512 changed files with 110086 additions and 196818 deletions

View File

@@ -70,7 +70,7 @@ jobs:
SHORTNAME=`basename $DATABASE`
python misc/scripts/models-as-data/generate_mad.py --language java --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
mkdir -p $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/modelgenerator/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
cd ..
}

View File

@@ -5,7 +5,7 @@ on:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
- "misc/scripts/models-as-data/*.py"
- "misc/scripts/models-as-data/bulk_generate_mad.py"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml

442
Cargo.lock generated
View File

@@ -140,26 +140,6 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bindgen"
version = "0.72.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
dependencies = [
"bitflags 2.9.4",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"log 0.4.28",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash 2.1.1",
"shlex",
"syn",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -260,9 +240,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.61"
version = "1.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -270,15 +250,6 @@ dependencies = [
"shlex",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.3"
@@ -357,7 +328,7 @@ dependencies = [
"chalk-derive 0.103.0",
"chalk-ir 0.103.0",
"ena",
"indexmap 2.14.0",
"indexmap 2.11.4",
"itertools 0.12.1",
"petgraph",
"rustc-hash 1.1.0",
@@ -378,17 +349,6 @@ dependencies = [
"windows-link 0.2.0",
]
[[package]]
name = "clang-sys"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "4.5.48"
@@ -456,7 +416,6 @@ dependencies = [
"tree-sitter",
"tree-sitter-json",
"tree-sitter-ql",
"yeast",
"zstd",
]
@@ -478,25 +437,6 @@ dependencies = [
"tree-sitter-ruby",
]
[[package]]
name = "codeql-extractor-unified"
version = "0.1.0"
dependencies = [
"clap",
"codeql-extractor",
"encoding",
"lazy_static",
"rayon",
"regex",
"serde_json",
"tracing",
"tracing-subscriber",
"tree-sitter",
"tree-sitter-embedded-template",
"tree-sitter-swift",
"yeast",
]
[[package]]
name = "codeql-rust"
version = "0.1.0"
@@ -545,15 +485,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "convert_case"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@@ -807,12 +738,6 @@ dependencies = [
"typeid",
]
[[package]]
name = "fastrand"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "figment"
version = "0.10.19"
@@ -829,9 +754,9 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
[[package]]
name = "fixedbitset"
@@ -861,12 +786,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "form_urlencoded"
version = "1.2.2"
@@ -951,26 +870,9 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.1.5",
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.2.0",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "hashlink"
version = "0.10.0"
@@ -1157,25 +1059,16 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.14.0"
version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
"hashbrown 0.17.1",
"hashbrown 0.15.5",
"serde",
"serde_core",
]
[[package]]
name = "indoc"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
dependencies = [
"rustversion",
]
[[package]]
name = "inlinable_string"
version = "0.1.15"
@@ -1305,16 +1198,6 @@ version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libloading"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
"cfg-if",
"windows-link 0.2.0",
]
[[package]]
name = "line-index"
version = "0.1.2"
@@ -1380,12 +1263,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
@@ -1432,16 +1309,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "notify"
version = "8.2.0"
@@ -1569,12 +1436,6 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "pathdiff"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "pear"
version = "0.2.9"
@@ -1630,36 +1491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
"indexmap 2.14.0",
]
[[package]]
name = "phf"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
dependencies = [
"phf_shared",
"serde",
]
[[package]]
name = "phf_generator"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
dependencies = [
"fastrand",
"phf_shared",
]
[[package]]
name = "phf_shared"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
dependencies = [
"siphasher",
"indexmap 2.11.4",
]
[[package]]
@@ -1704,25 +1536,6 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro-crate"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
dependencies = [
"toml_edit 0.25.11+spec-1.1.0",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
@@ -1854,7 +1667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e876bb2c3e52a8d4e6684526a2d4e81f9d028b939ee4dc5dc775fe10deb44d59"
dependencies = [
"dashmap",
"indexmap 2.14.0",
"indexmap 2.11.4",
"la-arena",
"ra_ap_cfg",
"ra_ap_intern",
@@ -1896,7 +1709,7 @@ checksum = "ebffdc134eccabc17209d7760cfff7fd12ed18ab6e21188c5e084b97aa38504c"
dependencies = [
"arrayvec",
"either",
"indexmap 2.14.0",
"indexmap 2.11.4",
"itertools 0.14.0",
"ra_ap_base_db",
"ra_ap_cfg",
@@ -1926,7 +1739,7 @@ dependencies = [
"drop_bomb",
"either",
"fst",
"indexmap 2.14.0",
"indexmap 2.11.4",
"itertools 0.14.0",
"la-arena",
"ra-ap-rustc_abi",
@@ -1995,7 +1808,7 @@ dependencies = [
"cov-mark",
"either",
"ena",
"indexmap 2.14.0",
"indexmap 2.11.4",
"itertools 0.14.0",
"la-arena",
"oorandom",
@@ -2033,7 +1846,7 @@ dependencies = [
"crossbeam-channel",
"either",
"fst",
"indexmap 2.14.0",
"indexmap 2.11.4",
"itertools 0.14.0",
"line-index",
"memchr",
@@ -2135,7 +1948,7 @@ version = "0.0.301"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45db9e2df587d56f0738afa89fb2c100ff7c1e9cbe49e07f6a8b62342832211b"
dependencies = [
"indexmap 2.14.0",
"indexmap 2.11.4",
"ra_ap_intern",
"ra_ap_paths",
"ra_ap_span",
@@ -2294,7 +2107,7 @@ checksum = "6c174d6b9b7a7f54687df7e00c3e75ed6f082a7943a9afb1d54f33c0c12773de"
dependencies = [
"crossbeam-channel",
"fst",
"indexmap 2.14.0",
"indexmap 2.11.4",
"nohash-hasher",
"ra_ap_paths",
"ra_ap_stdx",
@@ -2426,15 +2239,6 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "relative-path"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca40a312222d8ba74837cb474edef44b37f561da5f773981007a10bbaa992b0"
dependencies = [
"serde",
]
[[package]]
name = "rowan"
version = "0.15.15"
@@ -2448,57 +2252,6 @@ dependencies = [
"text-size",
]
[[package]]
name = "rquickjs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a135375fbac5ba723bb6a48f432a72f81539cedde422f0121a86c7c4e96d8e0d"
dependencies = [
"rquickjs-core",
"rquickjs-macro",
]
[[package]]
name = "rquickjs-core"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bccb7121a123865c8ace4dea42e7ed84d78b90cbaf4ca32c59849d8d210c9672"
dependencies = [
"hashbrown 0.16.1",
"phf",
"relative-path",
"rquickjs-sys",
]
[[package]]
name = "rquickjs-macro"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89f93602cc3112c7f30bf5f29e722784232138692c7df4c52ebbac7e035d900d"
dependencies = [
"convert_case",
"fnv",
"ident_case",
"indexmap 2.14.0",
"phf_generator",
"phf_shared",
"proc-macro-crate",
"proc-macro2",
"quote",
"rquickjs-core",
"syn",
]
[[package]]
name = "rquickjs-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57b1b6528590d4d65dc86b5159eae2d0219709546644c66408b2441696d1d725"
dependencies = [
"bindgen",
"cc",
]
[[package]]
name = "rust-extractor-macros"
version = "0.1.0"
@@ -2564,7 +2317,7 @@ dependencies = [
"crossbeam-utils",
"hashbrown 0.15.5",
"hashlink",
"indexmap 2.14.0",
"indexmap 2.11.4",
"intrusive-collections",
"papaya",
"parking_lot",
@@ -2653,12 +2406,11 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.28"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
dependencies = [
"serde",
"serde_core",
]
[[package]]
@@ -2718,7 +2470,7 @@ version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"indexmap 2.14.0",
"indexmap 2.11.4",
"itoa",
"memchr",
"ryu",
@@ -2754,7 +2506,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.14.0",
"indexmap 2.11.4",
"schemars 0.9.0",
"schemars 1.0.4",
"serde",
@@ -2782,7 +2534,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.14.0",
"indexmap 2.11.4",
"itoa",
"ryu",
"serde",
@@ -2804,18 +2556,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "siphasher"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
[[package]]
name = "smallbitvec"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b0e903ee191d8f7a8fbf0d712c3a1699d19e04ceba5ad1eb673053c7d938a09"
[[package]]
name = "smallvec"
version = "1.15.1"
@@ -2892,18 +2632,18 @@ checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
[[package]]
name = "thiserror"
version = "2.0.18"
version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
version = "2.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
dependencies = [
"proc-macro2",
"quote",
@@ -2968,7 +2708,7 @@ dependencies = [
"serde",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_edit 0.22.27",
"toml_edit",
]
[[package]]
@@ -2977,13 +2717,13 @@ version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
dependencies = [
"indexmap 2.14.0",
"indexmap 2.11.4",
"serde_core",
"serde_spanned 1.0.2",
"toml_datetime 0.7.2",
"toml_parser",
"toml_writer",
"winnow 0.7.13",
"winnow",
]
[[package]]
@@ -3004,48 +2744,27 @@ dependencies = [
"serde_core",
]
[[package]]
name = "toml_datetime"
version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap 2.14.0",
"indexmap 2.11.4",
"serde",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_write",
"winnow 0.7.13",
]
[[package]]
name = "toml_edit"
version = "0.25.11+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b"
dependencies = [
"indexmap 2.14.0",
"toml_datetime 1.1.1+spec-1.1.0",
"toml_parser",
"winnow 1.0.2",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.1.2+spec-1.1.0"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
dependencies = [
"winnow 1.0.2",
"winnow",
]
[[package]]
@@ -3060,12 +2779,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
[[package]]
name = "topological-sort"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
[[package]]
name = "tracing"
version = "0.1.41"
@@ -3140,9 +2853,9 @@ dependencies = [
[[package]]
name = "tree-sitter"
version = "0.26.8"
version = "0.25.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887bd495d0582c5e3e0d8ece2233666169fa56a9644d172fc22ad179ab2d0538"
checksum = "ccd2a058a86cfece0bf96f7cce1021efef9c8ed0e892ab74639173e5ed7a34fa"
dependencies = [
"cc",
"regex",
@@ -3162,30 +2875,6 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-generate"
version = "0.26.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fb2e1bdb1d5f9d23cd5fa68cf98b3bedbd223c92a2edd60bbcf30bcf7180a5"
dependencies = [
"bitflags 2.9.4",
"dunce",
"indexmap 2.14.0",
"indoc",
"log 0.4.28",
"pathdiff",
"regex",
"regex-syntax",
"rquickjs",
"rustc-hash 2.1.1",
"semver",
"serde",
"serde_json",
"smallbitvec",
"thiserror",
"topological-sort",
]
[[package]]
name = "tree-sitter-json"
version = "0.24.8"
@@ -3202,16 +2891,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8"
[[package]]
name = "tree-sitter-python"
version = "0.23.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d065aaa27f3aaceaf60c1f0e0ac09e1cb9eb8ed28e7bcdaa52129cffc7f4b04"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-ql"
version = "0.23.1"
@@ -3232,15 +2911,6 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-swift"
version = "0.7.2"
dependencies = [
"cc",
"tree-sitter-generate",
"tree-sitter-language",
]
[[package]]
name = "triomphe"
version = "0.1.14"
@@ -3290,12 +2960,6 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-segmentation"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]]
name = "unicode-xid"
version = "0.2.6"
@@ -3685,15 +3349,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.45.1"
@@ -3712,29 +3367,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yeast"
version = "0.1.0"
dependencies = [
"clap",
"serde",
"serde_json",
"serde_yaml",
"tree-sitter",
"tree-sitter-python",
"tree-sitter-ruby",
"yeast-macros",
]
[[package]]
name = "yeast-macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "yoke"
version = "0.8.0"

View File

@@ -4,11 +4,7 @@
resolver = "2"
members = [
"shared/tree-sitter-extractor",
"shared/yeast",
"shared/yeast-macros",
"ruby/extractor",
"unified/extractor",
"unified/extractor/tree-sitter-swift",
"rust/extractor",
"rust/extractor/macros",
"rust/ast-generator",

View File

@@ -102,7 +102,6 @@ use_repo(
tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.100",
"vendor_ts__argfile-0.2.1",
"vendor_ts__cc-1.2.61",
"vendor_ts__chalk-ir-0.104.0",
"vendor_ts__chrono-0.4.42",
"vendor_ts__clap-4.5.48",
@@ -142,18 +141,14 @@ use_repo(
"vendor_ts__serde-1.0.228",
"vendor_ts__serde_json-1.0.145",
"vendor_ts__serde_with-3.14.1",
"vendor_ts__serde_yaml-0.9.34-deprecated",
"vendor_ts__syn-2.0.106",
"vendor_ts__toml-0.9.7",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.20",
"vendor_ts__tree-sitter-0.26.8",
"vendor_ts__tree-sitter-0.25.9",
"vendor_ts__tree-sitter-embedded-template-0.25.0",
"vendor_ts__tree-sitter-generate-0.26.8",
"vendor_ts__tree-sitter-json-0.24.8",
"vendor_ts__tree-sitter-language-0.1.5",
"vendor_ts__tree-sitter-python-0.23.6",
"vendor_ts__tree-sitter-ql-0.23.1",
"vendor_ts__tree-sitter-ruby-0.23.1",
"vendor_ts__triomphe-0.1.14",

View File

@@ -1,17 +1,3 @@
## 0.4.35
No user-facing changes.
## 0.4.34
### Minor Analysis Improvements
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.
## 0.4.33
No user-facing changes.
## 0.4.32
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Altered 2 patterns in the `poisonable_steps` modelling. Extra sinks are detected in the following cases: scripts executed via python modules and `go run` in directories are detected as potential mechanisms of injection. For the go execution pattern, the pattern is updated to now ignore flags that occur between go and the specific command. This change may lead to more results being detected by the following queries: `actions/untrusted-checkout/high`, `actions/untrusted-checkout/critical`, `actions/untrusted-checkout-toctou/high`, `actions/untrusted-checkout-toctou/critical`, `actions/cache-poisoning/poisonable-step`, `actions/cache-poisoning/direct-cache` and `actions/artifact-poisoning/path-traversal`.

View File

@@ -1,3 +0,0 @@
## 0.4.33
No user-facing changes.

View File

@@ -1,5 +0,0 @@
## 0.4.34
### Minor Analysis Improvements
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.

View File

@@ -1,3 +0,0 @@
## 0.4.35
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.35
lastReleaseVersion: 0.4.32

View File

@@ -70,7 +70,7 @@ extensions:
- ["(source|sh|bash|zsh|fish)\\s+([^\\s]+)\\b", 2]
- ["(node)\\s+([^\\s]+)(\\.js|\\.ts)\\b", 2]
- ["(python[\\d\\.]*)\\s+([^\\s]+)\\.py\\b", 2]
- ["(python[\\d\\.]*)\\s+-m\\s+([A-Za-z_][\\w\\.]*)\\b", 2] # eg: pythonX -m anything(dir or file)
- ["(ruby)\\s+([^\\s]+)\\.rb\\b", 2]
- ["(go)\\s+(generate|run)(?:\\s+-[^\\s]+)*\\s+([^\\s]+)", 3]
- ["(go)\\s+(generate|run)\\s+([^\\s]+)\\.go\\b", 3]
- ["(dotnet)\\s+([^\\s]+)\\.csproj\\b", 2]

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: actionsSinkModel
data:
- ["docker/build-push-action", "*", "input.context", "code-injection", "manual"]

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: actionsSinkModel
data:
- ["step-security/harden-runner", "*", "input.allowed-endpoints", "command-injection", "manual"]

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.36-dev
version: 0.4.33-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,21 +1,3 @@
## 0.6.27
No user-facing changes.
## 0.6.26
### Major Analysis Improvements
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
## 0.6.25
No user-facing changes.
## 0.6.24
No user-facing changes.

View File

@@ -26,23 +26,10 @@ string permissionsForJob(Job job) {
"{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}"
}
predicate jobHasPermissions(Job job) {
exists(job.getPermissions())
or
exists(job.getEnclosingWorkflow().getPermissions())
or
// The workflow is reusable and cannot be triggered in any other way; check callers
exists(ReusableWorkflow r | r = job.getEnclosingWorkflow() |
not exists(Event e | e = r.getOn().getAnEvent() | e.getName() != "workflow_call") and
forall(Job caller | caller = job.getEnclosingWorkflow().(ReusableWorkflow).getACaller() |
jobHasPermissions(caller)
)
)
}
from Job job, string permissions
where
not jobHasPermissions(job) and
not exists(job.getPermissions()) and
not exists(job.getEnclosingWorkflow().getPermissions()) and
// exists a trigger event that is not a workflow_call
exists(Event e |
e = job.getATriggerEvent() and

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -1,5 +1,5 @@
/**
* @name Checkout of untrusted code in privileged context without privileged context use
* @name Checkout of untrusted code in trusted context
* @description Privileged workflows have read/write access to the base repository and access to secrets.
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
* that is able to push to the base repository and to access secrets.

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also clarify the wording to make it clear that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Also change the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* Fixed help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Previously the messages were unclear as to why and how the vulnerabilities could occur.

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* Adjusted the name of `actions/untrusted-checkout/high` to more clearly describe which parts of the scenario are in a privileged context.

View File

@@ -1,3 +0,0 @@
## 0.6.25
No user-facing changes.

View File

@@ -1,9 +0,0 @@
## 0.6.26
### Major Analysis Improvements
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.

View File

@@ -1,3 +0,0 @@
## 0.6.27
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.27
lastReleaseVersion: 0.6.24

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.28-dev
version: 0.6.25-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -1,9 +0,0 @@
on:
workflow_call:
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/deploy-pages

View File

@@ -1,11 +0,0 @@
on:
workflow_dispatch:
permissions:
contents: read
id-token: write
pages: write
jobs:
call-workflow:
uses: ./.github/workflows/perms11.yml

View File

@@ -7,12 +7,10 @@ ql/cpp/ql/src/Diagnostics/ExtractedFiles.ql
ql/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
ql/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
ql/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql
ql/cpp/ql/src/Likely Bugs/Format/SnprintfOverflow.ql
ql/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.ql
ql/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
@@ -30,7 +28,6 @@ ql/cpp/ql/src/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql
ql/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
ql/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
ql/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
ql/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
ql/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
ql/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql
ql/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
@@ -43,7 +40,6 @@ ql/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql
ql/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfUniquePointerAfterLifetimeEnds.ql
ql/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
ql/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
ql/cpp/ql/src/Security/CWE/CWE-611/XXE.ql
ql/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql

View File

@@ -1,45 +1,3 @@
## 10.1.0
### New Features
* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement.
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/).
### Minor Analysis Improvements
* Added taint flow models for the `Strsafe.h` header from the Windows SDK.
## 10.0.0
### Breaking Changes
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
### New Features
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.
## 9.0.0
### Breaking Changes
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
### New Features
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
### Minor Analysis Improvements
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
* Added dataflow through members initialized via non-static data member initialization (NSDMI).
## 8.0.3
No user-facing changes.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added dataflow through members initialized via non-static data member initialization (NSDMI).

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.

View File

@@ -1,10 +0,0 @@
## 10.0.0
### Breaking Changes
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
### New Features
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.

View File

@@ -1,10 +0,0 @@
## 10.1.0
### New Features
* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement.
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/).
### Minor Analysis Improvements
* Added taint flow models for the `Strsafe.h` header from the Windows SDK.

View File

@@ -1,19 +0,0 @@
## 9.0.0
### Breaking Changes
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
### New Features
* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
### Minor Analysis Improvements
* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
* Added dataflow through members initialized via non-static data member initialization (NSDMI).

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 10.1.0
lastReleaseVersion: 8.0.3

View File

@@ -1,94 +0,0 @@
# Models for strsafe.h safe string functions
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
# StringCchGets: (pszDest, cchDest)
- ["", "", False, "StringCchGetsA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCchGetsW", "", "", "Argument[*0]", "local", "manual"]
# StringCbGets: (pszDest, cbDest)
- ["", "", False, "StringCbGetsA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCbGetsW", "", "", "Argument[*0]", "local", "manual"]
# StringCchGetsEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchGetsExA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCchGetsExW", "", "", "Argument[*0]", "local", "manual"]
# StringCbGetsEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbGetsExA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCbGetsExW", "", "", "Argument[*0]", "local", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
# StringCchCopy: (pszDest, cchDest, pszSrc)
- ["", "", False, "StringCchCopyA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopy: (pszDest, cbDest, pszSrc)
- ["", "", False, "StringCbCopyA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyEx: (pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCopyExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyEx: (pszDest, cbDest, pszSrc, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCopyExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyN: (pszDest, cchDest, pszSrc, cchToCopy)
- ["", "", False, "StringCchCopyNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyN: (pszDest, cbDest, pszSrc, cbToCopy)
- ["", "", False, "StringCbCopyNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyNEx: (pszDest, cchDest, pszSrc, cchToCopy, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCopyNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyNEx: (pszDest, cbDest, pszSrc, cbToCopy, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCopyNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCat: (pszDest, cchDest, pszSrc)
- ["", "", False, "StringCchCatA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCat: (pszDest, cbDest, pszSrc)
- ["", "", False, "StringCbCatA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatEx: (pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCatExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatEx: (pszDest, cbDest, pszSrc, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCatExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatN: (pszDest, cchDest, pszSrc, cchToAppend)
- ["", "", False, "StringCchCatNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatN: (pszDest, cbDest, pszSrc, cbToAppend)
- ["", "", False, "StringCbCatNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatNEx: (pszDest, cchDest, pszSrc, cchToAppend, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCatNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatNEx: (pszDest, cbDest, pszSrc, cbToAppend, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCatNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchPrintf: (pszDest, cchDest, pszFormat, ...)
- ["", "", False, "StringCchPrintfA", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchPrintfW", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
# StringCbPrintf: (pszDest, cbDest, pszFormat, ...)
- ["", "", False, "StringCbPrintfA", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbPrintfW", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
# StringCchPrintfEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, ...)
- ["", "", False, "StringCchPrintfExA", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchPrintfExW", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
# StringCbPrintfEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, ...)
- ["", "", False, "StringCbPrintfExA", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbPrintfExW", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
# StringCchVPrintf: (pszDest, cchDest, pszFormat, argList)
- ["", "", False, "StringCchVPrintfA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchVPrintfW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbVPrintf: (pszDest, cbDest, pszFormat, argList)
- ["", "", False, "StringCbVPrintfA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbVPrintfW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchVPrintfEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList)
- ["", "", False, "StringCchVPrintfExA", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchVPrintfExW", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
# StringCbVPrintfEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, argList)
- ["", "", False, "StringCbVPrintfExA", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbVPrintfExW", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]

View File

@@ -12,7 +12,4 @@ extensions:
- ["", "", False, "_malloca", "0", "", "", False]
- ["", "", False, "calloc", "1", "0", "", True]
- ["std", "", False, "calloc", "1", "0", "", True]
- ["bsl", "", False, "calloc", "1", "0", "", True]
- ["", "", False, "aligned_alloc", "1", "", "", True]
- ["std", "", False, "aligned_alloc", "1", "", "", True]
- ["bsl", "", False, "aligned_alloc", "1", "", "", True]
- ["bsl", "", False, "calloc", "1", "0", "", True]

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 10.1.1-dev
version: 8.0.4-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -459,13 +459,6 @@ class FormatLiteral extends Literal instanceof StringLiteral {
*/
int getConvSpecOffset(int n) { result = this.getFormat().indexOf("%", n, 0) }
/**
* Gets the nth conversion specifier string.
*/
private string getConvSpecString(int n) {
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
}
/*
* Each of these predicates gets a regular expressions to match each individual
* parts of a conversion specifier.
@@ -531,20 +524,22 @@ class FormatLiteral extends Literal instanceof StringLiteral {
int n, string spec, string params, string flags, string width, string prec, string len,
string conv
) {
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
regexp = this.getConvSpecRegexp() and
(
spec = convSpec.regexpCapture(regexp, 1) and
params = convSpec.regexpCapture(regexp, 2) and
flags = convSpec.regexpCapture(regexp, 3) and
width = convSpec.regexpCapture(regexp, 4) and
prec = convSpec.regexpCapture(regexp, 5) and
len = convSpec.regexpCapture(regexp, 6) and
conv = convSpec.regexpCapture(regexp, 7)
spec = rst.regexpCapture(regexp, 1) and
params = rst.regexpCapture(regexp, 2) and
flags = rst.regexpCapture(regexp, 3) and
width = rst.regexpCapture(regexp, 4) and
prec = rst.regexpCapture(regexp, 5) and
len = rst.regexpCapture(regexp, 6) and
conv = rst.regexpCapture(regexp, 7)
or
spec = convSpec.regexpCapture(regexp, 1) and
not exists(convSpec.regexpCapture(regexp, 2)) and
spec = rst.regexpCapture(regexp, 1) and
not exists(rst.regexpCapture(regexp, 2)) and
params = "" and
flags = "" and
width = "" and
@@ -559,10 +554,12 @@ class FormatLiteral extends Literal instanceof StringLiteral {
* Gets the nth conversion specifier (including the initial `%`).
*/
string getConvSpec(int n) {
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
regexp = this.getConvSpecRegexp() and
result = convSpec.regexpCapture(regexp, 1)
result = rst.regexpCapture(regexp, 1)
)
}

View File

@@ -194,13 +194,6 @@ class ScanfFormatLiteral extends Expr {
)
}
/**
* Gets the nth conversion specifier string.
*/
private string getConvSpecString(int n) {
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
}
/**
* Gets the regular expression to match each individual part of a conversion specifier.
*/
@@ -234,14 +227,16 @@ class ScanfFormatLiteral extends Expr {
* specifier.
*/
predicate parseConvSpec(int n, string spec, string width, string len, string conv) {
exists(string convSpec, string regexp |
convSpec = this.getConvSpecString(n) and
exists(int offset, string fmt, string rst, string regexp |
offset = this.getConvSpecOffset(n) and
fmt = this.getFormat() and
rst = fmt.substring(offset, fmt.length()) and
regexp = this.getConvSpecRegexp() and
(
spec = convSpec.regexpCapture(regexp, 1) and
width = convSpec.regexpCapture(regexp, 2) and
len = convSpec.regexpCapture(regexp, 3) and
conv = convSpec.regexpCapture(regexp, 4)
spec = rst.regexpCapture(regexp, 1) and
width = rst.regexpCapture(regexp, 2) and
len = rst.regexpCapture(regexp, 3) and
conv = rst.regexpCapture(regexp, 4)
)
)
}

View File

@@ -6,15 +6,11 @@
*
* The extensible relations have the following columns:
* - Sources:
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
* `namespace; type; subtypes; name; signature; ext; output; kind`
* - Sinks:
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
* `namespace; type; subtypes; name; signature; ext; input; kind`
* - Summaries:
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
* - Barriers:
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
* - BarrierGuards:
* `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance`
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
*
* The interpretation of a row is similar to API-graphs with a left-to-right
* reading.
@@ -91,23 +87,11 @@
* value, and
* - flow from the _second_ indirection of the 0th argument to the first
* indirection of the return value, etc.
* 8. The `acceptingValue` column of barrier guard models specifies the condition
* under which the guard blocks flow. It can be one of "true" or "false". In
* the future "no-exception", "not-zero", "null", "not-null" may be supported.
* 9. The `kind` column is a tag that can be referenced from QL to determine to
* 8. The `kind` column is a tag that can be referenced from QL to determine to
* which classes the interpreted elements should be added. For example, for
* sources "remote" indicates a default remote flow source, and for summaries
* "taint" indicates a default additional taint step and "value" indicates a
* globally applicable value-preserving step.
* 10. The `provenance` column is a tag to indicate the origin and verification of a model.
* The format is {origin}-{verification} or just "manual" where the origin describes
* the origin of the model and verification describes how the model has been verified.
* Some examples are:
* - "df-generated": The model has been generated by the model generator tool.
* - "df-manual": The model has been generated by the model generator and verified by a human.
* - "manual": The model has been written by hand.
* This information is used in a heuristic for dataflow analysis to determine, if a
* model or source code should be used for determining flow.
*/
import cpp
@@ -947,13 +931,13 @@ private module Cached {
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
exists(
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingValue,
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
string kind, string model
|
isBarrierGuardNode(n, acceptingValue, kind, model) and
isBarrierGuardNode(n, acceptingvalue, kind, model) and
n.asNode().asExpr() = e and
kmp = TMkPair(kind, model) and
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
)
}
@@ -970,14 +954,14 @@ private module Cached {
) {
exists(
SourceSinkInterpretationInput::InterpretNode interpretNode,
Public::AcceptingValue acceptingValue, string kind, string model, int indirectionIndex,
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
Private::ArgumentNode arg
|
isBarrierGuardNode(interpretNode, acceptingValue, kind, model) and
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
arg = interpretNode.asNode() and
arg.asIndirectExpr(indirectionIndex) = e and
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
arg.getCall().asCallInstruction() = g
)
}

View File

@@ -33,7 +33,7 @@ extensible predicate barrierModel(
*/
extensible predicate barrierGuardModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string acceptingValue, string kind, string provenance, QlBuiltins::ExtensionId madId
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**

View File

@@ -162,13 +162,13 @@ module SourceSinkInterpretationInput implements
}
predicate barrierGuardElement(
Element e, string input, Public::AcceptingValue acceptingValue, string kind,
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
Public::Provenance provenance, string model
) {
exists(
string package, string type, boolean subtypes, string name, string signature, string ext
|
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingValue, kind,
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
provenance, model) and
e = interpretElement(package, type, subtypes, name, signature, ext)
)

View File

@@ -18,7 +18,7 @@ class Namespace extends @namespace {
if namespacembrs(_, this)
then
exists(Namespace ns |
namespacembrs(ns, pragma[only_bind_out](this)) and
namespacembrs(ns, this) and
result = ns.getQualifiedName() + "::" + this.getName()
)
else result = this.getName()
@@ -37,7 +37,7 @@ class Namespace extends @namespace {
string getAQualifierForMembers() {
if namespacembrs(_, this)
then
exists(Namespace ns | namespacembrs(ns, pragma[only_bind_out](this)) |
exists(Namespace ns | namespacembrs(ns, this) |
result = ns.getAQualifierForMembers() + "::" + this.getName()
or
// If this is an inline namespace, its members are also visible in any

View File

@@ -114,7 +114,6 @@ private predicate parseArgument(string arg, string s, int i, Opcode opcode) {
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
pragma[nomagic]
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
assertion0(mi, s, _) and
s.getParent() = scope
@@ -122,32 +121,15 @@ private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
hasAVariable(mi, s, getAChildScope(scope))
}
private predicate hasParentScope(Variable v, Element scope) { v.getParentScope() = scope }
pragma[nomagic]
private predicate hasAssertionOperand(MacroInvocation mi, int i, Stmt s, string operand) {
exists(string arg |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _)
)
}
pragma[nomagic]
private predicate hasNameAndParentScope(string name, Element scope, Variable v) {
v.hasName(name) and
hasParentScope(v, scope)
}
pragma[nomagic]
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
exists(string name, Stmt s |
hasAssertionOperand(mi, i, s, name) and
exists(string operand, string arg, Stmt s |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _) and
result =
unique(Variable v, Element parentScope |
hasAssertionOperand(mi, _, s, name) and
unique(Variable v |
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
hasAVariable(mi, s, parentScope) and
hasNameAndParentScope(name, parentScope, v)
hasAVariable(mi, s, v.getParentScope()) and
v.hasName(operand)
|
v
)

View File

@@ -11,3 +11,10 @@ import semmle.code.cpp.models.Models
* The function may still raise a structured exception handling (SEH) exception.
*/
abstract class NonCppThrowingFunction extends Function { }
/**
* A function that is guaranteed to never throw.
*
* DEPRECATED: use `NonCppThrowingFunction` instead.
*/
deprecated class NonThrowingFunction = NonCppThrowingFunction;

View File

@@ -10,6 +10,19 @@ import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* A function that is known to raise an exception.
*
* DEPRECATED: use `AlwaysSehThrowingFunction` instead.
*/
abstract deprecated class ThrowingFunction extends Function {
/**
* Holds if this function may throw an exception during evaluation.
* If `unconditional` is `true` the function always throws an exception.
*/
abstract predicate mayThrowException(boolean unconditional);
}
/**
* A function that unconditionally raises a structured exception handling (SEH) exception.
*/

View File

@@ -1412,9 +1412,9 @@ private int indexOfSwitchCaseRank(BlockStmt b, int rnk) {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1516,10 +1516,8 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* which has result `default:`, which has no result.
*/
SwitchCase getNextSwitchCase() {
exists(SwitchStmt s, int n |
this = s.getSwitchCase(n) and
result = s.getSwitchCase(n + 1)
)
result.getSwitchStmt() = this.getSwitchStmt() and
result.getChildNum() = this.getChildNum() + 1
}
/**
@@ -1709,9 +1707,9 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1733,9 +1731,9 @@ class DefaultCase extends SwitchCase {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1770,10 +1768,10 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1792,20 +1790,20 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* the result is
* ```
* {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1818,10 +1816,10 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1829,23 +1827,6 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
*/
SwitchCase getASwitchCase() { switch_case(underlyingElement(this), _, unresolveElement(result)) }
/**
* Gets the `n`th 'switch case' statement of this 'switch' statement, where
* `n` is 0-based.
*
* For example, for
* ```
* switch(i) {
* case 5:
* case 6:
* default:
* } * ```
* 0 yields `case 5:`, 1 yields `case 6:`, and 2 yields `default:`.
*/
SwitchCase getSwitchCase(int n) {
switch_case(underlyingElement(this), n, unresolveElement(result))
}
/**
* Gets the 'default case' statement of this 'switch' statement,
* if any.
@@ -1853,18 +1834,18 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* the result is `default:`, but there is no result for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* }
* ```
@@ -1877,18 +1858,18 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, this holds for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* but not for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* }
* ```

View File

@@ -1,32 +1,3 @@
## 1.6.2
No user-facing changes.
## 1.6.1
### Minor Analysis Improvements
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
## 1.6.0
### Query Metadata Changes
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
### Minor Analysis Improvements
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
## 1.5.15
No user-facing changes.

View File

@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 8.1
* @precision high
* @precision medium
* @id cpp/integer-multiplication-cast-to-long
* @tags reliability
* security

View File

@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @precision medium
* @id cpp/wrong-type-format-argument
* @tags reliability
* correctness

View File

@@ -227,30 +227,6 @@ class IgnorableUnaryBitwiseOperation extends IgnorableOperation instanceof Unary
class IgnorableAssignmentBitwiseOperation extends IgnorableOperation instanceof AssignBitwiseOperation
{ }
class YearFieldAssignmentNode extends DataFlow::Node {
YearFieldAccess access;
YearFieldAssignmentNode() {
exists(Function f |
f = this.getEnclosingCallable().getUnderlyingCallable() and not f instanceof IgnorableFunction
|
this.asDefinition().(Assignment).getLValue() = access
or
this.asDefinition().(CrementOperation).getOperand() = access
or
exists(Call c | c.getAnArgument() = access and this.asDefiningArgument() = access)
or
exists(Call c, AddressOfExpr aoe |
c.getAnArgument() = aoe and
aoe.getOperand() = access and
this.asDefiningArgument() = aoe
)
)
}
YearFieldAccess getYearFieldAccess() { result = access }
}
/**
* An arithmetic operation where one of the operands is a pointer or char type, ignore it
*/
@@ -311,7 +287,24 @@ predicate isOperationSourceCandidate(Expr e) {
}
/**
* The set of all expressions that are candidate expression.
* A data flow that tracks an ignorable operation (such as a bitwise operation) to an operation source, so we may disqualify it.
*/
module IgnorableOperationToOperationSourceCandidateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof IgnorableOperation }
predicate isSink(DataFlow::Node n) { isOperationSourceCandidate(n.asExpr()) }
// looking for sources and sinks in the same function
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module IgnorableOperationToOperationSourceCandidateFlow =
TaintTracking::Global<IgnorableOperationToOperationSourceCandidateConfig>;
/**
* The set of all expressions which is a candidate expression and also does not flow from to to some ignorable expression (eg. bitwise op)
* ```
* a = something <<< 2;
* myDate.year = a + 1; // invalid
@@ -321,16 +314,49 @@ predicate isOperationSourceCandidate(Expr e) {
* ```
*/
class OperationSource extends Expr {
OperationSource() { isOperationSourceCandidate(this) }
OperationSource() {
isOperationSourceCandidate(this) and
// If the candidate came from an ignorable operation, ignore the candidate
// NOTE: we cannot easily flow the candidate to an ignorable operation as that can
// be tricky in practice, e.g., a mod operation on a year would be part of a leap year check
// but a mod operation ending in a year is more indicative of something to ignore (a conversion)
not exists(IgnorableOperationToOperationSourceCandidateFlow::PathNode sink |
sink.getNode().asExpr() = this and
sink.isSink()
)
}
}
class YearFieldAssignmentNode extends DataFlow::Node {
YearFieldAccess access;
YearFieldAssignmentNode() {
exists(Function f |
f = this.getEnclosingCallable().getUnderlyingCallable() and not f instanceof IgnorableFunction
) and
(
this.asDefinition().(Assignment).getLValue() = access
or
this.asDefinition().(CrementOperation).getOperand() = access
or
exists(Call c | c.getAnArgument() = access and this.asDefiningArgument() = access)
or
exists(Call c, AddressOfExpr aoe |
c.getAnArgument() = aoe and
aoe.getOperand() = access and
this.asDefiningArgument() = aoe
)
)
}
YearFieldAccess getYearFieldAccess() { result = access }
}
/**
* An initial DataFlow configuration for identifying flows from an identified source
* to the Year field of a date object. This is used to restrict the sinks of
* `IgnorableOperationToOperationSourceCandidateConfig` and the sinks of the
* final `OperationToYearAssignmentConfig`.
* A DataFlow configuration for identifying flows from an identified source
* to the Year field of a date object.
*/
module OperationToYearAssignmentConfig0 implements DataFlow::ConfigSig {
module OperationToYearAssignmentConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof OperationSource }
predicate isSink(DataFlow::Node n) {
@@ -385,62 +411,6 @@ module OperationToYearAssignmentConfig0 implements DataFlow::ConfigSig {
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
}
module OperationToYearAssignmentFlow0 = TaintTracking::Global<OperationToYearAssignmentConfig0>;
predicate yearAssignmentFlowsFromSource(DataFlow::Node source, DataFlow::Node sink) {
OperationToYearAssignmentFlow0::flow(source, sink)
}
/**
* A data flow that tracks an ignorable operation (such as a bitwise operation) to an operation source, so we may disqualify it.
* Sinks are restricted to operation source candidates that have a flow to a year assignment in `OperationToYearAssignmentFlow0`.
*/
module IgnorableOperationToOperationSourceCandidateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof IgnorableOperation }
predicate isSink(DataFlow::Node n) {
isOperationSourceCandidate(n.asExpr()) and
yearAssignmentFlowsFromSource(n, _)
}
// looking for sources and sinks in the same function
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module IgnorableOperationToOperationSourceCandidateFlow =
TaintTracking::Global<IgnorableOperationToOperationSourceCandidateConfig>;
/**
* The final DataFlow configuration that refines `OperationToYearAssignmentConfig0` by
* additionally filtering out operation sources that flow from an ignorable operation
* (via `IgnorableOperationToOperationSourceCandidateFlow`).
*/
module OperationToYearAssignmentConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { yearAssignmentFlowsFromSource(n, _) }
predicate isSink(DataFlow::Node n) {
exists(DataFlow::Node operation |
yearAssignmentFlowsFromSource(operation, n) and
// If the candidate came from an ignorable operation, ignore the candidate
// NOTE: we cannot easily flow the candidate to an ignorable operation as that can
// be tricky in practice, e.g., a mod operation on a year would be part of a leap year check
// but a mod operation ending in a year is more indicative of something to ignore (a conversion)
not exists(IgnorableOperationToOperationSourceCandidateFlow::PathNode sink |
sink.getNode() = operation and
sink.isSink()
)
)
}
predicate isBarrier(DataFlow::Node n) { OperationToYearAssignmentConfig0::isBarrier(n) }
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
}
module OperationToYearAssignmentFlow = TaintTracking::Global<OperationToYearAssignmentConfig>;
predicate isLeapYearCheckSink(DataFlow::Node sink) {

View File

@@ -14,9 +14,6 @@ function may behave unpredictably.</p>
<p>This may indicate a misspelled function name, or that the required header containing
the function declaration has not been included.</p>
<p>Note: This query is not compatible with <code>build-mode: none</code> databases, and produces
no results on those databases.</p>
</overview>
<recommendation>
<p>Provide an explicit declaration of the function before invoking it.</p>
@@ -29,4 +26,4 @@ no results on those databases.</p>
<references>
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL31-C.+Declare+identifiers+before+using+them">DCL31-C. Declare identifiers before using them</a></li>
</references>
</qhelp>
</qhelp>

View File

@@ -5,7 +5,7 @@
* may lead to unpredictable behavior.
* @kind problem
* @problem.severity warning
* @precision high
* @precision medium
* @id cpp/implicit-function-declaration
* @tags correctness
* maintainability
@@ -17,11 +17,6 @@ import TooFewArguments
import TooManyArguments
import semmle.code.cpp.commons.Exclusions
/*
* This query is not compatible with build-mode: none databases, and produces
* no results on those databases.
*/
predicate locInfo(Locatable e, File file, int line, int col) {
e.getFile() = file and
e.getLocation().getStartLine() = line and
@@ -44,7 +39,6 @@ predicate isCompiledAsC(File f) {
from FunctionDeclarationEntry fdeIm, FunctionCall fc
where
isCompiledAsC(fdeIm.getFile()) and
not any(Compilation c).buildModeNone() and
not isFromMacroDefinition(fc) and
fdeIm.isImplicit() and
sameLocation(fdeIm, fc) and

View File

@@ -79,7 +79,9 @@ private predicate hasZeroParamDecl(Function f) {
// True if this file (or header) was compiled as a C file
private predicate isCompiledAsC(File f) {
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
f.compiledAsC()
or
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
}
predicate mistypedFunctionArguments(FunctionCall fc, Function f, Parameter p) {

View File

@@ -28,7 +28,9 @@ private predicate hasZeroParamDecl(Function f) {
/* Holds if this file (or header) was compiled as a C file. */
private predicate isCompiledAsC(File f) {
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
f.compiledAsC()
or
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
}
/** Holds if `fc` is a call to `f` with too few arguments. */

View File

@@ -19,7 +19,9 @@ private predicate hasZeroParamDecl(Function f) {
// True if this file (or header) was compiled as a C file
private predicate isCompiledAsC(File f) {
exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
f.compiledAsC()
or
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
}
predicate tooManyArguments(FunctionCall fc, Function f) {

View File

@@ -6,7 +6,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 7.8
* @precision high
* @precision medium
* @tags reliability
* security
* external/cwe/cwe-190

View File

@@ -6,7 +6,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 8.8
* @precision high
* @precision medium
* @id cpp/suspicious-add-sizeof
* @tags security
* external/cwe/cwe-468

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.

View File

@@ -0,0 +1,4 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.

View File

@@ -1,13 +0,0 @@
## 1.6.0
### Query Metadata Changes
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
### Minor Analysis Improvements
* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.

View File

@@ -1,10 +0,0 @@
## 1.6.1
### Minor Analysis Improvements
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.

View File

@@ -1,3 +0,0 @@
## 1.6.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.2
lastReleaseVersion: 1.5.15

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.6.3-dev
version: 1.5.16-dev
groups:
- cpp
- queries

View File

@@ -1,4 +1,4 @@
| complex.c:3:23:3:51 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:3:41:3:44 | real | file://:0:0:0:0 | double | complex.c:3:47:3:50 | imag | file://:0:0:0:0 | double |
| complex.c:4:23:4:57 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:4:41:4:47 | 2.71828 | file://:0:0:0:0 | double | complex.c:4:50:4:56 | 3.14159 | file://:0:0:0:0 | double |
| complex.c:4:23:4:57 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:4:41:4:47 | 2.71828000000000003 | file://:0:0:0:0 | double | complex.c:4:50:4:56 | 3.141589999999999883 | file://:0:0:0:0 | double |
| complex.c:8:22:8:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:8:40:8:44 | realf | file://:0:0:0:0 | float | complex.c:8:47:8:51 | imagf | file://:0:0:0:0 | float |
| complex.c:9:22:9:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:9:40:9:44 | 1.23 | file://:0:0:0:0 | float | complex.c:9:47:9:51 | 4.56 | file://:0:0:0:0 | float |
| complex.c:9:22:9:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:9:40:9:44 | 1.230000019 | file://:0:0:0:0 | float | complex.c:9:47:9:51 | 4.559999943 | file://:0:0:0:0 | float |

View File

@@ -298,16 +298,16 @@
| test.c:182:8:182:34 | ! ... | ! ... == 1 when ! ... is true |
| test.c:182:8:182:34 | ! ... | ... && ... != 0 when ! ... is false |
| test.c:182:8:182:34 | ! ... | ... && ... == 0 when ! ... is true |
| test.c:182:10:182:20 | ... >= ... | 1.0E-6 < foo+1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | 1.0E-6 >= foo+1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 < foo+1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 >= foo+1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... != 0 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | ... >= ... != 1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... == 0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... == 1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | foo < 1.0E-6+0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | foo >= 1.0E-6+0 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | foo < 9.999999999999999547e-07+0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | foo >= 9.999999999999999547e-07+0 when ... >= ... is true |
| test.c:182:10:182:33 | ... && ... | 1.0 >= foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | 1.0E-6 < foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | 9.999999999999999547e-07 < foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ! ... != 0 when ... && ... is false |
| test.c:182:10:182:33 | ... && ... | ! ... != 1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ! ... == 0 when ... && ... is true |
@@ -319,7 +319,7 @@
| test.c:182:10:182:33 | ... && ... | ... >= ... != 0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ... >= ... == 1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo < 1.0+0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo >= 1.0E-6+0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo >= 9.999999999999999547e-07+0 when ... && ... is true |
| test.c:182:25:182:33 | ... < ... | 1.0 < foo+1 when ... < ... is false |
| test.c:182:25:182:33 | ... < ... | 1.0 >= foo+1 when ... < ... is true |
| test.c:182:25:182:33 | ... < ... | ... < ... != 0 when ... < ... is true |

View File

@@ -169,12 +169,12 @@ binary
| test.c:176:8:176:15 | ! ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } |
| test.c:176:10:176:14 | ... < ... | test.c:176:10:176:10 | a | >= | test.c:176:14:176:14 | b | 0 | test.c:176:18:178:5 | { ... } |
| test.c:176:10:176:14 | ... < ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } |

View File

@@ -115,19 +115,3 @@ void test_zmc(void *socket) {
// ...
}
}
long StringCchGetsA(char *, size_t);
long StringCchGetsExA(char *, size_t, char **, size_t *, unsigned long);
void test_strsafe_gets() {
{
char dest[256] = {0};
StringCchGetsA(dest, sizeof(dest)); // $ local_source
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchGetsExA(dest, sizeof(dest), &end, &remaining, 0); // $ local_source
}
}

View File

@@ -8008,174 +8008,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
| taint.cpp:866:26:866:34 | ref arg & ... | taint.cpp:866:27:866:34 | size_out [inner post update] | |
| taint.cpp:866:27:866:34 | size_out | taint.cpp:866:26:866:34 | & ... | |
| taint.cpp:867:8:867:8 | p | taint.cpp:867:7:867:8 | * ... | TAINT |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:897:38:897:43 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:907:37:907:42 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:914:40:914:45 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:919:39:919:44 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:926:41:926:46 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:931:37:931:42 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:941:36:941:41 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:948:39:948:44 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:953:38:953:43 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:960:40:960:45 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:965:46:965:51 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:975:45:975:50 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:902:38:902:44 | wsource | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:936:37:936:43 | wsource | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:970:47:970:53 | wsource | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:897:18:897:21 | dest | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:897:31:897:34 | dest | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:898:9:898:12 | dest | |
| taint.cpp:896:21:896:21 | 0 | taint.cpp:896:19:896:22 | {...} | TAINT |
| taint.cpp:897:18:897:21 | ref arg dest | taint.cpp:898:9:898:12 | dest | |
| taint.cpp:898:9:898:12 | dest | taint.cpp:898:8:898:12 | * ... | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:902:18:902:21 | dest | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:902:31:902:34 | dest | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:903:9:903:12 | dest | |
| taint.cpp:901:24:901:24 | 0 | taint.cpp:901:22:901:25 | {...} | TAINT |
| taint.cpp:902:18:902:21 | ref arg dest | taint.cpp:903:9:903:12 | dest | |
| taint.cpp:903:9:903:12 | dest | taint.cpp:903:8:903:12 | * ... | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:907:17:907:20 | dest | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:907:30:907:33 | dest | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:908:9:908:12 | dest | |
| taint.cpp:906:21:906:21 | 0 | taint.cpp:906:19:906:22 | {...} | TAINT |
| taint.cpp:907:17:907:20 | ref arg dest | taint.cpp:908:9:908:12 | dest | |
| taint.cpp:908:9:908:12 | dest | taint.cpp:908:8:908:12 | * ... | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:914:20:914:23 | dest | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:914:33:914:36 | dest | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:915:9:915:12 | dest | |
| taint.cpp:911:21:911:21 | 0 | taint.cpp:911:19:911:22 | {...} | TAINT |
| taint.cpp:912:9:912:11 | end | taint.cpp:914:49:914:51 | end | |
| taint.cpp:913:10:913:18 | remaining | taint.cpp:914:55:914:63 | remaining | |
| taint.cpp:914:20:914:23 | ref arg dest | taint.cpp:915:9:915:12 | dest | |
| taint.cpp:914:48:914:51 | ref arg & ... | taint.cpp:914:49:914:51 | end [inner post update] | |
| taint.cpp:914:49:914:51 | end | taint.cpp:914:48:914:51 | & ... | |
| taint.cpp:914:54:914:63 | ref arg & ... | taint.cpp:914:55:914:63 | remaining [inner post update] | |
| taint.cpp:914:55:914:63 | remaining | taint.cpp:914:54:914:63 | & ... | |
| taint.cpp:915:9:915:12 | dest | taint.cpp:915:8:915:12 | * ... | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:919:19:919:22 | dest | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:919:32:919:35 | dest | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:920:9:920:12 | dest | |
| taint.cpp:918:21:918:21 | 0 | taint.cpp:918:19:918:22 | {...} | TAINT |
| taint.cpp:919:19:919:22 | ref arg dest | taint.cpp:920:9:920:12 | dest | |
| taint.cpp:920:9:920:12 | dest | taint.cpp:920:8:920:12 | * ... | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:926:21:926:24 | dest | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:926:34:926:37 | dest | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:927:8:927:11 | dest | |
| taint.cpp:923:21:923:21 | 0 | taint.cpp:923:19:923:22 | {...} | TAINT |
| taint.cpp:924:9:924:11 | end | taint.cpp:926:55:926:57 | end | |
| taint.cpp:925:10:925:18 | remaining | taint.cpp:926:61:926:69 | remaining | |
| taint.cpp:926:21:926:24 | ref arg dest | taint.cpp:927:8:927:11 | dest | |
| taint.cpp:926:54:926:57 | ref arg & ... | taint.cpp:926:55:926:57 | end [inner post update] | |
| taint.cpp:926:55:926:57 | end | taint.cpp:926:54:926:57 | & ... | |
| taint.cpp:926:60:926:69 | ref arg & ... | taint.cpp:926:61:926:69 | remaining [inner post update] | |
| taint.cpp:926:61:926:69 | remaining | taint.cpp:926:60:926:69 | & ... | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:931:17:931:20 | dest | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:931:30:931:33 | dest | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:932:9:932:12 | dest | |
| taint.cpp:931:17:931:20 | ref arg dest | taint.cpp:932:9:932:12 | dest | |
| taint.cpp:932:9:932:12 | dest | taint.cpp:932:8:932:12 | * ... | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:936:17:936:20 | dest | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:936:30:936:33 | dest | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:937:9:937:12 | dest | |
| taint.cpp:936:17:936:20 | ref arg dest | taint.cpp:937:9:937:12 | dest | |
| taint.cpp:937:9:937:12 | dest | taint.cpp:937:8:937:12 | * ... | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:941:16:941:19 | dest | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:941:29:941:32 | dest | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:942:9:942:12 | dest | |
| taint.cpp:941:16:941:19 | ref arg dest | taint.cpp:942:9:942:12 | dest | |
| taint.cpp:942:9:942:12 | dest | taint.cpp:942:8:942:12 | * ... | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:948:19:948:22 | dest | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:948:32:948:35 | dest | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:949:9:949:12 | dest | |
| taint.cpp:946:9:946:11 | end | taint.cpp:948:48:948:50 | end | |
| taint.cpp:947:10:947:18 | remaining | taint.cpp:948:54:948:62 | remaining | |
| taint.cpp:948:19:948:22 | ref arg dest | taint.cpp:949:9:949:12 | dest | |
| taint.cpp:948:47:948:50 | ref arg & ... | taint.cpp:948:48:948:50 | end [inner post update] | |
| taint.cpp:948:48:948:50 | end | taint.cpp:948:47:948:50 | & ... | |
| taint.cpp:948:53:948:62 | ref arg & ... | taint.cpp:948:54:948:62 | remaining [inner post update] | |
| taint.cpp:948:54:948:62 | remaining | taint.cpp:948:53:948:62 | & ... | |
| taint.cpp:949:9:949:12 | dest | taint.cpp:949:8:949:12 | * ... | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:953:18:953:21 | dest | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:953:31:953:34 | dest | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:954:9:954:12 | dest | |
| taint.cpp:953:18:953:21 | ref arg dest | taint.cpp:954:9:954:12 | dest | |
| taint.cpp:954:9:954:12 | dest | taint.cpp:954:8:954:12 | * ... | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:960:20:960:23 | dest | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:960:33:960:36 | dest | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:961:9:961:12 | dest | |
| taint.cpp:958:9:958:11 | end | taint.cpp:960:54:960:56 | end | |
| taint.cpp:959:10:959:18 | remaining | taint.cpp:960:60:960:68 | remaining | |
| taint.cpp:960:20:960:23 | ref arg dest | taint.cpp:961:9:961:12 | dest | |
| taint.cpp:960:53:960:56 | ref arg & ... | taint.cpp:960:54:960:56 | end [inner post update] | |
| taint.cpp:960:54:960:56 | end | taint.cpp:960:53:960:56 | & ... | |
| taint.cpp:960:59:960:68 | ref arg & ... | taint.cpp:960:60:960:68 | remaining [inner post update] | |
| taint.cpp:960:60:960:68 | remaining | taint.cpp:960:59:960:68 | & ... | |
| taint.cpp:961:9:961:12 | dest | taint.cpp:961:8:961:12 | * ... | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:965:20:965:23 | dest | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:965:33:965:36 | dest | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:966:9:966:12 | dest | |
| taint.cpp:964:21:964:21 | 0 | taint.cpp:964:19:964:22 | {...} | TAINT |
| taint.cpp:965:20:965:23 | ref arg dest | taint.cpp:966:9:966:12 | dest | |
| taint.cpp:965:40:965:43 | %s | taint.cpp:965:20:965:23 | ref arg dest | TAINT |
| taint.cpp:965:46:965:51 | ref arg source | taint.cpp:975:45:975:50 | source | |
| taint.cpp:965:46:965:51 | ref arg source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:965:46:965:51 | source | taint.cpp:965:20:965:23 | ref arg dest | TAINT |
| taint.cpp:966:9:966:12 | dest | taint.cpp:966:8:966:12 | * ... | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:970:20:970:23 | dest | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:970:33:970:36 | dest | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:971:9:971:12 | dest | |
| taint.cpp:969:24:969:24 | 0 | taint.cpp:969:22:969:25 | {...} | TAINT |
| taint.cpp:970:20:970:23 | ref arg dest | taint.cpp:971:9:971:12 | dest | |
| taint.cpp:970:40:970:44 | %s | taint.cpp:970:20:970:23 | ref arg dest | TAINT |
| taint.cpp:970:47:970:53 | wsource | taint.cpp:970:20:970:23 | ref arg dest | TAINT |
| taint.cpp:971:9:971:12 | dest | taint.cpp:971:8:971:12 | * ... | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:975:19:975:22 | dest | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:975:32:975:35 | dest | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:976:9:976:12 | dest | |
| taint.cpp:974:21:974:21 | 0 | taint.cpp:974:19:974:22 | {...} | TAINT |
| taint.cpp:975:19:975:22 | ref arg dest | taint.cpp:976:9:976:12 | dest | |
| taint.cpp:975:39:975:42 | %s | taint.cpp:975:19:975:22 | ref arg dest | TAINT |
| taint.cpp:975:45:975:50 | ref arg source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:975:45:975:50 | source | taint.cpp:975:19:975:22 | ref arg dest | TAINT |
| taint.cpp:976:9:976:12 | dest | taint.cpp:976:8:976:12 | * ... | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:982:22:982:25 | dest | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:982:35:982:38 | dest | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:983:9:983:12 | dest | |
| taint.cpp:979:21:979:21 | 0 | taint.cpp:979:19:979:22 | {...} | TAINT |
| taint.cpp:980:9:980:11 | end | taint.cpp:982:43:982:45 | end | |
| taint.cpp:981:10:981:18 | remaining | taint.cpp:982:49:982:57 | remaining | |
| taint.cpp:982:22:982:25 | ref arg dest | taint.cpp:983:9:983:12 | dest | |
| taint.cpp:982:42:982:45 | ref arg & ... | taint.cpp:982:43:982:45 | end [inner post update] | |
| taint.cpp:982:43:982:45 | end | taint.cpp:982:42:982:45 | & ... | |
| taint.cpp:982:48:982:57 | ref arg & ... | taint.cpp:982:49:982:57 | remaining [inner post update] | |
| taint.cpp:982:49:982:57 | remaining | taint.cpp:982:48:982:57 | & ... | |
| taint.cpp:982:63:982:66 | %s | taint.cpp:982:22:982:25 | ref arg dest | TAINT |
| taint.cpp:982:69:982:74 | source | taint.cpp:982:22:982:25 | ref arg dest | TAINT |
| taint.cpp:983:9:983:12 | dest | taint.cpp:983:8:983:12 | * ... | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:988:20:988:23 | dest | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:988:33:988:36 | dest | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:989:9:989:12 | dest | |
| taint.cpp:986:21:986:21 | 0 | taint.cpp:986:19:986:22 | {...} | TAINT |
| taint.cpp:987:15:987:29 | call to indirect_source | taint.cpp:988:40:988:42 | fmt | |
| taint.cpp:988:20:988:23 | ref arg dest | taint.cpp:989:9:989:12 | dest | |
| taint.cpp:988:40:988:42 | fmt | taint.cpp:988:20:988:23 | ref arg dest | TAINT |
| taint.cpp:989:9:989:12 | dest | taint.cpp:989:8:989:12 | * ... | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:993:20:993:23 | dest | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:993:33:993:36 | dest | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:994:9:994:12 | dest | |
| taint.cpp:992:21:992:21 | 0 | taint.cpp:992:19:992:22 | {...} | TAINT |
| taint.cpp:993:20:993:23 | ref arg dest | taint.cpp:994:9:994:12 | dest | |
| taint.cpp:993:40:993:43 | %d | taint.cpp:993:20:993:23 | ref arg dest | TAINT |
| taint.cpp:993:46:993:47 | 42 | taint.cpp:993:20:993:23 | ref arg dest | TAINT |
| taint.cpp:994:9:994:12 | dest | taint.cpp:994:8:994:12 | * ... | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:998:18:998:21 | dest | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:998:31:998:34 | dest | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:999:9:999:12 | dest | |
| taint.cpp:997:21:997:21 | 0 | taint.cpp:997:19:997:22 | {...} | TAINT |
| taint.cpp:998:18:998:21 | ref arg dest | taint.cpp:999:9:999:12 | dest | |
| taint.cpp:999:9:999:12 | dest | taint.cpp:999:8:999:12 | * ... | |
| thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | |
| thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | |
| thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | |

View File

@@ -866,136 +866,3 @@ void test_iconv(size_t size) {
iconv(0, &s, &size, &p, &size_out);
sink(*p); // $ ast,ir
}
using va_list = void*;
long StringCchCopyA(char *, size_t, const char *);
long StringCchCopyW(wchar_t *, size_t, const wchar_t *);
long StringCbCopyA(char *, size_t, const char *);
long StringCchCopyExA(char *, size_t, const char *, char **, size_t *, unsigned long);
long StringCchCopyNA(char *, size_t, const char *, size_t);
long StringCchCopyNExA(char *, size_t, const char *, size_t, char **, size_t *, unsigned long);
long StringCchCatA(char *, size_t, const char *);
long StringCchCatW(wchar_t *, size_t, const wchar_t *);
long StringCbCatA(char *, size_t, const char *);
long StringCchCatExA(char *, size_t, const char *, char **, size_t *, unsigned long);
long StringCchCatNA(char *, size_t, const char *, size_t);
long StringCchCatNExA(char *, size_t, const char *, size_t, char **, size_t *, unsigned long);
long StringCchPrintfA(char *, size_t, const char *, ...);
long StringCchPrintfW(wchar_t *, size_t, const wchar_t *, ...);
long StringCbPrintfA(char *, size_t, const char *, ...);
long StringCchPrintfExA(char *, size_t, char **, size_t *, unsigned long, const char *, ...);
long StringCchVPrintfA(char *, size_t, const char *, va_list);
long StringCchVPrintfExA(char *, size_t, char **, size_t *, unsigned long, const char *, va_list);
void test_strsafe() {
char *source = indirect_source();
wchar_t *wsource = (wchar_t *)indirect_source();
{
char dest[256] = {0};
StringCchCopyA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = {0};
StringCchCopyW(dest, sizeof(dest), wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCbCopyA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchCopyExA(dest, sizeof(dest), source, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchCopyNA(dest, sizeof(dest), source, 128);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchCopyNExA(dest, sizeof(dest), source, 128, &end, &remaining, 0);
sink(dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCchCatA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = L"prefix";
StringCchCatW(dest, sizeof(dest), wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCbCatA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
char *end;
size_t remaining;
StringCchCatExA(dest, sizeof(dest), source, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCchCatNA(dest, sizeof(dest), source, 128);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
char *end;
size_t remaining;
StringCchCatNExA(dest, sizeof(dest), source, 128, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchPrintfA(dest, sizeof(dest), "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = {0};
StringCchPrintfW(dest, sizeof(dest), L"%s", wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCbPrintfA(dest, sizeof(dest), "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchPrintfExA(dest, sizeof(dest), &end, &remaining, 0, "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *fmt = indirect_source();
StringCchPrintfA(dest, sizeof(dest), fmt);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchPrintfA(dest, sizeof(dest), "%d", 42);
sink(*dest); // clean
}
{
char dest[256] = {0};
StringCchCopyA(dest, sizeof(dest), "hello");
sink(*dest); // clean
}
}

View File

@@ -28044,118 +28044,6 @@ getParameterTypeName
| taint.cpp:859:8:859:12 | iconv | 4 | unsigned long * |
| taint.cpp:861:6:861:15 | test_iconv | 0 | size_t |
| taint.cpp:861:6:861:15 | test_iconv | 0 | unsigned long |
| taint.cpp:872:6:872:19 | StringCchCopyA | 0 | char * |
| taint.cpp:872:6:872:19 | StringCchCopyA | 1 | size_t |
| taint.cpp:872:6:872:19 | StringCchCopyA | 1 | unsigned long |
| taint.cpp:872:6:872:19 | StringCchCopyA | 2 | const char * |
| taint.cpp:873:6:873:19 | StringCchCopyW | 0 | wchar_t * |
| taint.cpp:873:6:873:19 | StringCchCopyW | 1 | size_t |
| taint.cpp:873:6:873:19 | StringCchCopyW | 1 | unsigned long |
| taint.cpp:873:6:873:19 | StringCchCopyW | 2 | const wchar_t * |
| taint.cpp:874:6:874:18 | StringCbCopyA | 0 | char * |
| taint.cpp:874:6:874:18 | StringCbCopyA | 1 | size_t |
| taint.cpp:874:6:874:18 | StringCbCopyA | 1 | unsigned long |
| taint.cpp:874:6:874:18 | StringCbCopyA | 2 | const char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 0 | char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 1 | size_t |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 1 | unsigned long |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 2 | const char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 3 | char ** |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 4 | size_t * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 4 | unsigned long * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 5 | unsigned long |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 0 | char * |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 1 | size_t |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 1 | unsigned long |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 2 | const char * |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 3 | size_t |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 3 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 0 | char * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 1 | size_t |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 1 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 2 | const char * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 3 | size_t |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 3 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 4 | char ** |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 5 | size_t * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 5 | unsigned long * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 6 | unsigned long |
| taint.cpp:878:6:878:18 | StringCchCatA | 0 | char * |
| taint.cpp:878:6:878:18 | StringCchCatA | 1 | size_t |
| taint.cpp:878:6:878:18 | StringCchCatA | 1 | unsigned long |
| taint.cpp:878:6:878:18 | StringCchCatA | 2 | const char * |
| taint.cpp:879:6:879:18 | StringCchCatW | 0 | wchar_t * |
| taint.cpp:879:6:879:18 | StringCchCatW | 1 | size_t |
| taint.cpp:879:6:879:18 | StringCchCatW | 1 | unsigned long |
| taint.cpp:879:6:879:18 | StringCchCatW | 2 | const wchar_t * |
| taint.cpp:880:6:880:17 | StringCbCatA | 0 | char * |
| taint.cpp:880:6:880:17 | StringCbCatA | 1 | size_t |
| taint.cpp:880:6:880:17 | StringCbCatA | 1 | unsigned long |
| taint.cpp:880:6:880:17 | StringCbCatA | 2 | const char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 0 | char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 1 | size_t |
| taint.cpp:881:6:881:20 | StringCchCatExA | 1 | unsigned long |
| taint.cpp:881:6:881:20 | StringCchCatExA | 2 | const char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 3 | char ** |
| taint.cpp:881:6:881:20 | StringCchCatExA | 4 | size_t * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 4 | unsigned long * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 5 | unsigned long |
| taint.cpp:882:6:882:19 | StringCchCatNA | 0 | char * |
| taint.cpp:882:6:882:19 | StringCchCatNA | 1 | size_t |
| taint.cpp:882:6:882:19 | StringCchCatNA | 1 | unsigned long |
| taint.cpp:882:6:882:19 | StringCchCatNA | 2 | const char * |
| taint.cpp:882:6:882:19 | StringCchCatNA | 3 | size_t |
| taint.cpp:882:6:882:19 | StringCchCatNA | 3 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 0 | char * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 1 | size_t |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 1 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 2 | const char * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 3 | size_t |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 3 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 4 | char ** |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 5 | size_t * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 5 | unsigned long * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 6 | unsigned long |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 0 | char * |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 1 | size_t |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 1 | unsigned long |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 2 | const char * |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 3 | ... |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 0 | wchar_t * |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 1 | size_t |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 1 | unsigned long |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 2 | const wchar_t * |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 3 | ... |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 0 | char * |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 1 | size_t |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 1 | unsigned long |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 2 | const char * |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 3 | ... |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 0 | char * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 1 | size_t |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 1 | unsigned long |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 2 | char ** |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 3 | size_t * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 3 | unsigned long * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 4 | unsigned long |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 5 | const char * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 6 | ... |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 0 | char * |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 1 | size_t |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 1 | unsigned long |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 2 | const char * |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 3 | va_list |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 3 | void * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 0 | char * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 1 | size_t |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 1 | unsigned long |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 2 | char ** |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 3 | size_t * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 3 | unsigned long * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 4 | unsigned long |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 5 | const char * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 6 | va_list |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 6 | void * |
| thread.cpp:4:6:4:9 | sink | 0 | int |
| thread.cpp:6:8:6:8 | operator= | 0 | S && |
| thread.cpp:6:8:6:8 | operator= | 0 | const S & |

View File

@@ -25796,9 +25796,9 @@ ir.cpp:
# 2919| getExpr(): [FunctionCall] call to VariableTemplateFunc
# 2919| Type = [DoubleType] double
# 2919| ValueCategory = prvalue
# 2919| getArgument(0): [Literal] 2.3
# 2919| getArgument(0): [Literal] 2.299999999999999822
# 2919| Type = [DoubleType] double
# 2919| Value = [Literal] 2.3
# 2919| Value = [Literal] 2.299999999999999822
# 2919| ValueCategory = prvalue
# 2919| getExpr().getFullyConverted(): [CStyleCast] (int)...
# 2919| Conversion = [FloatingPointToIntegralConversion] floating point to integral conversion

View File

@@ -12954,21 +12954,21 @@ ir.cpp:
# 1592| double StructuredBindingTupleRefGet::d
# 1592| Block 0
# 1592| v1592_1(void) = EnterFunction :
# 1592| m1592_2(unknown) = AliasedDefinition :
# 1592| m1592_3(unknown) = InitializeNonLocal :
# 1592| m1592_4(unknown) = Chi : total:m1592_2, partial:m1592_3
# 1592| r1592_5(glval<unknown>) = VariableAddress[#this] :
# 1592| m1592_6(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_5
# 1592| r1592_7(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_5, m1592_6
# 1592| m1592_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_7
# 1592| r1592_9(glval<double>) = FieldAddress[d] : r1592_7
# 1592| r1592_10(double) = Constant[2.2] :
# 1592| m1592_11(double) = Store[?] : &:r1592_9, r1592_10
# 1592| m1592_12(unknown) = Chi : total:m1592_8, partial:m1592_11
# 1592| v1592_13(void) = ReturnVoid :
# 1592| v1592_14(void) = AliasedUse : m1592_3
# 1592| v1592_15(void) = ExitFunction :
# 1592| v1592_1(void) = EnterFunction :
# 1592| m1592_2(unknown) = AliasedDefinition :
# 1592| m1592_3(unknown) = InitializeNonLocal :
# 1592| m1592_4(unknown) = Chi : total:m1592_2, partial:m1592_3
# 1592| r1592_5(glval<unknown>) = VariableAddress[#this] :
# 1592| m1592_6(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_5
# 1592| r1592_7(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_5, m1592_6
# 1592| m1592_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_7
# 1592| r1592_9(glval<double>) = FieldAddress[d] : r1592_7
# 1592| r1592_10(double) = Constant[2.200000000000000178] :
# 1592| m1592_11(double) = Store[?] : &:r1592_9, r1592_10
# 1592| m1592_12(unknown) = Chi : total:m1592_8, partial:m1592_11
# 1592| v1592_13(void) = ReturnVoid :
# 1592| v1592_14(void) = AliasedUse : m1592_3
# 1592| v1592_15(void) = ExitFunction :
# 1593| int& StructuredBindingTupleRefGet::r
# 1593| Block 0
@@ -21761,7 +21761,7 @@ ir.cpp:
# 2919| m2919_2(unknown) = AliasedDefinition :
# 2919| r2919_3(glval<int>) = VariableAddress[VariableTemplateFuncUse] :
# 2919| r2919_4(glval<unknown>) = FunctionAddress[VariableTemplateFunc] :
# 2919| r2919_5(double) = Constant[2.3] :
# 2919| r2919_5(double) = Constant[2.299999999999999822] :
# 2919| r2919_6(double) = Call[VariableTemplateFunc] : func:r2919_4, 0:r2919_5
# 2919| m2919_7(unknown) = ^CallSideEffect : ~m2919_2
# 2919| m2919_8(unknown) = Chi : total:m2919_2, partial:m2919_7

View File

@@ -11861,19 +11861,19 @@ ir.cpp:
# 1592| double StructuredBindingTupleRefGet::d
# 1592| Block 0
# 1592| v1592_1(void) = EnterFunction :
# 1592| mu1592_2(unknown) = AliasedDefinition :
# 1592| mu1592_3(unknown) = InitializeNonLocal :
# 1592| r1592_4(glval<unknown>) = VariableAddress[#this] :
# 1592| mu1592_5(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_4
# 1592| r1592_6(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_4, ~m?
# 1592| mu1592_7(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_6
# 1592| r1592_8(glval<double>) = FieldAddress[d] : r1592_6
# 1592| r1592_9(double) = Constant[2.2] :
# 1592| mu1592_10(double) = Store[?] : &:r1592_8, r1592_9
# 1592| v1592_11(void) = ReturnVoid :
# 1592| v1592_12(void) = AliasedUse : ~m?
# 1592| v1592_13(void) = ExitFunction :
# 1592| v1592_1(void) = EnterFunction :
# 1592| mu1592_2(unknown) = AliasedDefinition :
# 1592| mu1592_3(unknown) = InitializeNonLocal :
# 1592| r1592_4(glval<unknown>) = VariableAddress[#this] :
# 1592| mu1592_5(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_4
# 1592| r1592_6(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_4, ~m?
# 1592| mu1592_7(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_6
# 1592| r1592_8(glval<double>) = FieldAddress[d] : r1592_6
# 1592| r1592_9(double) = Constant[2.200000000000000178] :
# 1592| mu1592_10(double) = Store[?] : &:r1592_8, r1592_9
# 1592| v1592_11(void) = ReturnVoid :
# 1592| v1592_12(void) = AliasedUse : ~m?
# 1592| v1592_13(void) = ExitFunction :
# 1593| int& StructuredBindingTupleRefGet::r
# 1593| Block 0
@@ -19768,7 +19768,7 @@ ir.cpp:
# 2919| mu2919_2(unknown) = AliasedDefinition :
# 2919| r2919_3(glval<int>) = VariableAddress[VariableTemplateFuncUse] :
# 2919| r2919_4(glval<unknown>) = FunctionAddress[VariableTemplateFunc] :
# 2919| r2919_5(double) = Constant[2.3] :
# 2919| r2919_5(double) = Constant[2.299999999999999822] :
# 2919| r2919_6(double) = Call[VariableTemplateFunc] : func:r2919_4, 0:r2919_5
# 2919| mu2919_7(unknown) = ^CallSideEffect : ~m?
# 2919| r2919_8(int) = Convert : r2919_6

Some files were not shown because too many files have changed in this diff Show More