Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
test-fuzz — Rust-Makros und Cargo-Subcommand zur Automatisierung von Fuzzing mit afl.rs, einschließlich Korpusgenerierung und Harness-Implementierung, integriert in Rusts Testframework. | Kitploit
Tools/GitHubGitHub/trailofbits/test-fuzz
Dynamische Analyse (Sandboxing)SchwachstellenanalyseCode-AnalyseFuzzing
GitHubtrailofbits/test-fuzz

test-fuzz

Rust-Makros und Cargo-Subcommand zur Automatisierung von Fuzzing mit afl.rs, einschließlich Korpusgenerierung und Harness-Implementierung, integriert in Rusts Testframework.

Repository anzeigen
20827vor 11 TagenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Webseite
Teilen

test-fuzz

test-fuzz ist ein Cargo-Subcommand und eine Sammlung von Rust-Makros, um bestimmte Aufgaben im Zusammenhang mit Fuzzing mit afl.rs zu automatisieren, darunter:

  • Generieren eines Fuzzing-Korpus
  • Implementieren einer Fuzzing-Harness

test-fuzz erreicht dies (teilweise) mithilfe der Testfunktionen von Rust. Um beispielsweise ein Fuzzing-Korpus zu generieren, zeichnet test-fuzz die Argumente eines Ziels jedes Mal auf, wenn es während eines Aufrufs von cargo test aufgerufen wird. Ebenso implementiert test-fuzz eine Fuzzing-Harness als zusätzlichen Test in einem von cargo-test generierten Binary. Diese enge Integration mit den Testfunktionen von Rust ist der Grund für den Namen test-fuzz.

Inhaltsverzeichnis

  1. Installation
  2. [Überblick]
  3. [Komponenten]
    • test_fuzz-Makro
    • test_fuzz_impl-Makro
    • [cargo test-fuzz-Befehl]
    • [Praktische Funktionen und Makros]
  4. [test-fuzz-Paket-Features]
  5. [Automatisch generierte Korpusdateien]
  6. [Umgebungsvariablen]
  7. [Einschränkungen]
  8. [Tipps und Tricks]
  9. [Semantische Versionsrichtlinie]
  10. [Lizenz]

Installation

Installiere cargo-test-fuzz und afl.rs mit dem folgenden Befehl:```sh cargo install cargo-test-fuzz cargo-afl

root@kitploit:~
## Übersicht

Fuzzing mit `test-fuzz` besteht im Wesentlichen aus drei Schritten:\*

1. **Identifiziere ein Fuzz-Ziel**:
   - Füge die folgenden `dependencies` zur `Cargo.toml`-Datei des Ziel-Crates hinzu:
     ```toml
     serde = "*"
     test-fuzz = "*"
     ```
   - Setze das [`test_fuzz`]-Makro vor die Zielfunktion:
     ```rust
     #[test_fuzz::test_fuzz]
     fn foo(...) {
         ...
     }
     ```
2. **Generiere einen Korpus**, indem du `cargo test` ausführst:   ```
   cargo test
  1. Fuzze dein Ziel, indem du cargo test-fuzz ausführst: ``` cargo test-fuzz foo
    root@kitploit:~

* Ein zusätzlicher, vorbereitender Schritt kann nach einem Neustart erforderlich sein:```sh cargo afl system-config

root@kitploit:~
Note that the above command runs `sudo` internally. Hence, you may be prompted to enter your password.

## Komponenten

### `test_fuzz`-Makro

Das Voranstellen des `test_fuzz`-Makros vor eine Funktion kennzeichnet diese als Fuzz-Target.

Die Hauptwirkungen des `test_fuzz`-Makros sind:

- Fügt dem Target Instrumentierung hinzu, um seine Argumente zu serialisieren und bei jedem Aufruf des Targets in eine Corpus-Datei zu schreiben. Die Instrumentierung ist durch `#[cfg(test)]` geschützt, sodass Corpus-Dateien nur bei der Ausführung von Tests erzeugt werden (siehe jedoch [`enable_in_production`] unten).
- Fügt einen Test hinzu, der Argumente von der Standardeingabe liest und deserialisiert und das Target darauf anwendet. Der Test prüft eine Umgebungsvariable, die von [`cargo test-fuzz`] gesetzt wird, sodass der Test während eines normalen Aufrufs von `cargo test` nicht versucht, blockierend von der Standardeingabe zu lesen. Der Test ist in ein Modul eingebettet, um die Wahrscheinlichkeit einer Namenskollision zu verringern. Derzeit lautet der Name des Moduls `target_fuzz`, wobei `target` der Name des Targets ist (siehe jedoch [`rename`] unten).

#### Argumente

##### `bounds = "where_predicates"`

Erzwingt `where_predicates` (z. B. Trait-Bounds) für die Struktur, die zum Serialisieren/Deserialisieren von Argumenten verwendet wird. Dies kann z. B. erforderlich sein, wenn der Argumenttyp eines Targets ein assoziierter Typ ist. Ein Beispiel finden Sie unter [associated_type.rs] in diesem Repository.

##### `generic_args = "parameters"`

Verwenden Sie `parameters` als Typparameter des Targets beim Fuzzing. Beispiel:```rust
#[test_fuzz(generic_args = "String")]
fn foo<T: Clone + Debug + Serialize>(x: &T) {
    ...
}

Hinweis: Die Argumente des Ziels müssen für jede Instanziierung seiner Typparameter serialisierbar sein. Die Argumente des Ziels müssen jedoch nur dann deserialisierbar sein, wenn das Ziel mit parameters instanziiert wird.

impl_generic_args = "parameters"

Verwende parameters als Self-Typparameter des Ziels beim Fuzzing. Beispiel:```rust #[test_fuzz_impl] impl<T: Clone + Debug + Serialize> for Foo { #[test_fuzz(impl_generic_args = "String")] fn bar(&self, x: &T) { ... } }

root@kitploit:~
Hinweis: Die Argumente des Ziels müssen für **jede** Instanziierung seiner `Self`-Typparameter serialisierbar sein. Allerdings müssen die Argumente des Ziels nur dann deserialisierbar sein, wenn das `Self` des Ziels mit `parameters` instanziiert wird.

##### `convert = "X, Y"`

Beim Serialisieren der Argumente des Ziels werden Werte des Typs `X` in den Typ `Y` konvertiert – unter Verwendung der Implementierung von `From<X>` durch `Y` – oder Werte des Typs `&X` in den Typ `Y` – unter Verwendung der Implementierung des nicht standardmäßigen Traits `test_fuzz::FromRef<X>` durch `Y`. Beim Deserialisieren werden diese Werte unter Verwendung der Implementierung des nicht standardmäßigen Traits `test_fuzz::Into<X>` durch `Y` zurück in den Typ `X` konvertiert.

Das heißt, die Verwendung von `convert = "X, Y"` muss von bestimmten Implementierungen begleitet sein. Wenn `X` [`Clone`] implementiert, dann kann `Y` Folgendes implementieren:```rust
impl From<X> for Y {
    fn from(x: X) -> Self {
        ...
    }
}

Wenn X Clone nicht implementiert, dann muss Y Folgendes implementieren:```rust impl test_fuzz::FromRef for Y { fn from_ref(x: &X) -> Self { ... } }

root@kitploit:~
Zusätzlich muss `Y` das Folgende implementieren (unabhängig davon, ob `X` [`Clone`] implementiert):```rust
impl test_fuzz::Into<X> for Y {
    fn into(self) -> X {
        ...
    }
}

Die Definition von test_fuzz::Into ist identisch mit der von std::convert::Into. Der Grund für die Verwendung eines nicht standardkonformen Traits ist es, Konflikte zu vermeiden, die durch Blanket-Implementierungen von Standard-Traits entstehen könnten.

enable_in_production

Erzeugen Sie Korpusdateien, wenn keine Tests ausgeführt werden, sofern die Umgebungsvariable TEST_FUZZ_WRITE gesetzt ist. Standardmäßig werden Korpusdateien nur beim Ausführen von Tests erzeugt, unabhängig davon, ob TEST_FUZZ_WRITE gesetzt ist. Wenn Sie ein Target von außerhalb seines Paketverzeichnisses ausführen, setzen Sie TEST_FUZZ_MANIFEST_PATH auf den Pfad der Cargo.toml-Datei des Pakets.

WARNUNG: Das Setzen von enable_in_production könnte einen Denial-of-Service-Vektor einführen. Wenn diese Option beispielsweise für eine Funktion gesetzt wird, die viele Male mit unterschiedlichen Argumenten aufgerufen wird, könnte dies die Festplatte füllen. Die Prüfung von TEST_FUZZ_WRITE soll einen gewissen Schutz gegen diese Möglichkeit bieten. Dennoch sollten Sie diese Option vor der Verwendung sorgfältig abwägen.

execute_with = "function"

Anstatt das Target direkt aufzurufen:

  • eine Closure des Typs FnOnce() -> R konstruieren, wobei R der Rückgabetyp des Targets ist, sodass der Aufruf der Closure das Target aufruft;
  • function mit der Closure aufrufen.

Das Target auf diese Weise aufzurufen, ermöglicht es function, die Umgebung des Aufrufs einzurichten. Dies kann beispielsweise beim Fuzzing von Substrate externalities nützlich sein.

no_auto_generate

Versuchen Sie nicht, für das Target [Korpusdateien automatisch zu generieren].

only_generic_args

Erfassen Sie die generischen Argumente des Targets beim Ausführen von Tests, generieren Sie jedoch keine Korpusdateien und implementieren Sie keine Fuzzing-Harness. Dies kann nützlich sein, wenn das Target eine generische Funktion ist, aber unklar ist, welche Typparameter für das Fuzzing verwendet werden sollten.

Der vorgesehene Arbeitsablauf ist: Aktivieren Sie only_generic_args, führen Sie dann cargo test und anschließend cargo test-fuzz --display generic-args aus. Eines der resultierenden generischen Argumente könnte als parameters von generic_args verwendbar sein. Ebenso könnten generische Argumente, die aus cargo test-fuzz --display impl-generic-args resultieren, als parameters von impl_generic_args verwendbar sein.

Beachten Sie jedoch, dass allein die Tatsache, dass ein Target während Tests mit bestimmten Parametern aufgerufen wurde, nicht bedeutet, dass die Argumente des Targets serialisierbar/deserialisierbar sind, wenn diese Parameter verwendet werden. Die Ergebnisse von --display generic-args/--display impl-generic-args sind lediglich Hinweise.

rename = "name"

Behandeln Sie das Target so, als ob sein Name name wäre, wenn ein Modul zum umgebenden Gültigkeitsbereich hinzugefügt wird. Die Expansion des Makros test_fuzz fügt dem umgebenden Gültigkeitsbereich eine Moduldefinition hinzu. Standardmäßig wird das Modul wie folgt benannt:

  • Wenn das Target nicht in einem impl-Block vorkommt, wird das Modul target_fuzz__ genannt, wobei target der Name des Targets ist.
  • Wenn das Target in einem impl-Block vorkommt, wird das Modul path_target_fuzz__ genannt, wobei path das letzte Segment des Self-Typpfads des impl ist.

Die Verwendung dieser Option führt jedoch dazu, dass das Modul stattdessen name_fuzz__ genannt wird. Beispiel:```rust #[test_fuzz(rename = "bar")] fn foo() {}

// Without the use of rename, a name collision and compile error would result. mod foo_fuzz__ {}

root@kitploit:~
#### Serde-Feldattribute für Funktionsargumente

Das `test_fuzz`-Makro erlaubt es, [Serde field attributes] auf Funktionsargumente anzuwenden. Dies bietet ein weiteres Werkzeug für den Umgang mit schwierigen Typen.

Das Folgende ist ein Beispiel. Die Traits `serde::Serialize` und `serde::Deserialize` können für `Context` nicht abgeleitet werden, da es einen `Mutex` enthält. `Context` implementiert jedoch `Default`. Die Anwendung von `#[serde(skip)]` auf das `Context`-Argument bewirkt, dass es beim Serialisieren übersprungen wird und beim Deserialisieren seinen Standardwert annimmt.```rust
use std::sync::Mutex;

// Traits `serde::Serialize` and `serde::Deserialize` cannot be derived for `Context` because it
// contains a `Mutex`.
#[derive(Default)]
struct Context {
    lock: Mutex<()>,
}

impl Clone for Context {
    fn clone(&self) -> Self {
        Self {
            lock: Mutex::new(()),
        }
    }
}

#[test_fuzz::test_fuzz]
fn target(#[serde(skip)] context: Context, x: i32) {
    assert!(x >= 0);
}

Beachten Sie, dass die test_fuzz-Makro keine weiteren [Konvertierungen] am Argument vornimmt, wenn Serde-Feldattribute auf ein Argument angewendet werden.

test_fuzz_impl-Makro

Wann immer das test_fuzz-Makro in einem impl-Block verwendet wird, muss dem impl das test_fuzz_impl-Makro vorangestellt werden. Beispiel:```rust #[test_fuzz_impl] impl Foo { #[test_fuzz] fn bar(&self, x: &str) { ... } }

root@kitploit:~
Der Grund für diese Anforderung ist folgender. Die Erweiterung des Makros [`test_fuzz`] fügt dem umgebenden Gültigkeitsbereich eine Moduldefinition hinzu. Eine Moduldefinition kann jedoch nicht innerhalb eines `impl`-Blocks erscheinen. Wenn dem `impl` das Makro `test_fuzz_impl` vorangestellt wird, wird das Modul außerhalb des `impl`-Blocks hinzugefügt.

Wenn Sie einen Fehler wie den folgenden sehen, bedeutet dies wahrscheinlich, dass eine Verwendung des Makros `test_fuzz_impl` fehlt:```
error: module is not supported in `trait`s or `impl`s

test_fuzz_impl hat derzeit keine Optionen.

Der Befehl cargo test-fuzz

Der Befehl cargo test-fuzz wird verwendet, um mit Fuzz-Targets zu interagieren und deren Corpora, Abstürze, Hänger und Arbeitswarteschlangen zu manipulieren. Beispielhafte Aufrufe sind:

  1. Fuzz-Targets auflisten ``` cargo test-fuzz --list
    root@kitploit:~
  2. Korpus des Ziels foo anzeigen ``` cargo test-fuzz foo --display corpus
    root@kitploit:~
  3. Fuzze das Ziel foo ``` cargo test-fuzz foo
    root@kitploit:~
  4. Spielen Sie die für das Ziel foo gefundenen Abstürze erneut ab. ``` cargo test-fuzz foo --replay crashes
    root@kitploit:~

Verwendung```

Usage: cargo test-fuzz [OPTIONS] [TARGETNAME] [-- ...]

Arguments: [TARGETNAME] String that fuzz target's name must contain [ARGS]... Arguments for the fuzzer

Options: --backtrace Display backtraces --consolidate Move one target's crashes, hangs, and work queue to its corpus; to consolidate all targets, use --consolidate-all --coverage Generate coverage for corpus, crashes, hangs, or work queue. Note that generating coverage for instrumented fuzz targets is not supported. --cpus Fuzz using at most cpus; default is all but one --display Display corpus, crashes, generic args, impl generic args, hangs, or work queue. By default, an uninstrumented fuzz target is used. To display with instrumentation, append -instrumented to , e.g., --display corpus-instrumented. --exact Target name is an exact name rather than a substring --exit-code Exit with 0 if the time limit was reached, 1 for other programmatic aborts, and 2 if an error occurred; implies --no-ui, does not imply --run-until-crash or --max-total-time --features Space or comma separated list of features to activate --list List fuzz targets --manifest-path Path to Cargo.toml --max-total-time Fuzz at most of time (equivalent to -- -V ) --no-default-features Do not activate the default feature --no-run Compile, but don't fuzz --no-ui Disable user interface -p, --package Package containing fuzz target --persistent Enable persistent mode fuzzing --pretty Pretty-print debug output when generating coverage, displaying, or replaying --release Build in release mode --replay Replay corpus, crashes, hangs, or work queue. By default, an uninstrumented fuzz target is used. To replay with instrumentation, append -instrumented to , e.g., --replay corpus-instrumented. --reset Clear fuzzing data for one target, but leave corpus intact; to reset all targets, use --reset-all --resume Resume target's last fuzzing session --run-until-crash Stop fuzzing once a crash is found --slice If there are not sufficiently many cpus to fuzz all targets simultaneously, fuzz them in intervals of [default: 1200] --test Integration test containing fuzz target --timeout Number of seconds to consider a hang when fuzzing or replaying (equivalent to -- -t <TIMEOUT * 1000> when fuzzing) --verbose Show build output when generating coverage, displaying, or replaying -h, --help Print help -V, --version Print version

Try cargo afl fuzz --help to see additional fuzzer options.

root@kitploit:~
Wenn die Option `--display` verwendet wird, wird jede Ausgabe des Ziels, die nach stderr geschrieben wird, angezeigt. Dies umfasst Ausgaben von `eprintln!`-Anweisungen sowie von Debug-Makros wie `dbg!`. Dies kann nützlich sein, um zu verstehen, was in Ihrem Code bei der Verarbeitung bestimmter Eingaben geschieht.

Die Optionen `--display` und `--replay` können zusammen übergeben werden, sodass Sie Korpus-Einträge mit einem einzigen Befehl sowohl anzeigen als auch wiedergeben können, zum Beispiel:```
cargo test-fuzz foo --display corpus --replay corpus

Komfortfunktionen und Makros

Warnung: Diese Hilfsprogramme sind von der semantischen Versionierung ausgenommen und können in zukünftigen Versionen von test-fuzz entfernt werden.

dont_care!

Das Makro dont_care! kann verwendet werden, um serde::Serialize/serde::Deserialize für Typen zu implementieren, die einfach zu konstruieren sind und deren Werte Sie nicht aufzeichnen möchten. Intuitiv besagt dont_care!($ty, $expr):

  • Werte des Typs $ty beim Serialisieren überspringen.
  • Werte des Typs $ty beim Deserialisieren mit $expr initialisieren.

Genauer gesagt erweitert sich dont_care!($ty, $expr) zu Folgendem:```rust impl serde::Serialize for $ty { fn serialize(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> where S: serde::Serializer, { ().serialize(serializer) } }

impl<'de> serde::Deserialize<'de> for $ty { fn deserialize(deserializer: D) -> std::result::Result<Self, D::Error> where D: serde::Deserializer<'de>, { <()>::deserialize(deserializer).map(|_| $expr) } }

root@kitploit:~
Wenn `$ty` eine Unit-Struct ist, kann `$expr` weggelassen werden. Das heißt, `dont_care!($ty)` ist äquivalent zu `dont_care!($ty, $ty)`.

#### `leak!`

Das `leak!`-Makro kann dabei helfen, Zielargumente zu serialisieren, die Referenzen sind und deren Typen das [`ToOwned`]-Trait implementieren. Es ist für die Verwendung mit der Option [`convert`] gedacht.```rust
leak!(X, LeakedX);

Man kann dann LeakedX mit der Option convert wie folgt verwenden:```rust #[test_fuzz::test_fuzz(convert = "&X, LeakedX")

root@kitploit:~
Ein Beispiel, bei dem `X` [`Path`] ist, findet sich in [conversion.rs] in diesem Repository.

Allgemeiner gesagt erweitert sich ein Aufruf der Form `leak!($ty, $ident)` zu Folgendem:```rust
#[derive(Clone, std::fmt::Debug, serde::Deserialize, serde::Serialize)]
struct $ident(<$ty as ToOwned>::Owned);

impl From<&$ty> for $ident {
    fn from(ty: &$ty) -> Self {
        Self(ty.to_owned())
    }
}

impl test_fuzz::Into<&$ty> for $ident {
    fn into(self) -> &'static $ty {
        Box::leak(Box::new(self.0))
    }
}

/

Tool herunterladen
serialize_ref
deserialize_ref

serialize_ref und deserialize_ref funktionieren ähnlich wie leak!, aber sie sind für die Verwendung mit Serdes serialize_with- bzw. deserialize_with-Feldattributen gedacht.```rust fn serialize_ref<S, T>(x: &&T, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, T: serde::Serialize, { ::serialize(*x, serializer) }

fn deserialize_ref<'de, D, T>(deserializer: D) -> Result<&'static T, D::Error> where D: serde::Deserializer<'de>, T: serde:🇩🇪:DeserializeOwned + std::fmt::Debug, { let x = ::deserialize(deserializer)?; Ok(Box::leak(Box::new(x))) }

root@kitploit:~
#### `serialize_ref_mut` / `deserialize_ref_mut`

`serialize_ref_mut` und `deserialize_ref_mut` ähneln `serialize_ref` bzw. `deserialize_ref`, mit dem Unterschied, dass sie mit veränderlichen Referenzen arbeiten statt mit unveränderlichen.

## Funktionen des `test-fuzz`-Pakets

Die in diesem Abschnitt beschriebenen Funktionen gelten für das gesamte `test-fuzz`-Paket. Aktivieren Sie sie in der Abhängigkeitsangabe von `test-fuzz`, wie im [The Cargo Book] beschrieben. Um beispielsweise die Funktion `cast_checks` zu aktivieren, verwenden Sie:```toml
test-fuzz = { version = "*", features = ["cast_checks"] }

Das test-fuzz-Paket unterstützt derzeit die folgenden Features:

cast_checks

Verwenden Sie cast_checks, um Zielfunktionen automatisch auf ungültige Casts zu prüfen.

Beachten Sie, dass dieses Feature cast_checks nur für Funktionen aktiviert, die mit dem test_fuzz-Makro annotiert sind, nicht für die von ihnen aufgerufenen Funktionen.

Serde-Formate

test-fuzz kann Zielargumente in mehreren Serde-Formaten serialisieren. Die folgenden Features werden verwendet, um ein Format auszuwählen.

  • serde_postcard - Postcard (Standard)

  • serde_bincode - Bincode

Automatisch generierte Korpusdateien

cargo-test-fuzz kann Werte für Typen automatisch generieren, die bestimmte Traits implementieren. Wenn alle Argumenttypen eines Targets solche Traits implementieren, kann cargo-test-fuzz Korpusdateien für das Target automatisch generieren.

Die Traits, die cargo-test-fuzz derzeit unterstützt, und die für sie generierten Werte sind wie folgt:

Trait(s)Wert(e)
BoundedT::min_value(), T::max_value()
Bounded + Add + OneT::min_value() + T::one()
Bounded + Add + Div + TwoT::min_value() / T::two() + T::max_value() / T::two()
Bounded + Add + Div + Two + OneT::min_value() / T::two() + T::max_value() / T::two() + T::one()
Bounded + Sub + OneT::max_value() - T::one()
DefaultT::default()

Legende

  • Add - core::ops::Add
  • Bounded - num_traits::bounds::Bounded
  • Default - std::default::Default
  • Div - core::ops::Div
  • One - num_traits::One
  • Sub - core::ops::Sub
  • Two - test_fuzz::runtime::traits::Two (im Wesentlichen Add + One)

Umgebungsvariablen

TEST_FUZZ_LOG

Während der Makroerweiterung:

  • Wenn TEST_FUZZ_LOG auf 1 gesetzt ist, werden alle instrumentierten Fuzz-Targets und Moduldefinitionen in die Standardausgabe geschrieben.
  • Wenn TEST_FUZZ_LOG auf einen Crate-Namen gesetzt ist, werden die instrumentierten Fuzz-Targets und Moduldefinitionen dieses Crates in die Standardausgabe geschrieben.

Dies kann beim Debuggen nützlich sein.

TEST_FUZZ_MANIFEST_PATH

Wenn ein Target von außerhalb seines Paketverzeichnisses ausgeführt wird, wird die Cargo.toml-Datei des Pakets an diesem Speicherort gesucht. Möglicherweise muss diese Umgebungsvariable gesetzt werden, wenn enable_in_production verwendet wird.

TEST_FUZZ_WRITE

Für diejenigen Targets, für die enable_in_production gesetzt ist, werden Korpusdateien generiert, wenn keine Tests ausgeführt werden.

Einschränkungen

Klonbare Argumente

Die Argumente eines Targets müssen das Clone-Trait implementieren. Der Grund für diese Anforderung ist, dass die Argumente an zwei Stellen benötigt werden: in einer test-fuzz-internen Funktion, die Korpusdateien schreibt, und im Rumpf der Zielfunktion. Um diesen Konflikt aufzulösen, werden die Argumente geklont, bevor sie an erstere übergeben werden.

Serialisierbare / deserialisierbare Argumente

Im Allgemeinen müssen die Argumente eines Targets die Traits serde::Serialize und serde::Deserialize implementieren, z. B. durch Ableiten. Wir sagen »im Allgemeinen«, weil test-fuzz bestimmte Sonderfälle zu behandeln weiß, die normalerweise nicht serialisierbar/deserialisierbar wären. Beispielsweise wird ein Argument vom Typ &str beim Serialisieren in String umgewandelt und beim Deserialisieren zurück in ein &str. Siehe auch generic_args und impl_generic_args oben.

Globale Variablen

Die von test-fuzz implementierten Fuzzing-Harnesses initialisieren keine globalen Variablen. Obwohl execute_with eine gewisse Abhilfe schafft, ist dies keine vollständige Lösung. Im Allgemeinen erfordert das Fuzzing einer Funktion, die von globalen Variablen abhängt, Ad-hoc-Methoden.

convert und generic_args / impl_generic_args

Diese Optionen sind in folgendem Sinne inkompatibel. Wenn der Argumenttyp eines Fuzz-Targets ein Typparameter ist, versucht convert, den Typparameter abzugleichen, nicht den Typ, auf den der Parameter gesetzt ist. Die Unterstützung des Letzteren würde offenbar erfordern, die Typsubstitution so zu simulieren, wie der Compiler sie durchführen würde. Dies ist jedoch derzeit nicht implementiert.

Tipps und Tricks

  • #[cfg(test)] ist nicht aktiviert für Integrationstests. Wenn Ihr Target nur durch Integrationstests getestet wird, ziehen Sie in Betracht, enable_in_production und TEST_FUZZ_WRITE zu verwenden, um ein Korpus zu generieren. (Beachten Sie jedoch die Warnung, die mit enable_in_production einhergeht.)

  • Wenn Sie das Paket kennen, in dem sich Ihr Target befindet, kann die Übergabe von -p <package> an cargo test/cargo test-fuzz die Buildzeiten erheblich reduzieren. Wenn Sie außerdem wissen, dass Ihr Target nur aus einem einzigen Integrationstest aufgerufen wird, kann die Übergabe von --test <name> die Buildzeiten reduzieren.

  • Rust erlaubt es Ihnen nicht, serde::Serialize für Typen anderer Repositories zu implementieren. Aber Sie können möglicherweise andere Repositories patchen, um ihre Typen serialisierbar zu machen. Auch cargo-clone kann nützlich sein, um die Repositories von Abhängigkeiten zu holen.

  • Serde-Attribute können hilfreich sein, um serde::Serialize/serde::Deserialize für schwierige Typen zu implementieren.

Richtlinie zur semantischen Versionierung

Wir behalten uns das Recht vor, das Format von Korpora, Abstürzen, Hängern und Arbeitswarteschlangen zu ändern und solche Änderungen als nicht-brechend zu betrachten.

Lizenz

test-fuzz ist unter der AGPLv3-Lizenz mit der Ausnahme für Makros und Inline-Funktionen lizenziert und verbreitet. In einfachen Worten: Wenn Sie test_fuzz-Makro, test_fuzz_impl-Makro oder die Bequemlichkeitsfunktionen und Makros von test-fuzz in Ihrer Software verwenden, erfordert dies nicht, dass Ihre Software von der AGPLv3-Lizenz abgedeckt wird.