Skip to content

Commit e205a68

Browse files
committed
feat(rust:) Add initial rusqlite support
1 parent 5bfd22e commit e205a68

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/rust-all
4+
extensible: sinkModel
5+
data:
6+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::execute", "Argument[0]", "sql-injection", "manual"]
7+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::execute_batch", "Argument[0]", "sql-injection", "manual"]
8+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::prepare", "Argument[0]", "sql-injection", "manual"]
9+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::prepare_with_flags", "Argument[0]", "sql-injection", "manual"]
10+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::query_row", "Argument[0]", "sql-injection", "manual"]
11+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::Connection>::query_row_and_then", "Argument[0]", "sql-injection", "manual"]

rust/ql/test/library-tests/frameworks/rusqlite/Rusqlite.expected

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import rust
2+
import codeql.rust.security.SqlInjectionExtensions
3+
import codeql.rust.Concepts
4+
import utils.test.InlineExpectationsTest
5+
6+
module RusqliteTest implements TestSig {
7+
string getARelevantTag() { result = ["sql-sink"] }
8+
9+
predicate hasActualResult(Location location, string element, string tag, string value) {
10+
exists(SqlInjection::Sink sink |
11+
location = sink.getLocation() and
12+
location.getFile().getBaseName() != "" and
13+
element = sink.toString() and
14+
tag = "sql-sink" and
15+
value = ""
16+
)
17+
}
18+
}
19+
20+
import MakeTest<RusqliteTest>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[workspace]
2+
3+
[package]
4+
name = "rusqlite-test"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
[dependencies]
9+
rusqlite = { version = "0.33", features = ["bundled"] }
10+
11+
[[bin]]
12+
name = "rusqlite"
13+
path = "./main.rs"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
use rusqlite::Connection;
3+
4+
#[derive(Debug)]
5+
struct Person {
6+
id: i32,
7+
name: String,
8+
age: i32,
9+
}
10+
11+
fn main() -> Result<(), Box<dyn std::error::Error>> {
12+
// Get input from CLI
13+
let args: Vec<String> = std::env::args().collect();
14+
let name = &args[1];
15+
let age = &args[2];
16+
17+
let connection = Connection::open_in_memory()?;
18+
19+
connection.execute( // $ sql-sink
20+
"CREATE TABLE person (
21+
id SERIAL PRIMARY KEY,
22+
name VARCHAR NOT NULL,
23+
age INT NOT NULL
24+
)",
25+
(),
26+
)?;
27+
28+
let query = format!("INSERT INTO person (name, age) VALUES ('{}', '{}')", name, age);
29+
30+
connection.execute(&query, ())?; // $ sql-sink
31+
32+
let person = connection.query_row(&query, (), |row| { // $ sql-sink
33+
Ok(Person {
34+
id: row.get(0)?,
35+
name: row.get(1)?,
36+
age: row.get(2)?,
37+
})
38+
})?;
39+
40+
let mut stmt = connection.prepare("SELECT id, name, age FROM person")?; // $ sql-sink
41+
let people = stmt.query_map([], |row| {
42+
Ok(Person {
43+
id: row.get(0)?,
44+
name: row.get(1)?,
45+
age: row.get(2)?,
46+
})
47+
})?;
48+
49+
Ok(())
50+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
qltest_cargo_check: true
2+
qltest_dependencies:
3+
- rusqlite = { version = "0.33", features = ["bundled"] }

0 commit comments

Comments
 (0)