Adds very basic SPARQL evaluation fuzzer

pull/307/head
Tpt 2 years ago committed by Thomas Tanon
parent 0ccdea2ff1
commit b7059d07e8
  1. 27
      Cargo.lock
  2. 1
      Cargo.toml
  3. 7
      fuzz/Cargo.toml
  4. 26
      fuzz/fuzz_targets/sparql_eval.rs
  5. 7
      fuzz/fuzz_targets/sparql_query.rs
  6. 6
      fuzz/fuzz_targets/sparql_update.rs
  7. 16
      lib/sparql-smith/Cargo.toml
  8. 44
      lib/sparql-smith/README.md
  9. 1522
      lib/sparql-smith/src/lib.rs

27
Cargo.lock generated

@ -40,6 +40,15 @@ version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "arbitrary"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60"
dependencies = [
"derive_arbitrary",
]
[[package]] [[package]]
name = "assert_cmd" name = "assert_cmd"
version = "2.0.6" version = "2.0.6"
@ -414,6 +423,17 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "derive_arbitrary"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9a577516173adb681466d517d39bd468293bc2c2a16439375ef0f35bba45f3d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "difflib" name = "difflib"
version = "0.4.0" version = "0.4.0"
@ -1587,6 +1607,13 @@ dependencies = [
"rand", "rand",
] ]
[[package]]
name = "sparql-smith"
version = "0.1.0-alpha.1"
dependencies = [
"arbitrary",
]
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.5.2" version = "0.5.2"

@ -5,6 +5,7 @@ members = [
"lib/oxrdf", "lib/oxrdf",
"lib/spargebra", "lib/spargebra",
"lib/sparesults", "lib/sparesults",
"lib/sparql-smith",
"python", "python",
"oxrocksdb-sys", "oxrocksdb-sys",
"server", "server",

@ -9,12 +9,19 @@ edition = "2021"
cargo-fuzz = true cargo-fuzz = true
[dependencies] [dependencies]
lazy_static = "1"
libfuzzer-sys = "0.4" libfuzzer-sys = "0.4"
spargebra = { path = "../lib/spargebra", features = ["rdf-star"] } spargebra = { path = "../lib/spargebra", features = ["rdf-star"] }
sparesults = { path = "../lib/sparesults", features = ["rdf-star"] } sparesults = { path = "../lib/sparesults", features = ["rdf-star"] }
sparql-smith = { path = "../lib/sparql-smith" }
oxigraph = { path = "../lib" }
[workspace] [workspace]
[[bin]]
name = "sparql_eval"
path = "fuzz_targets/sparql_eval.rs"
[[bin]] [[bin]]
name = "sparql_query" name = "sparql_query"
path = "fuzz_targets/sparql_query.rs" path = "fuzz_targets/sparql_query.rs"

@ -0,0 +1,26 @@
#![no_main]
use lazy_static::lazy_static;
use libfuzzer_sys::fuzz_target;
use oxigraph::io::DatasetFormat;
use oxigraph::sparql::Query;
use oxigraph::store::Store;
lazy_static! {
static ref STORE: Store = {
let store = Store::new().unwrap();
store
.load_dataset(
sparql_smith::DATA_TRIG.as_bytes(),
DatasetFormat::TriG,
None,
)
.unwrap();
store
};
}
fuzz_target!(|data: sparql_smith::Query| {
if let Ok(q) = Query::parse(&data.to_string(), None) {
STORE.query(q).unwrap();
}
});

@ -1,10 +1,7 @@
#![no_main] #![no_main]
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use spargebra::Query; use spargebra::Query;
use std::str;
fuzz_target!(|data: &[u8]| { fuzz_target!(|data: &str| {
if let Ok(data) = str::from_utf8(data) { Query::parse(data, None);
Query::parse(data, None);
}
}); });

@ -3,8 +3,6 @@ use libfuzzer_sys::fuzz_target;
use spargebra::Update; use spargebra::Update;
use std::str; use std::str;
fuzz_target!(|data: &[u8]| { fuzz_target!(|data: &str| {
if let Ok(data) = str::from_utf8(data) { Update::parse(data, None);
Update::parse(data, None);
}
}); });

@ -0,0 +1,16 @@
[package]
name = "sparql-smith"
version = "0.1.0-alpha.1"
authors = ["Tpt <thomas@pellissier-tanon.fr>"]
license = "MIT OR Apache-2.0"
readme = "README.md"
keywords = ["SPARQL"]
repository = "https://github.com/oxigraph/oxigraph/tree/main/lib/sparql-smith"
homepage = "https://oxigraph.org/"
description = """
A SPARQL test cases generator
"""
edition = "2021"
[dependencies]
arbitrary = { version = "1", features = ["derive"] }

@ -0,0 +1,44 @@
SPARQL smith
============
[![Latest Version](https://img.shields.io/crates/v/sparql-smith.svg)](https://crates.io/crates/sparql-smith)
[![Released API docs](https://docs.rs/sparql-smith/badge.svg)](https://docs.rs/sparql-smith)
[![Crates.io downloads](https://img.shields.io/crates/d/sparql-smith)](https://crates.io/crates/sparql-smith)
[![actions status](https://github.com/oxigraph/oxigraph/workflows/build/badge.svg)](https://github.com/oxigraph/oxigraph/actions)
[![Gitter](https://badges.gitter.im/oxigraph/community.svg)](https://gitter.im/oxigraph/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
sparql-smith is a test case generator for the [SPARQL](https://www.w3.org/TR/sparql11-overview/) language.
It provides a single struct, `Query` that could be serialized to a SPARQL query using `to_string()`.
The queries generated are sadly not always valid. Variables scopes are not properly handled yet.
All SPARQL features are not supported yet.
The `DATA_TRIG` constant is provided as an example dataset on which queries could be evaluated.
Usage example with [libfuzzer-sys](https://docs.rs/libfuzzer-sys) and [spargebra](https://docs.rs/spargebra):
```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: sparql_smith::Query| {
spargebra::Query::parse(&data.to_string(), None).unwrap()
});
```
## License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or
`<http://www.apache.org/licenses/LICENSE-2.0>`)
* MIT license ([LICENSE-MIT](../LICENSE-MIT) or
`<http://opensource.org/licenses/MIT>`)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Oxigraph by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save