Skip to content

Commit b3bcf75

Browse files
committed
Add url fuzz target
1 parent 1884056 commit b3bcf75

4 files changed

Lines changed: 75 additions & 2 deletions

File tree

fuzz/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ name = "uri_deserialize_pjuri"
2929
path = "fuzz_targets/uri/deserialize_pjuri.rs"
3030
doc = false
3131
bench = false
32+
33+
[[bin]]
34+
name = "url_decode_url"
35+
path = "fuzz_targets/url/decode_url.rs"
36+
doc = false
37+
bench = false

fuzz/cycle.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
# Continuously cycle over fuzz targets running each for 1 hour.
44
# It uses chrt SCHED_IDLE so that other process takes priority.
5+
# A number of concurrent forks can be applied for parallelization. Be sure to leave one or two available CPUs open for the OS.
56
#
67
# For cargo-fuzz usage see https://github.com/rust-fuzz/cargo-fuzz?tab=readme-ov-file#usage
78

89
set -euo pipefail
910

11+
FORKS=${1:-1}
1012
REPO_DIR=$(git rev-parse --show-toplevel)
1113
# can't find the file because of the ENV var
1214
# shellcheck source=/dev/null
@@ -17,7 +19,7 @@ while :; do
1719
targetName=$(targetFileToName "$targetFile")
1820
echo "Fuzzing target $targetName ($targetFile)"
1921
# fuzz for one hour
20-
cargo +nightly fuzz run "$targetName" -- -max_total_time=3600
22+
cargo +nightly fuzz run "$targetName" -- -max_total_time=3600 -fork="$FORKS"
2123
# minimize the corpus
2224
cargo +nightly fuzz cmin "$targetName"
2325
done

fuzz/fuzz.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
#!/usr/bin/env bash
22

33
# This script is used to briefly fuzz every target when no target is provided. Otherwise, it will briefly fuzz the provided target
4+
# When fuzzing with a specific target a number of concurrent forks can be applied. Be sure to leave one or two available CPUs open for the OS.
45

56
set -euo pipefail
67

78
TARGET=""
9+
FORKS=1
810

911
if [[ $# -gt 0 ]]; then
1012
TARGET="$1"
1113
shift
1214
fi
1315

16+
if [[ $# -gt 0 ]]; then
17+
FORKS="$1"
18+
shift
19+
fi
20+
1421
REPO_DIR=$(git rev-parse --show-toplevel)
1522

1623
# can't find the file because of the ENV var
@@ -26,5 +33,5 @@ fi
2633
for targetFile in $targetFiles; do
2734
targetName=$(targetFileToName "$targetFile")
2835
echo "Fuzzing target $targetName ($targetFile)"
29-
cargo fuzz run "$targetName" -- -max_total_time=30
36+
cargo fuzz run "$targetName" -- -max_total_time=30 -fork="$FORKS"
3037
done
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#![no_main]
2+
3+
use std::str;
4+
5+
use libfuzzer_sys::fuzz_target;
6+
// Adjust this path to wherever your Url module lives in your crate.
7+
use payjoin::Url;
8+
9+
fn do_test(data: &[u8]) {
10+
let Ok(s) = str::from_utf8(data) else { return };
11+
12+
let Ok(mut url) = Url::parse(s) else { return };
13+
14+
let _ = url.scheme();
15+
let _ = url.has_host();
16+
let _ = url.domain();
17+
let _ = url.host_str();
18+
let _ = url.port();
19+
let _ = url.path();
20+
let _ = url.query();
21+
let _ = url.fragment();
22+
let _ = url.as_str();
23+
let _ = url.to_string();
24+
if let Some(segs) = url.path_segments() {
25+
let _ = segs.collect::<Vec<_>>();
26+
}
27+
28+
let raw = url.as_str().to_owned();
29+
if let Ok(reparsed) = Url::parse(&raw) {
30+
assert_eq!(
31+
reparsed.as_str(),
32+
raw,
33+
"round-trip mismatch: first={raw:?} second={:?}",
34+
reparsed.as_str()
35+
);
36+
}
37+
38+
url.set_port(Some(8080));
39+
url.set_port(None);
40+
url.set_fragment(Some("fuzz"));
41+
url.set_fragment(None);
42+
url.set_query(Some("k=v"));
43+
url.set_query(None);
44+
url.query_pairs_mut().append_pair("fuzz_key", "fuzz_val");
45+
46+
if let Some(mut segs) = url.path_segments_mut() {
47+
segs.push("fuzz_segment");
48+
}
49+
50+
let _ = url.join("relative/path");
51+
let _ = url.join("/absolute/path");
52+
let _ = url.join("../dotdot");
53+
let _ = url.join("https://other.example.com/new");
54+
}
55+
56+
fuzz_target!(|data| {
57+
do_test(data);
58+
});

0 commit comments

Comments
 (0)