Fuzzer: SPARQL results: Makes the fuzzers test serialization too

pull/409/head
Tpt 1 year ago committed by Thomas Tanon
parent 9063867ec9
commit fab5db9511
  1. 5
      fuzz/Cargo.toml
  2. 15
      fuzz/fuzz_targets/sparql_results_json.rs
  3. 10
      fuzz/fuzz_targets/sparql_results_tsv.rs
  4. 10
      fuzz/fuzz_targets/sparql_results_xml.rs
  5. 1
      fuzz/src/lib.rs
  6. 63
      fuzz/src/result_format.rs

@ -9,6 +9,7 @@ edition = "2021"
cargo-fuzz = true
[dependencies]
anyhow = "1"
lazy_static = "1"
libfuzzer-sys = "0.4"
spargebra = { path = "../lib/spargebra", features = ["rdf-star", "sep-0006"] }
@ -16,6 +17,10 @@ sparesults = { path = "../lib/sparesults", features = ["rdf-star"] }
sparql-smith = { path = "../lib/sparql-smith", features = ["sep-0006"] }
oxigraph = { path = "../lib" }
[profile.release]
codegen-units = 1
debug = true
[workspace]
[[bin]]

@ -1,15 +1,6 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use sparesults::{QueryResultsFormat, QueryResultsParser, QueryResultsReader};
use oxigraph_fuzz::result_format::fuzz_result_format;
use sparesults::QueryResultsFormat;
fuzz_target!(|data: &[u8]| {
let parser = QueryResultsParser::from_format(QueryResultsFormat::Json);
if let Ok(QueryResultsReader::Solutions(solutions)) = parser.read_results(data) {
for s in solutions {
if s.is_err() {
// TODO: avoid infinite loop of errors
break;
}
}
}
});
fuzz_target!(|data: &[u8]| { fuzz_result_format(QueryResultsFormat::Json, data) });

@ -1,10 +1,6 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use sparesults::{QueryResultsFormat, QueryResultsParser, QueryResultsReader};
use oxigraph_fuzz::result_format::fuzz_result_format;
use sparesults::QueryResultsFormat;
fuzz_target!(|data: &[u8]| {
let parser = QueryResultsParser::from_format(QueryResultsFormat::Tsv);
if let Ok(QueryResultsReader::Solutions(solutions)) = parser.read_results(data) {
for _ in solutions {}
}
});
fuzz_target!(|data: &[u8]| { fuzz_result_format(QueryResultsFormat::Tsv, data) });

@ -1,10 +1,6 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use sparesults::{QueryResultsFormat, QueryResultsParser, QueryResultsReader};
use oxigraph_fuzz::result_format::fuzz_result_format;
use sparesults::QueryResultsFormat;
fuzz_target!(|data: &[u8]| {
let parser = QueryResultsParser::from_format(QueryResultsFormat::Xml);
if let Ok(QueryResultsReader::Solutions(solutions)) = parser.read_results(data) {
for _ in solutions {}
}
});
fuzz_target!(|data: &[u8]| { fuzz_result_format(QueryResultsFormat::Xml, data) });

@ -0,0 +1 @@
pub mod result_format;

@ -0,0 +1,63 @@
use anyhow::Context;
use sparesults::{
QueryResultsFormat, QueryResultsParser, QueryResultsReader, QueryResultsSerializer,
};
pub fn fuzz_result_format(format: QueryResultsFormat, data: &[u8]) {
let parser = QueryResultsParser::from_format(format);
let serializer = QueryResultsSerializer::from_format(format);
let Ok(reader) = parser.read_results(data) else {
return;
};
match reader {
QueryResultsReader::Solutions(solutions) => {
let Ok(solutions) = solutions.collect::<Result<Vec<_>, _>>() else {
return;
};
// We try to write again
let mut writer = serializer
.solutions_writer(
Vec::new(),
solutions
.get(0)
.map_or_else(Vec::new, |s| s.variables().to_vec()),
)
.unwrap();
for solution in &solutions {
writer.write(solution).unwrap();
}
let serialized = String::from_utf8(writer.finish().unwrap()).unwrap();
// And to parse again
if let QueryResultsReader::Solutions(roundtrip_solutions) = parser
.read_results(serialized.as_bytes())
.with_context(|| format!("Parsing {:?}", &serialized))
.unwrap()
{
assert_eq!(
roundtrip_solutions
.collect::<Result<Vec<_>, _>>()
.with_context(|| format!("Parsing {:?}", &serialized))
.unwrap(),
solutions
)
}
}
QueryResultsReader::Boolean(value) => {
// We try to write again
let mut serialized = Vec::new();
serializer
.write_boolean_result(&mut serialized, value)
.unwrap();
// And to parse again
if let QueryResultsReader::Boolean(roundtrip_value) =
parser.read_results(serialized.as_slice()).unwrap()
{
assert_eq!(roundtrip_value, value)
}
}
}
}
Loading…
Cancel
Save