Skip to content
Merged
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
9 changes: 8 additions & 1 deletion rust/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -57,3 +57,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "fuzztest_clippy",
deps = [
":fuzztest",
],
)
9 changes: 8 additions & 1 deletion rust/coverage/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -48,3 +48,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "coverage_clippy",
deps = [
":coverage",
],
)
9 changes: 8 additions & 1 deletion rust/engine/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library")

licenses(["notice"])

Expand All @@ -30,3 +30,10 @@ rust_library(
"@com_google_fuzztest//centipede:engine_worker",
],
)

rust_clippy(
name = "engine_clippy",
deps = [
":engine",
],
)
5 changes: 1 addition & 4 deletions rust/engine/src/engine_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,7 @@ impl FuzzTestUint64sView {
if self.data.is_null() {
&[]
} else {
ptr::slice_from_raw_parts(
self.data as *const u8,
self.size * core::mem::size_of::<u64>(),
)
ptr::slice_from_raw_parts(self.data as *const u8, self.size * size_of::<u64>())
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions rust/engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(clippy::absolute_paths)]
#![deny(unused_imports)]

pub mod engine_ffi;

use std::marker::PhantomData;
Expand Down
9 changes: 8 additions & 1 deletion rust/options/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -42,3 +42,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "fuzztest_options_clippy",
deps = [
":fuzztest_options",
],
)
7 changes: 5 additions & 2 deletions rust/options/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// This module provides the core command-line flag and environment variable options
// structure (`FuzzTestOptions`) and domain execution modes (`ExecutionMode`).
//! This module provides the core command-line flag and environment variable options
//! structure (`FuzzTestOptions`) and domain execution modes (`ExecutionMode`).

#![deny(clippy::absolute_paths)]
#![deny(unused_imports)]

use clap::{Parser, ValueEnum};
use humantime::Duration;
Expand Down
4 changes: 3 additions & 1 deletion rust/src/domains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub mod containers;
pub mod range;
pub mod tuple_of;
pub mod utility;
use ::serde::de::DeserializeOwned;
use ::serde::Serialize;

use anyhow;
use anyhow::Context;
Expand Down Expand Up @@ -118,7 +120,7 @@ pub trait Domain {
/// the CorpusValue could the owned data structured that the `&str` points to (eg: String).
/// The CorpusValue type should implement `serde::Serialize`, `serde::de::DeserializeOwned` and
/// `Clone`.
type CorpusValue: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone;
type CorpusValue: Serialize + DeserializeOwned + Clone;

/// Initializes a new value drawn from the domain.
fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue>;
Expand Down
27 changes: 11 additions & 16 deletions rust/src/domains/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use super::utility::choose_value;
use super::utility::mutate_integer;
use super::utility::shrink_towards;
use super::Domain;
use std::char;
use std::marker::PhantomData;

use anyhow;
use rand::RngExt;
Expand All @@ -39,9 +41,8 @@ use rand::RngExt;
/// let sample = arbitrary_i32.init(&mut rng);
/// assert!(sample.is_ok());
/// ```

pub struct Arbitrary<T> {
_phantom: std::marker::PhantomData<T>,
_phantom: PhantomData<T>,
}

impl<T> Clone for Arbitrary<T> {
Expand All @@ -59,14 +60,14 @@ impl<T> std::fmt::Debug for Arbitrary<T> {
// We cannot just use `#[derive(Default)]` because `T` might not be `Default`.
impl<T> Default for Arbitrary<T> {
fn default() -> Self {
Self { _phantom: std::marker::PhantomData }
Self { _phantom: PhantomData }
}
}

impl<T> Arbitrary<T> {
/// Creates a new `Arbitrary` domain for the given type `T`.
pub fn new() -> Self {
Self { _phantom: std::marker::PhantomData }
Self { _phantom: PhantomData }
}
}

Expand Down Expand Up @@ -254,7 +255,7 @@ fn map_int_to_char(u: u32) -> char {
NUM_VALID_CODEPOINTS
);
let val = if u >= SURROGATE_START { u + (SURROGATE_END - SURROGATE_START + 1) } else { u };
std::char::from_u32(val).unwrap()
char::from_u32(val).unwrap()
}

impl Domain for Arbitrary<char> {
Expand Down Expand Up @@ -745,19 +746,13 @@ mod tests {
assert_eq!(map_int_to_char(0), '\u{0000}');

let before_surrogate = SURROGATE_START - 1;
assert_eq!(
map_char_to_int(std::char::from_u32(before_surrogate).unwrap()),
before_surrogate
);
assert_eq!(
map_int_to_char(before_surrogate),
std::char::from_u32(before_surrogate).unwrap()
);
assert_eq!(map_char_to_int(char::from_u32(before_surrogate).unwrap()), before_surrogate);
assert_eq!(map_int_to_char(before_surrogate), char::from_u32(before_surrogate).unwrap());

let after_surrogate = SURROGATE_END + 1;
let mapped_after_surrogate = map_char_to_int(std::char::from_u32(after_surrogate).unwrap());
let mapped_after_surrogate = map_char_to_int(char::from_u32(after_surrogate).unwrap());
assert_eq!(mapped_after_surrogate, SURROGATE_START);
assert_eq!(map_int_to_char(SURROGATE_START), std::char::from_u32(after_surrogate).unwrap());
assert_eq!(map_int_to_char(SURROGATE_START), char::from_u32(after_surrogate).unwrap());

assert_eq!(map_char_to_int('\u{10FFFF}'), NUM_VALID_CODEPOINTS - 1);
assert_eq!(map_int_to_char(NUM_VALID_CODEPOINTS - 1), '\u{10FFFF}');
Expand All @@ -776,7 +771,7 @@ mod tests {
while value != '\0' && iterations < MAX_ITERATIONS {
domain.mutate(&mut value, &mut rng, true).unwrap();
// Ensure that the value is always a valid char after mutation.
assert!(std::char::from_u32(value as u32).is_some());
assert!(char::from_u32(value as u32).is_some());
iterations += 1;
}
assert_eq!(
Expand Down
24 changes: 10 additions & 14 deletions rust/src/domains/utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use num_traits::PrimInt;
use rand::distr::uniform::SampleUniform;
use rand::distr::{Distribution, StandardUniform};
use rand::RngExt;
use std::fmt::Display;

/// Shrinks a `val` towards a `target` value.
///
Expand All @@ -32,7 +33,7 @@ use rand::RngExt;
/// * `target`: The value to shrink towards.
pub fn shrink_towards<T, R: rand::Rng + ?Sized>(rng: &mut R, val: T, target: T) -> T
where
T: SampleUniform + PartialOrd + Copy + std::fmt::Display,
T: SampleUniform + PartialOrd + Copy + Display,
{
match val.partial_cmp(&target) {
Some(Ordering::Equal) => val,
Expand Down Expand Up @@ -81,7 +82,7 @@ pub fn mutate_integer<T, R: rand::Rng + ?Sized>(
max_value: Option<T>,
) -> T
where
T: PrimInt + SampleUniform + std::fmt::Display,
T: PrimInt + SampleUniform + Display,
{
assert!(range > T::zero(), "mutate_integer: range value cannot be <= 0: {range}");

Expand All @@ -106,7 +107,7 @@ where
}
1 => {
// 1/3 chance: Flip a random bit
let num_bits = std::mem::size_of::<T>() * 8;
let num_bits = size_of::<T>() * 8;
let bit_index = rng.random_range(0..num_bits);
let mask = T::one() << bit_index;
let result = val ^ mask;
Expand Down Expand Up @@ -194,7 +195,7 @@ impl SpecialValues for char {
///
/// # Type Parameters
/// * `T`: The type of the value to choose. Must implement `SpecialValues` and
/// `StandardUniform` must be able to generate values of type `T`.
/// `StandardUniform` must be able to generate values of type `T`.
pub fn choose_value<T, R: rand::Rng + ?Sized>(rng: &mut R) -> T
where
T: SpecialValues + 'static,
Expand All @@ -217,7 +218,7 @@ pub fn mutate_float<T, R: rand::Rng + ?Sized>(
_range: Option<(T, T)>, // TODO: Implement range support for floats.
) -> anyhow::Result<()>
where
T: num_traits::Float + SampleUniform + std::fmt::Display + Copy + SpecialValues + 'static,
T: num_traits::Float + SampleUniform + Display + Copy + SpecialValues + 'static,
StandardUniform: Distribution<T>,
{
if only_shrink {
Expand Down Expand Up @@ -259,14 +260,15 @@ mod tests {
rngs::{SmallRng, SysRng},
SeedableRng,
};
use std::fmt::Debug;

fn get_rng() -> SmallRng {
SmallRng::try_from_rng(&mut SysRng).unwrap()
}

fn check_shrink_towards<T>(smaller: T, larger: T)
where
T: SampleUniform + PartialOrd + Copy + std::fmt::Display + std::fmt::Debug + PartialEq,
T: SampleUniform + PartialOrd + Copy + Display + Debug + PartialEq,
{
let mut rng = get_rng();

Expand Down Expand Up @@ -317,7 +319,7 @@ mod tests {

fn check_mutate_integer<T>()
where
T: PrimInt + SampleUniform + std::fmt::Display + std::fmt::Debug + SpecialValues + 'static,
T: PrimInt + SampleUniform + Display + Debug + SpecialValues + 'static,
StandardUniform: Distribution<T>,
{
let mut rng = get_rng();
Expand Down Expand Up @@ -369,13 +371,7 @@ mod tests {

fn check_mutate_float<T>()
where
T: num_traits::Float
+ SampleUniform
+ std::fmt::Display
+ std::fmt::Debug
+ Copy
+ SpecialValues
+ 'static,
T: num_traits::Float + SampleUniform + Display + Debug + Copy + SpecialValues + 'static,
StandardUniform: Distribution<T>,
{
let mut rng = get_rng();
Expand Down
3 changes: 2 additions & 1 deletion rust/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait FuzzTest {
/// (will attempt to downcast to actual user values).
///
/// Returns `true` if the property function holds, `false` if it crashes.
fn execute<'a>(&self, args: &'a GenericCorpusValue) -> bool;
fn execute(&self, args: &GenericCorpusValue) -> bool;
fn print_finding_report(&self);
fn domains(&self) -> &dyn GenericDomain;
}
Expand All @@ -57,6 +57,7 @@ pub struct FuzzTestRegistration {

inventory::collect!(FuzzTestRegistration);

#[allow(clippy::type_complexity)]
pub static FUZZ_TEST_NAME_TO_FACTORY: LazyLock<HashMap<&str, fn() -> BoxedFuzzTest>> =
LazyLock::new(|| {
inventory::iter
Expand Down
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(clippy::absolute_paths)]
#![deny(unused_imports)]
#![feature(cfg_sanitize)]

mod crash_handler;
Expand Down
6 changes: 4 additions & 2 deletions rust/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ use crate::internal::FuzzTestRegistration;
use ::engine::engine_ffi;
use anyhow::Context;
use clap::Parser;
use std::env;
use std::ffi::CString;
use std::ffi::OsString;
use std::iter;
use std::path::Path;
use std::sync::OnceLock;
use tempfile::{NamedTempFile, TempDir};
Expand All @@ -34,7 +36,7 @@ pub fn get_fuzztest_options() -> &'static FuzzTestOptions {
// from environment variables (like `FUZZTEST_FUZZ_FOR` etc.). We (currently) do not envisage
// support for passing flags on cli as the Rust's libtest harness does not support custom
// flags.
OPTIONS.get_or_init(|| FuzzTestOptions::parse_from(std::iter::empty::<OsString>()))
OPTIONS.get_or_init(|| FuzzTestOptions::parse_from(iter::empty::<OsString>()))
}

trait ExecutionModeExt {
Expand Down Expand Up @@ -155,7 +157,7 @@ impl CentipedeArgs {
// ==============================================================================
// 1. Common Base Arguments (Required across all Centipede executions)
// ==============================================================================
let argv0 = std::env::args().next().context("while attempting to get argv[0]")?;
let argv0 = env::args().next().context("while attempting to get argv[0]")?;

add_arg(format!("--binary={argv0} {current_test_name} --exact --nocapture"))?;
let normalized_test_name = current_test_name.replace("::", ".");
Expand Down
Loading
Loading