Skip to content

Commit e07b25c

Browse files
authored
Merge pull request github#18577 from GeekMasher/rust-rusqlite
Rust: Add initial RuSQLite support
2 parents aa43d50 + 1b30847 commit e07b25c

File tree

6 files changed

+114
-0
lines changed

6 files changed

+114
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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"]
12+
13+
- addsTo:
14+
pack: codeql/rust-all
15+
extensible: sourceModel
16+
data:
17+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::row::Row>::get", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "database", "manual"]
18+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::row::Row>::get_unwrap", "ReturnValue", "database", "manual"]
19+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::row::Row>::get_ref", "ReturnValue.Variant[crate::result::Result::Ok(0)]", "database", "manual"]
20+
- ["repo:https://github.com/rusqlite/rusqlite:rusqlite", "<crate::row::Row>::get_ref_unwrap", "ReturnValue", "database", "manual"]

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

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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", "database-read"] }
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+
or
18+
exists(ModeledDatabaseSource sink |
19+
location = sink.getLocation() and
20+
location.getFile().getBaseName() != "" and
21+
element = sink.toString() and
22+
tag = "database-read" and
23+
value = ""
24+
)
25+
}
26+
}
27+
28+
import MakeTest<RusqliteTest>
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"
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 INTEGER PRIMARY KEY AUTOINCREMENT,
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)?, // $ database-read
35+
name: row.get(1)?, // $ database-read
36+
age: row.get(2)?, // $ database-read
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_unwrap(0), // $ database-read
44+
name: row.get_unwrap(1), // $ database-read
45+
age: row.get_unwrap(2), // $ database-read
46+
})
47+
})?;
48+
49+
Ok(())
50+
}
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)