Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
35 changes: 3 additions & 32 deletions docs/fuzzing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,10 @@

# Fuzzing

## Installing `honggfuzz`

```
cargo install honggfuzz
```

Install [dependencies](https://github.com/rust-fuzz/honggfuzz-rs#dependencies) for your system.

## Running the fuzzer

Running the fuzzer is as easy as running in the `fuzz` directory.

Choose a target:

These are `[[bin]]` entries in `Cargo.toml`.
List them with `cargo read-manifest | jq '.targets[].name'` from the `fuzz` directory.

Run the fuzzer:

```shell
cargo install cargo-fuzz
cd fuzz
cargo hfuzz run <target>
```

After a panic is found, get a stack trace with:

```shell
cargo hfuzz run-debug <target> hfuzz_workspace/<target>/*.fuzz
cargo fuzz run fuzz_parse_sql -- -max_total_time=600
```

For example, with the `fuzz_parse_sql` target:

```shell
cargo hfuzz run fuzz_parse_sql
cargo hfuzz run-debug fuzz_parse_sql hfuzz_workspace/fuzz_parse_sql/*.fuzz
```
Crashes land in `artifacts/<target>/` and replay with `cargo fuzz run <target> <crash-file>`.
6 changes: 3 additions & 3 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
corpus
hfuzz_target
hfuzz_workspace
/artifacts
/corpus
/target
10 changes: 8 additions & 2 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
[package]
name = "fuzz"
version = "0.1.0"
edition = "2018"
edition = "2021"
publish = false

[package.metadata]
cargo-fuzz = true

[dependencies]
honggfuzz = "0.5.54"
libfuzzer-sys = "0.4"
sqlparser = { path = ".." }

# Prevent this from interfering with workspaces
Expand All @@ -32,3 +35,6 @@ members = ["."]
[[bin]]
name = "fuzz_parse_sql"
path = "fuzz_targets/fuzz_parse_sql.rs"
test = false
doc = false
bench = false
49 changes: 23 additions & 26 deletions fuzz/fuzz_targets/fuzz_parse_sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,33 @@
// specific language governing permissions and limitations
// under the License.

use honggfuzz::fuzz;
#![no_main]

use libfuzzer_sys::fuzz_target;
use sqlparser::dialect::{
AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, DuckDbDialect,
AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, Dialect, DuckDbDialect,
GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, OracleDialect, PostgreSqlDialect,
RedshiftSqlDialect, SQLiteDialect, SnowflakeDialect,
};
use sqlparser::parser::Parser;

fn main() {
let dialects: Vec<Box<dyn sqlparser::dialect::Dialect>> = vec![
Box::new(AnsiDialect::default()),
Box::new(BigQueryDialect::default()),
Box::new(ClickHouseDialect::default()),
Box::new(DatabricksDialect::default()),
Box::new(DuckDbDialect::default()),
Box::new(GenericDialect::default()),
Box::new(HiveDialect::default()),
Box::new(MsSqlDialect::default()),
Box::new(MySqlDialect::default()),
Box::new(OracleDialect::default()),
Box::new(PostgreSqlDialect::default()),
Box::new(RedshiftSqlDialect::default()),
Box::new(SQLiteDialect::default()),
Box::new(SnowflakeDialect::default()),
fuzz_target!(|sql: &str| {
let dialects: [&dyn Dialect; 14] = [
&AnsiDialect {},
&BigQueryDialect {},
&ClickHouseDialect {},
&DatabricksDialect {},
&DuckDbDialect {},
&GenericDialect {},
&HiveDialect {},
&MsSqlDialect {},
&MySqlDialect {},
&OracleDialect {},
&PostgreSqlDialect {},
&RedshiftSqlDialect {},
&SQLiteDialect {},
&SnowflakeDialect {},
];
loop {
fuzz!(|data: String| {
for dialect in &dialects {
let _ = Parser::parse_sql(dialect.as_ref(), &data);
}
});
for dialect in dialects {
let _ = Parser::parse_sql(dialect, sql);
}
}
});
Loading