Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions .github/workflows/copilot-setup-steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,47 @@ jobs:
- name: Copilot Setup - Install CodeQL
uses: ./.github/actions/install-codeql

- name: Copilot Setup - Install CodeQL packs
uses: ./.github/actions/install-codeql-packs
- name: Copilot Setup - Install CodeQL packs (common)
uses: ./.github/actions/install-codeql-packs
with:
language: common

- name: Copilot Setup - Install CodeQL packs (cpp)
uses: ./.github/actions/install-codeql-packs
with:
language: cpp

- name: Copilot Setup - Install CodeQL packs (csharp)
uses: ./.github/actions/install-codeql-packs
with:
language: csharp

- name: Copilot Setup - Install CodeQL packs (go)
uses: ./.github/actions/install-codeql-packs
with:
language: go

- name: Copilot Setup - Install CodeQL packs (java)
uses: ./.github/actions/install-codeql-packs
with:
language: java

- name: Copilot Setup - Install CodeQL packs (javascript)
uses: ./.github/actions/install-codeql-packs
with:
language: javascript

- name: Copilot Setup - Install CodeQL packs (python)
uses: ./.github/actions/install-codeql-packs
with:
language: python

- name: Copilot Setup - Install CodeQL packs (ruby)
uses: ./.github/actions/install-codeql-packs
with:
language: ruby

- name: Copilot Setup - Install CodeQL packs (swift)
uses: ./.github/actions/install-codeql-packs
with:
language: swift
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# CodeQL CLI installation directory
codeql_home/
5 changes: 5 additions & 0 deletions cpp/src/qtil/cpp/graph/CustomPathStateProblem.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.cpp.locations.Locatable
private import cpp
// Import the C++ specific configuration for making custom path state problems.
import PathStateProblem<Location, CppLocatableConfig>
9 changes: 9 additions & 0 deletions cpp/test/qtil/cpp/graph/CustomPathStateProblemTest.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.cpp:3:9:3:11 | mid | test.cpp:2:9:2:11 | end | | |
| test.cpp:4:9:4:13 | start | test.cpp:3:9:3:11 | mid | | |
nodes
| test.cpp:2:9:2:11 | end | semmle.label | end |
| test.cpp:3:9:3:11 | mid | semmle.label | mid |
| test.cpp:4:9:4:13 | start | semmle.label | start |
#select
| test.cpp:4:9:4:13 | start | test.cpp:2:9:2:11 | end | Path from $@ to $@. | start | test.cpp:4:9:4:13 | start | end | test.cpp:2:9:2:11 | end |
30 changes: 30 additions & 0 deletions cpp/test/qtil/cpp/graph/CustomPathStateProblemTest.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Minimal test to make sure CustomPathStateProblem works with C++ code.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test.cpp file that has interesting contents in order to test that the CustomPathStateProblem module is working correctly.

This will need to happen for the other languages as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added meaningful test.cpp content with variable initialization chain (end→mid→start) that demonstrates the CustomPathStateProblem functionality. The test now produces actual path analysis results showing the variable dependency chain. Commit: 4cae451

import cpp
import qtil.cpp.graph.CustomPathStateProblem

module CallGraphPathStateProblemConfig implements CustomPathStateProblemConfigSig {
class Node = Variable;

class State = int; // Track search depth

predicate start(Node n, int depth) { n.getName() = "start" and depth = 0 }

bindingset[depth]
predicate end(Node n, int depth) { n.getName() = "end" and depth >= 0 }

bindingset[depth1]
bindingset[depth2]
predicate edge(Variable a, int depth1, Variable b, int depth2) {
depth2 = depth1 + 1 and
exists(Initializer initA |
a.getInitializer() = initA and
initA.getExpr().(VariableAccess).getTarget() = b
)
}
}

import CustomPathStateProblem<CallGraphPathStateProblemConfig>

from Variable start, Variable end
where problem(start, end)
select start, end, "Path from $@ to $@.", start.getName(), start, end.getName(), end
11 changes: 4 additions & 7 deletions cpp/test/qtil/cpp/graph/test.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
void f1() {
int mid;
int start;
int end;
int unrelated;
start = mid;
start = unrelated;
mid = end;
int end = 42;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes broke CustomPathProblemTest. The same goes for other changes to test files in the other languages.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by restoring the original test.cpp structure that works with both CustomPathProblemTest and CustomPathStateProblemTest. The issue was changing the variable declaration/assignment pattern without updating all related test expectations. Commit: ff031be

int mid = end;
int start = mid;
int unrelated = 0;
}
5 changes: 5 additions & 0 deletions csharp/src/qtil/csharp/graph/CustomPathStateProblem.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.csharp.locations.Locatable
private import csharp
// Import the C# specific configuration for making custom path state problems.
import PathStateProblem<Location, CsharpLocatableConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.cs:4:13:4:15 | mid | test.cs:3:13:3:15 | end | | |
| test.cs:5:13:5:17 | start | test.cs:4:13:4:15 | mid | | |
nodes
| test.cs:3:13:3:15 | end | semmle.label | end |
| test.cs:4:13:4:15 | mid | semmle.label | mid |
| test.cs:5:13:5:17 | start | semmle.label | start |
#select
| test.cs:5:13:5:17 | start | test.cs:3:13:3:15 | end | Path from $@ to $@. | start | test.cs:5:13:5:17 | start | end | test.cs:3:13:3:15 | end |
31 changes: 31 additions & 0 deletions csharp/test/qtil/csharp/graph/CustomPathStateProblemTest.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Minimal test to make sure CustomPathStateProblem works with C# code.
import csharp
import qtil.csharp.graph.CustomPathStateProblem

module CallGraphPathStateProblemConfig implements CustomPathStateProblemConfigSig {
class Node = LocalVariable;

class State = int; // Track search depth

predicate start(Node n, int depth) { n.getName() = "start" and depth = 0 }

bindingset[depth]
predicate end(Node n, int depth) { n.getName() = "end" and depth >= 0 }

bindingset[depth1]
bindingset[depth2]
predicate edge(LocalVariable a, int depth1, LocalVariable b, int depth2) {
depth2 = depth1 + 1 and
exists(LocalVariableDeclExpr declA, LocalVariableDeclExpr declB |
declA.getVariable() = a and
declB.getVariable() = b and
declA.getInitializer().(VariableAccess).getTarget() = b
)
}
}

import CustomPathStateProblem<CallGraphPathStateProblemConfig>

from LocalVariable start, LocalVariable end
where problem(start, end)
select start, end, "Path from $@ to $@.", start.getName(), start, end.getName(), end
9 changes: 3 additions & 6 deletions csharp/test/qtil/csharp/graph/test.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
public class Test {
void f1() {
int mid = 0;
int start = 0;
int end = 0;
int end = 42;
int mid = end;
int start = mid;
int unrelated = 0;
start = mid;
start = unrelated;
mid = end;
}
}
5 changes: 5 additions & 0 deletions go/src/qtil/go/graph/CustomPathStateProblem.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.go.locations.Locatable
private import go
// Import the Go specific configuration for making custom path state problems.
import PathStateProblem<DbLocation, GoLocatableConfig>
9 changes: 9 additions & 0 deletions go/test/qtil/go/graph/CustomPathStateProblemTest.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.go:5:5:5:7 | mid | test.go:4:5:4:7 | end | | |
| test.go:6:5:6:9 | start | test.go:5:5:5:7 | mid | | |
nodes
| test.go:4:5:4:7 | end | semmle.label | end |
| test.go:5:5:5:7 | mid | semmle.label | mid |
| test.go:6:5:6:9 | start | semmle.label | start |
#select
| test.go:6:5:6:9 | start | test.go:4:5:4:7 | end | Path from $@ to $@. | start | test.go:6:5:6:9 | start | end | test.go:4:5:4:7 | end |
30 changes: 30 additions & 0 deletions go/test/qtil/go/graph/CustomPathStateProblemTest.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Minimal test to make sure CustomPathStateProblem works with Go code.
import go
import qtil.go.graph.CustomPathStateProblem

module CallGraphPathStateProblemConfig implements CustomPathStateProblemConfigSig {
class Node = Ident;

class State = int; // Track search depth

predicate start(Node n, int depth) { n.getName() = "start" and depth = 0 }

bindingset[depth]
predicate end(Node n, int depth) { n.getName() = "end" and depth >= 0 }

bindingset[depth1]
bindingset[depth2]
predicate edge(Ident a, int depth1, Ident b, int depth2) {
depth2 = depth1 + 1 and
exists(Assignment assign |
assign.getLhs().(Name).getTarget().getDeclaration() = a and
assign.getRhs().(Name).getTarget().getDeclaration() = b
)
}
}

import CustomPathStateProblem<CallGraphPathStateProblemConfig>

from Ident start, Ident end
where problem(start, end)
select start, end, "Path from $@ to $@.", start.getName(), start, end.getName(), end
11 changes: 5 additions & 6 deletions go/test/qtil/go/graph/test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package main

func f1() {
mid := 0
start := 1
end := 2
unrelated := 3
start = mid
start = unrelated
end := 42
mid := 0
start := 0
unrelated := 0
mid = end
start = mid
}
5 changes: 5 additions & 0 deletions java/src/qtil/java/graph/CustomPathStateProblem.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.java.locations.Locatable
private import java
// Import the Java specific configuration for making custom path state problems.
import PathStateProblem<Location, JavaLocatableConfig>
9 changes: 9 additions & 0 deletions java/test/qtil/java/graph/CustomPathStateProblemTest.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.java:4:9:4:22 | int mid | test.java:3:9:3:21 | int end | | |
| test.java:5:9:5:24 | int start | test.java:4:9:4:22 | int mid | | |
nodes
| test.java:3:9:3:21 | int end | semmle.label | int end |
| test.java:4:9:4:22 | int mid | semmle.label | int mid |
| test.java:5:9:5:24 | int start | semmle.label | int start |
#select
| test.java:5:9:5:24 | int start | test.java:3:9:3:21 | int end | Path from $@ to $@. | start | test.java:5:9:5:24 | int start | end | test.java:3:9:3:21 | int end |
31 changes: 31 additions & 0 deletions java/test/qtil/java/graph/CustomPathStateProblemTest.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Minimal test to make sure CustomPathStateProblem works with Java code.
import java
import qtil.java.graph.CustomPathStateProblem

module CallGraphPathStateProblemConfig implements CustomPathStateProblemConfigSig {
class Node = LocalVariableDecl;

class State = int; // Track search depth

predicate start(Node n, int depth) { n.getName() = "start" and depth = 0 }

bindingset[depth]
predicate end(Node n, int depth) { n.getName() = "end" and depth >= 0 }

bindingset[depth1]
bindingset[depth2]
predicate edge(LocalVariableDecl a, int depth1, LocalVariableDecl b, int depth2) {
depth2 = depth1 + 1 and
exists(LocalVariableDeclExpr declA, LocalVariableDeclExpr declB |
declA.getVariable() = a and
declB.getVariable() = b and
declA.getInit().(VarAccess).getVariable() = b
)
}
}

import CustomPathStateProblem<CallGraphPathStateProblemConfig>

from LocalVariableDecl start, LocalVariableDecl end
where problem(start, end)
select start, end, "Path from $@ to $@.", start.getName(), start, end.getName(), end
9 changes: 3 additions & 6 deletions java/test/qtil/java/graph/test.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
class Test {
public static void f1() {
int mid = 0;
int start = 0;
int end = 0;
int end = 42;
int mid = end;
int start = mid;
int unrelated = 0;
start = mid;
start = unrelated;
mid = end;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.javascript.locations.Locatable
private import javascript
// Import the javascript specific configuration for making custom path state problems.
import PathStateProblem<DbLocation, JavascriptLocatableConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.js:2:9:2:11 | mid | test.js:4:9:4:11 | end | | |
| test.js:3:9:3:13 | start | test.js:2:9:2:11 | mid | | |
nodes
| test.js:2:9:2:11 | mid | semmle.label | mid |
| test.js:3:9:3:13 | start | semmle.label | start |
| test.js:4:9:4:11 | end | semmle.label | end |
#select
| test.js:3:9:3:13 | start | test.js:4:9:4:11 | end | Path from $@ to $@. | start | test.js:3:9:3:13 | start | end | test.js:4:9:4:11 | end |
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Minimal test to make sure CustomPathStateProblem works with Javascript code.
import javascript
import qtil.javascript.graph.CustomPathStateProblem

module CallGraphPathStateProblemConfig implements CustomPathStateProblemConfigSig {
class Node = VarDecl;

class State = int; // Track search depth

predicate start(Node n, int depth) { n.getAVariable().getName() = "start" and depth = 0 }

bindingset[depth]
predicate end(Node n, int depth) { n.getAVariable().getName() = "end" and depth >= 0 }

bindingset[depth1]
bindingset[depth2]
predicate edge(VarDecl a, int depth1, VarDecl b, int depth2) {
depth2 = depth1 + 1 and
a.getAVariable().getAnAssignedExpr() = b.getAVariable().getAnAccess()
}
}

import CustomPathStateProblem<CallGraphPathStateProblemConfig>

from VarDecl start, VarDecl end
where problem(start, end)
select start, end, "Path from $@ to $@.", start.getAVariable().getName(), start,
end.getAVariable().getName(), end
5 changes: 5 additions & 0 deletions python/src/qtil/python/graph/CustomPathStateProblem.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
private import qtil.locations.CustomPathStateProblem
private import qtil.python.locations.Locatable
private import python
// Import the python specific configuration for making custom path state problems.
import PathStateProblem<Location, PythonLocatableConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
edges
| test.py:4:5:4:7 | mid | test.py:3:5:3:7 | end | | |
| test.py:5:5:5:9 | start | test.py:4:5:4:7 | mid | | |
nodes
| test.py:3:5:3:7 | end | semmle.label | end |
| test.py:4:5:4:7 | mid | semmle.label | mid |
| test.py:5:5:5:9 | start | semmle.label | start |
#select
| test.py:5:5:5:9 | start | test.py:3:5:3:7 | end | Path from $@ to $@. | start | test.py:5:5:5:9 | start | end | test.py:3:5:3:7 | end |
Loading
Loading