From a9ae583e14c119c8e762b5e4380783f8b953c032 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 16 Oct 2025 16:50:13 +0200 Subject: [PATCH 1/3] Rust: introduce `File::hasSemantics` and `File::isSkippedByCompilation` --- .../2025-10-16-new-extracted-file-methods.md | 4 ++++ rust/ql/lib/codeql/files/FileSystem.qll | 19 +++++++++++++++++++ .../test/extractor-tests/File/File.expected | 15 +++++++++------ rust/ql/test/extractor-tests/File/File.ql | 14 +++++++++++--- .../extractor-tests/File/bad_cargo/.gitignore | 1 + .../extractor-tests/File/bad_cargo/Cargo.toml | 1 + .../File/bad_cargo/src/no_semantics.rs | 0 .../File/nested/not_compiled.rs | 0 8 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 rust/ql/lib/change-notes/2025-10-16-new-extracted-file-methods.md create mode 100644 rust/ql/test/extractor-tests/File/bad_cargo/.gitignore create mode 100644 rust/ql/test/extractor-tests/File/bad_cargo/Cargo.toml create mode 100644 rust/ql/test/extractor-tests/File/bad_cargo/src/no_semantics.rs create mode 100644 rust/ql/test/extractor-tests/File/nested/not_compiled.rs diff --git a/rust/ql/lib/change-notes/2025-10-16-new-extracted-file-methods.md b/rust/ql/lib/change-notes/2025-10-16-new-extracted-file-methods.md new file mode 100644 index 000000000000..63fbbe388999 --- /dev/null +++ b/rust/ql/lib/change-notes/2025-10-16-new-extracted-file-methods.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added `ExtractedFile::hasSemantics` and `ExtractedFile::isSkippedByCompilation` predicates. diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index 5a60d28418eb..9ad78cb465be 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -71,6 +71,25 @@ class File extends Container, Impl::File { */ class ExtractedFile extends File { ExtractedFile() { this.fromSource() } + + private Diagnostic getNoSemanticsDiagnostic() { + result.getTag() = "semantics" and result.getLocation().getFile() = this + } + + /** + * Holds if we have semantical information about this file, which means + * we should be able to + * * expand any macros + * * skip any blocks that are conditionally compiled out + */ + predicate hasSemantics() { not exists(Diagnostic d | d = this.getNoSemanticsDiagnostic()) } + + /** + * Holds if we know this file was skipped by conditional compilation. + * This is not the same as `not this.hasSemantics()`, as a file + * might not have semantics because of some error. + */ + predicate isSkippedByCompilation() { this.getNoSemanticsDiagnostic().getSeverityText() = "Info" } } /** diff --git a/rust/ql/test/extractor-tests/File/File.expected b/rust/ql/test/extractor-tests/File/File.expected index ad701669ab2a..ebfcdae19674 100644 --- a/rust/ql/test/extractor-tests/File/File.expected +++ b/rust/ql/test/extractor-tests/File/File.expected @@ -1,6 +1,9 @@ -| Cargo.toml:0:0:0:0 | Cargo.toml | fromSource: no | -| a_file.rs:0:0:0:0 | a_file.rs | fromSource: yes | -| another_file.rs:0:0:0:0 | another_file.rs | fromSource: yes | -| lib.rs:0:0:0:0 | lib.rs | fromSource: yes | -| nested.rs:0:0:0:0 | nested.rs | fromSource: yes | -| nested/file.rs:0:0:0:0 | nested/file.rs | fromSource: yes | +| Cargo.toml:0:0:0:0 | Cargo.toml | fromSource: no | hasSemantics: no | isSkippedByCompilation: no | +| a_file.rs:0:0:0:0 | a_file.rs | fromSource: yes | hasSemantics: yes | isSkippedByCompilation: no | +| another_file.rs:0:0:0:0 | another_file.rs | fromSource: yes | hasSemantics: yes | isSkippedByCompilation: no | +| bad_cargo/Cargo.toml:0:0:0:0 | bad_cargo/Cargo.toml | fromSource: no | hasSemantics: no | isSkippedByCompilation: no | +| bad_cargo/src/no_semantics.rs:0:0:0:0 | bad_cargo/src/no_semantics.rs | fromSource: yes | hasSemantics: no | isSkippedByCompilation: no | +| lib.rs:0:0:0:0 | lib.rs | fromSource: yes | hasSemantics: yes | isSkippedByCompilation: no | +| nested.rs:0:0:0:0 | nested.rs | fromSource: yes | hasSemantics: yes | isSkippedByCompilation: no | +| nested/file.rs:0:0:0:0 | nested/file.rs | fromSource: yes | hasSemantics: yes | isSkippedByCompilation: no | +| nested/not_compiled.rs:0:0:0:0 | nested/not_compiled.rs | fromSource: yes | hasSemantics: no | isSkippedByCompilation: yes | diff --git a/rust/ql/test/extractor-tests/File/File.ql b/rust/ql/test/extractor-tests/File/File.ql index 316099193d15..2d21f12bc296 100644 --- a/rust/ql/test/extractor-tests/File/File.ql +++ b/rust/ql/test/extractor-tests/File/File.ql @@ -1,7 +1,15 @@ import rust -from File f, string fromSource +from File f, string fromSource, string hasSemantics, string isSkippedByCompilation where exists(f.getRelativePath()) and - if f.fromSource() then fromSource = "fromSource: yes" else fromSource = "fromSource: no" -select f, fromSource + (if f.fromSource() then fromSource = "fromSource: yes" else fromSource = "fromSource: no") and + ( + if f.(ExtractedFile).hasSemantics() + then hasSemantics = "hasSemantics: yes" + else hasSemantics = "hasSemantics: no" + ) and + if f.(ExtractedFile).isSkippedByCompilation() + then isSkippedByCompilation = "isSkippedByCompilation: yes" + else isSkippedByCompilation = "isSkippedByCompilation: no" +select f, fromSource, hasSemantics, isSkippedByCompilation diff --git a/rust/ql/test/extractor-tests/File/bad_cargo/.gitignore b/rust/ql/test/extractor-tests/File/bad_cargo/.gitignore new file mode 100644 index 000000000000..eac412e1a6d1 --- /dev/null +++ b/rust/ql/test/extractor-tests/File/bad_cargo/.gitignore @@ -0,0 +1 @@ +!/Cargo.toml diff --git a/rust/ql/test/extractor-tests/File/bad_cargo/Cargo.toml b/rust/ql/test/extractor-tests/File/bad_cargo/Cargo.toml new file mode 100644 index 000000000000..688dd9e29ac4 --- /dev/null +++ b/rust/ql/test/extractor-tests/File/bad_cargo/Cargo.toml @@ -0,0 +1 @@ +wrong \ No newline at end of file diff --git a/rust/ql/test/extractor-tests/File/bad_cargo/src/no_semantics.rs b/rust/ql/test/extractor-tests/File/bad_cargo/src/no_semantics.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/rust/ql/test/extractor-tests/File/nested/not_compiled.rs b/rust/ql/test/extractor-tests/File/nested/not_compiled.rs new file mode 100644 index 000000000000..e69de29bb2d1 From 4aef1ba9d15a892ecf83c862d6731aba03311634 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 16 Oct 2025 17:20:41 +0200 Subject: [PATCH 2/3] Rust: clean up --- rust/ql/lib/codeql/files/FileSystem.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index 9ad78cb465be..854de53652f4 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -82,7 +82,7 @@ class ExtractedFile extends File { * * expand any macros * * skip any blocks that are conditionally compiled out */ - predicate hasSemantics() { not exists(Diagnostic d | d = this.getNoSemanticsDiagnostic()) } + predicate hasSemantics() { not exists(this.getNoSemanticsDiagnostic()) } /** * Holds if we know this file was skipped by conditional compilation. From 6a6015e0eb4d6bbee468b28a26f00eda81d44e56 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 17 Oct 2025 15:10:49 +0200 Subject: [PATCH 3/3] Rust: accept test changes --- .../File/CONSISTENCY/ExtractionConsistency.expected | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 rust/ql/test/extractor-tests/File/CONSISTENCY/ExtractionConsistency.expected diff --git a/rust/ql/test/extractor-tests/File/CONSISTENCY/ExtractionConsistency.expected b/rust/ql/test/extractor-tests/File/CONSISTENCY/ExtractionConsistency.expected new file mode 100644 index 000000000000..c642b9fc2dd9 --- /dev/null +++ b/rust/ql/test/extractor-tests/File/CONSISTENCY/ExtractionConsistency.expected @@ -0,0 +1,2 @@ +extractionWarning +| bad_cargo/src/no_semantics.rs:1:1:1:1 | semantic analyzer unavailable (unable to load manifest) |