Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
test-fuzz — وحدات ماكرو Rust وأمر فرعي لـ Cargo لأتمتة الاختبار بالتغذية العشوائية (fuzzing) باستخدام afl.rs، بما في ذلك توليد مجموعة المدخلات (corpus) وتنفيذ harness، ومدمج مع إطار الاختبار الخاص بـ Rust. | Kitploit
أدوات/GitHubGitHub/trailofbits/test-fuzz
التحليل الديناميكي (عزل)تحليل الثغرات الأمنيةتحليل الكودالاختبار العشوائي
GitHubtrailofbits/test-fuzz

test-fuzz

وحدات ماكرو Rust وأمر فرعي لـ Cargo لأتمتة الاختبار بالتغذية العشوائية (fuzzing) باستخدام afl.rs، بما في ذلك توليد مجموعة المدخلات (corpus) وتنفيذ harness، ومدمج مع إطار الاختبار الخاص بـ Rust.

عرض المستودع
20827منذ 11 أيامتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
الموقع الإلكتروني

test-fuzz

test-fuzz هي أمر فرعي لـ Cargo ومجموعة من ماكروات Rust لأتمتة مهام معينة تتعلق بـ fuzzing باستخدام afl.rs، وتشمل:

  • توليد corpus للـ fuzzing
  • تنفيذ harness للـ fuzzing

test-fuzz تحقق هذه الأمور (جزئيًا) باستخدام أدوات الاختبار في Rust. على سبيل المثال، لتوليد corpus للـ fuzzing، يسجّل test-fuzz وسائط الهدف في كل مرة يُستدعى فيها أثناء تشغيل cargo test. وبالمثل، ينفّذ test-fuzz harness للـ fuzzing كاختبار إضافي في ملف ثنائي مُولَّد بواسطة cargo-test. هذا التكامل الوثيق مع أدوات الاختبار في Rust هو ما يبرر الاسم test-fuzz.

المحتويات

  1. [التثبيت]
  2. [نظرة عامة]
  3. [المكوّنات]
    • [ماكرو test_fuzz]
    • [ماكرو test_fuzz_impl]
    • [أمر cargo test-fuzz]
    • [دوال وماكروات مساعدة]
  4. [ميزات حزمة test-fuzz]
  5. [ملفات corpus المُولَّدة تلقائيًا]
  6. [متغيرات البيئة]
  7. [القيود]
  8. [نصائح وحيل]
  9. [سياسة الإصدارات الدلالية]
  10. [الترخيص]

التثبيت

ثبّت cargo-test-fuzz وafl.rs بالأمر التالي:```sh cargo install cargo-test-fuzz cargo-afl

root@kitploit:~
## نظرة عامة

التضمين باستخدام `test-fuzz` يتم أساسًا في ثلاث خطوات:\*

1. **حدد هدف التضمين**:
   - أضف التبعيات `dependencies` التالية إلى ملف `Cargo.toml` الخاص بالكريت الهدف:
     ```toml
     serde = "*"
     test-fuzz = "*"
     ```
   - سبق الدالة الهدف بماكرو [`test_fuzz`]:
     ```rust
     #[test_fuzz::test_fuzz]
     fn foo(...) {
         ...
     }
     ```
2. **أنشئ مجموعة بيانات** بتشغيل `cargo test`:   ```
   cargo test
  1. اختبر هدفك بالتزوير عن طريق تشغيل cargo test-fuzz: ``` cargo test-fuzz foo
    root@kitploit:~

* قد تكون هناك حاجة إلى خطوة إضافية أولية بعد إعادة التشغيل:```sh cargo afl system-config

root@kitploit:~
لاحظ أن الأمر أعلاه يشغّل `sudo` داخليًا. لذلك، قد يُطلب منك إدخال كلمة المرور.

## المكونات

### الماكرو `test_fuzz`

وضعُ الماكرو `test_fuzz` قبل دالة يشير إلى أن هذه الدالة هي هدف fuzzing.

الآثار الرئيسية للماكرو `test_fuzz` هي:

- إضافة أدوات قياس إلى الهدف لتسلسل وسائطه وكتابتها إلى ملف مجموعة (corpus file) في كل مرة يُستدعى فيها الهدف. الأدوات محمية بواسطة `#[cfg(test)]` بحيث يتم إنشاء ملفات المجموعة فقط عند تشغيل الاختبارات (ومع ذلك، انظر [`enable_in_production`] أدناه).
- إضافة اختبار لقراءة الوسائط وفك تسلسلها من الإدخال القياسي وتطبيق الهدف عليها. يفحص الاختبار متغير بيئة معيّنًا بواسطة [`cargo test-fuzz`]، بحيث لا يعلق الاختبار في محاولة القراءة من الإدخال القياسي أثناء استدعاء عادي لـ `cargo test`. الاختبار موضوع داخل وحدة (module) لتقليل احتمالية تعارض الأسماء. حاليًا، اسم الوحدة هو `target_fuzz`، حيث `target` هو اسم الهدف (ومع ذلك، انظر [`rename`] أدناه).

#### الوسائط

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

فرض `where_predicates` (مثل قيود الخصائص) على البنية المستخدمة لتسلسل/فك تسلسل الوسائط. قد يكون هذا ضروريًا، مثلًا، إذا كان نوع وسيط الهدف نوعًا مرتبطًا (associated type). لمثال، انظر [associated_type.rs] في هذا المستودع.

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

استخدم `parameters` كمعاملات نوع الهدف عند fuzzing. مثال:```rust
#[test_fuzz(generic_args = "String")]
fn foo<T: Clone + Debug + Serialize>(x: &T) {
    ...
}

ملاحظة: يجب أن تكون وسائط الهدف قابلة للتسلسل (serializable) لكل instantiation من معاملات النوع الخاصة به. لكن وسائط الهدف مطلوبة لتكون قابلة لإلغاء التسلسل (deserializable) فقط عندما يتم إنشاء الهدف باستخدام parameters.

impl_generic_args = "parameters"

استخدم parameters كمعاملات النوع Self الخاصة بالهدف عند الفازينج (fuzzing). مثال:```rust #[test_fuzz_impl] impl<T: Clone + Debug + Serialize> for Foo { #[test_fuzz(impl_generic_args = "String")] fn bar(&self, x: &T) { ... } }

root@kitploit:~
ملاحظة: يجب أن تكون وسيطات الهدف قابلة للتسلسل (serializable) لكل **instantiation** (نسخة) من معاملات النوع `Self` الخاصة به. لكن وسيطات الهدف مطلوبة لتكون قابلة لإلغاء التسلسل (deserializable) فقط عندما يتم إنشاء نسخة `Self` الخاصة بالهدف باستخدام `parameters`.

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

عند تسلسل وسيطات الهدف، حوّل القيم من النوع `X` إلى النوع `Y` باستخدام تنفيذ `Y` لـ `From<X>`، أو من النوع `&X` إلى النوع `Y` باستخدام تنفيذ `Y` للخاصية غير القياسية `test_fuzz::FromRef<X>`. عند إلغاء التسلسل، حوّل تلك القيم مرة أخرى إلى النوع `X` باستخدام تنفيذ `Y` للخاصية غير القياسية `test_fuzz::Into<X>`.

أي أنّ استخدام `convert = "X, Y"` يجب أن يكون مصحوبًا بتنفيذات معيّنة. إذا كان `X` يطبّق [`Clone`]، فإن `Y` يمكن أن يطبّق ما يلي:```rust
impl From<X> for Y {
    fn from(x: X) -> Self {
        ...
    }
}

إذا كان X لا يطبّق Clone، فيجب أن يطبّق Y ما يلي:```rust impl test_fuzz::FromRef for Y { fn from_ref(x: &X) -> Self { ... } }

root@kitploit:~
بالإضافة إلى ذلك، يجب أن يطبّق `Y` ما يلي (بغض النظر عما إذا كان `X` يطبّق [`Clone`]):```rust
impl test_fuzz::Into<X> for Y {
    fn into(self) -> X {
        ...
    }
}

تعريف test_fuzz::Into مطابق تمامًا لتعريف std::convert::Into. والسبب في استخدام trait غير قياسي هو تجنّب التعارضات التي قد تنشأ عن التطبيقات الشاملة (blanket implementations) للـ traits القياسية.

enable_in_production

قم بإنشاء ملفات corpus عند عدم تشغيل الاختبارات، بشرط أن يكون متغير البيئة TEST_FUZZ_WRITE مضبوطًا. السلوك الافتراضي هو إنشاء ملفات corpus فقط عند تشغيل الاختبارات، بغض النظر عن ضبط TEST_FUZZ_WRITE أو عدمه. عند تشغيل هدف من خارج مجلد الحزمة، اضبط TEST_FUZZ_MANIFEST_PATH على مسار ملف Cargo.toml الخاص بالحزمة.

تحذير: ضبط enable_in_production قد يُدخل ناقل رفض خدمة (denial-of-service). على سبيل المثال، ضبط هذا الخيار لدالة تُستدعى مرات عديدة بوسائط مختلفة قد يملأ القرص. ويأتي التحقق من TEST_FUZZ_WRITE ليوفر بعض الحماية ضد هذا الاحتمال. ومع ذلك، فكّر في هذا الخيار بعناية قبل استخدامه.

execute_with = "function"

بدلاً من استدعاء الهدف مباشرة:

  • أنشئ إغلاقًا (closure) من النوع FnOnce() -> R، حيث R هو نوع القيمة المعادة للهدف، بحيث يكون استدعاء الإغلاق هو استدعاء الهدف؛
  • استدعِ function مع تمرير الإغلاق إليه.

استدعاء الهدف بهذه الطريقة يتيح لـ function إعداد بيئة الاستدعاء. وقد يكون هذا مفيدًا، مثلًا، للـ fuzzing على Substrate externalities.

no_auto_generate

لا تحاول إنشاء auto-generate corpus files للهدف.

only_generic_args

سجّل الوسائط العامة (generic args) للهدف عند تشغيل الاختبارات، لكن لا تُنشئ ملفات corpus ولا تنفّذ أداة fuzzing harness. قد يكون هذا مفيدًا عندما يكون الهدف دالة عامة، ولكن من غير الواضح ما هي معاملات الأنواع (type parameters) التي ينبغي استخدامها في الـ fuzzing.

سير العمل المقصود هو: فعّل only_generic_args، ثم شغّل cargo test متبوعًا بـ cargo test-fuzz --display generic-args. قد تكون إحدى الوسائط العامة الناتجة صالحة للاستخدام كـ parameters لـ generic_args. وبالمثل، قد تكون الوسائط العامة الناتجة عن cargo test-fuzz --display impl-generic-args صالحة للاستخدام كـ parameters لـ impl_generic_args.

لاحظ، مع ذلك، أن مجرد استدعاء الهدف بمعاملات معينة أثناء الاختبارات لا يعني أن وسائط الهدف قابلة للـ serialization/deserialization عند استخدام تلك المعاملات. نتائج --display generic-args/--display impl-generic-args هي مجرد مؤشرات إرشادية.

rename = "name"

تعامل مع الهدف كما لو كان اسمه name عند إضافة وحدة (module) إلى النطاق المحيط. توسيع الماكرو test_fuzz يضيف تعريف وحدة إلى النطاق المحيط. افتراضيًا، تُسمى الوحدة على النحو التالي:

  • إذا لم يظهر الهدف داخل كتلة impl، تكون الوحدة باسم target_fuzz__، حيث target هو اسم الهدف.
  • إذا ظهر الهدف داخل كتلة impl، تكون الوحدة باسم path_target_fuzz__، حيث path هو الجزء الأخير من مسار نوع Self في impl.

لكن استخدام هذا الخيار يجعل الوحدة تُسمى بدلًا من ذلك name_fuzz__. مثال:```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 على وسائط الدوال

تسمح وحدة الماكرو `test_fuzz` بتطبيق [سمات حقول Serde] على وسائط الدوال. وهذا يوفر أداة إضافية للتعامل مع الأنواع الصعبة.

فيما يلي مثال. لا يمكن اشتقاق خصائص `serde::Serialize` و`serde::Deserialize` لـ `Context` لأنها تحتوي على `Mutex`. ومع ذلك، فإن `Context` تنفّذ `Default`. لذا فإن تطبيق `#[serde(skip)]` على وسيط `Context` يتسبب في تخطيه عند التسلسل، وأخذ قيمته الافتراضية عند إلغاء التسلسل.```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);
}

لاحظ أنه عند تطبيق سمات حقول Serde على وسيط، فإن ماكرو test_fuzz لا يُجري أي conversions أخرى على الوسيط.

ماكرو `test_fuzz_impl`

متى تم استخدام ماكرو test_fuzz في كتلة impl، يجب أن يسبق impl ماكرو test_fuzz_impl. مثال:```rust #[test_fuzz_impl] impl Foo { #[test_fuzz] fn bar(&self, x: &str) { ... } }

root@kitploit:~
السبب وراء هذا المطلب هو كما يلي. توسيع ماكرو [`test_fuzz`] يضيف تعريف وحدة نمطية إلى النطاق المحيط. لكن لا يمكن أن يظهر تعريف وحدة نمطية داخل كتلة `impl`. إضافة ماكرو `test_fuzz_impl` قبل `impl` يؤدي إلى إضافة الوحدة خارج كتلة `impl`.

إذا رأيت خطأً مشابهاً لما يلي، فمن المحتمل أن ذلك يعني أن استخدام ماكرو `test_fuzz_impl` مفقود:```
error: module is not supported in `trait`s or `impl`s

test_fuzz_impl لا يحتوي حاليًا على أي خيارات.

أمر cargo test-fuzz

يُستخدم أمر cargo test-fuzz للتفاعل مع أهداف التلقيح، ومعالجة مجاميع البيانات، وحالات الانهيار، والتعلقات، وقوائم العمل الخاصة بها. تتضمن أمثلة الاستدعاءات ما يلي:

  1. سرد أهداف التلقيح ``` cargo test-fuzz --list
    root@kitploit:~
  2. اعرض مجموعة نصوص الهدف foo ``` cargo test-fuzz foo --display corpus
    root@kitploit:~
  3. هدف الـ Fuzzing foo ``` cargo test-fuzz foo
    root@kitploit:~
  4. إعادة إنتاج الأعطال المكتشفة للهدف foo ``` cargo test-fuzz foo --replay crashes
    root@kitploit:~

الاستخدام```

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:~
عند استخدام خيار `--display`، يتم عرض أي مخرجات يكتبها الهدف إلى stderr. يتضمن ذلك مخرجات عبارات `eprintln!`، بالإضافة إلى وحدات ماكرو التصحيح مثل `dbg!`. قد يكون هذا مفيدًا لفهم ما يحدث في الكود الخاص بك عند معالجة مدخلات محددة.

يمكن تمرير الخيارين `--display` و `--replay` معًا، مما يتيح لك عرض وإعادة تشغيل إدخالات corpus في أمر واحد، على سبيل المثال:```
cargo test-fuzz foo --display corpus --replay corpus

دوال وماكرو مساعدة

تحذير: هذه الأدوات المساعدة مستثناة من نظام الإصدارات الدلالية (semantic versioning) وقد تُزال في إصدارات مستقبلية من test-fuzz.

dont_care!

يمكن استخدام ماكرو dont_care! لتنفيذ serde::Serialize/serde::Deserialize للأنواع التي يسهل إنشاؤها ولا تهتم بتسجيل قيمها. بشكل بديهي، يعني dont_care!($ty, $expr) ما يلي:

  • تخطّي قيم النوع $ty عند إجراء التسلسل (serializing).
  • تهيئة قيم النوع $ty باستخدام $expr عند إلغاء التسلسل (deserializing).

بشكل أكثر تحديدًا، يتوسّع dont_care!($ty, $expr) إلى ما يلي:```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:~
إذا كان `$ty` بنية وحدة، فيمكن حذف `$expr`. أي أن `dont_care!($ty)` يعادل `dont_care!($ty, $ty)`.

#### `leak!`

يمكن أن تساعد ماكرو `leak!` في تسلسل وسائط الهدف التي تكون مراجعًا وتنفّذ أنواعها سمة [`ToOwned`]. يُقصد استخدامها مع خيار [`convert`].

على وجه التحديد، استدعاء بالشكل التالي يعلن عن نوع `LeakedX`، وينفّذ سمتي `From` و `test_fuzz::Into` له:```rust
leak!(X, LeakedX);

يمكن للمرء بعد ذلك استخدام LeakedX مع خيار convert كما يلي:```rust #[test_fuzz::test_fuzz(convert = "&X, LeakedX")

root@kitploit:~
مثال حيث `X` هو [`Path`] يظهر في [conversion.rs] في هذا المستودع.

بشكل أكثر عمومية، استدعاء بالشكل `leak!($ty, $ident)` يتوسع إلى ما يلي:```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))
    }
}

serialize_ref / deserialize_ref

تعمل serialize_ref وdeserialize_ref بشكل مشابه لـ leak!، لكنهما مخصصتان للاستخدام مع سمات الحقل serialize_with وdeserialize_with الخاصة بـ Serde (على التوالي).```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` و `deserialize_ref_mut` يشبهان `serialize_ref` و `deserialize_ref` (على التوالي)، باستثناء أنّهما يعملان على مراجع قابلة للتغيير بدلاً من المراجع غير القابلة للتغيير.

## ميزات حزمة `test-fuzz`

تنطبق الميزات في هذا القسم على حزمة `test-fuzz` ككل. فعّلها في مواصفات تبعية `test-fuzz` كما هو موصوف في [The Cargo Book]. على سبيل المثال، لتفعيل ميزة `cast_checks`، استخدم:```toml
test-fuzz = { version = "*", features = ["cast_checks"] }

تدعم حزمة test-fuzz حالياً الميزات التالية:

cast_checks

استخدم cast_checks لفحص الدوال المستهدفة تلقائياً بحثاً عن عمليات التحويل غير الصالحة.

لاحظ أن هذه الميزة تُفعّل cast_checks فقط للدوال المُعلَّمة بـ test_fuzz macro، وليس للدوال التي تستدعيها.

تنسيقات Serde

يمكن لـ test-fuzz تسلسل وسائط الأهداف بتنسيقات Serde متعددة. فيما يلي الميزات المستخدمة لاختيار التنسيق.

  • serde_postcard - Postcard (الافتراضي)

  • serde_bincode - Bincode

ملفات الكوربوس المُولَّدة تلقائياً

يمكن لـ cargo-test-fuzz توليد قيم تلقائياً للأنواع التي تطبّق سمات معينة. إذا كانت جميع أنواع وسائط الهدف تطبّق هذه السمات، فيمكن لـ cargo-test-fuzz توليد ملفات كوربوس للهدف تلقائياً.

السمات التي يدعمها cargo-test-fuzz حالياً والقيم المُولَّدة لها هي كما يلي:

مفتاح الرموز

  • 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

متغيرات البيئة

TEST_FUZZ_LOG

أثناء توسيع الماكرو:

  • إذا كانت TEST_FUZZ_LOG مضبوطة على 1، فاكتب جميع أهداف التلغيم المُجهَّزة وتعريفات الوحدات إلى الإخراج القياسي.
  • إذا كانت TEST_FUZZ_LOG مضبوطة على اسم crate، فاكتب أهداف التلغيم المُجهَّزة وتعريفات الوحدات لذلك crate إلى الإخراج القياسي.

قد يكون هذا مفيداً لتصحيح الأخطاء.

TEST_FUZZ_MANIFEST_PATH

عند تشغيل هدف من خارج دليل الحزمة الخاصة به، ابحث عن ملف Cargo.toml الخاص بالحزمة في هذا الموقع. قد يحتاج المرء إلى ضبط متغير البيئة هذا عند استخدام enable_in_production.

TEST_FUZZ_WRITE

توليد ملفات كوربوس عند عدم تشغيل الاختبارات لتلك الأهداف التي تم ضبط enable_in_production لها.

القيود

الوسائط القابلة للاستنساخ

يجب أن تطبّق وسائط الهدف سمة Clone. سبب هذا المطلب هو أن الوسائط مطلوبة في مكانين: في دالة داخلية لـ test-fuzz تكتب ملفات الكوربوس، وفي جسم الدالة المستهدفة. لحل هذا التعارض، تُستنسخ الوسائط قبل تمريرها إلى الدالة الأولى.

الوسائط القابلة للتسلسل وإلغاء التسلسل

بشكل عام، يجب أن تطبّق وسائط الهدف سمتي serde::Serialize وserde::Deserialize، على سبيل المثال عن طريق deriving them. نقول "بشكل عام" لأن test-fuzz يعرف كيفية التعامل مع حالات خاصة معينة لن تكون قابلة للتسلسل/إلغاء التسلسل في الوضع الطبيعي. على سبيل المثال، يتم تحويل وسيط من النوع &str إلى String عند التسلسل، ثم يُعاد إلى &str عند إلغاء التسلسل. انظر أيضاً generic_args وimpl_generic_args أعلاه.

المتغيرات العامة

لا تقوم أُطر التلغيم التي تنفذها test-fuzz بتهيئة المتغيرات العامة. وبينما يوفر execute_with بعض المعالجة، فإنه ليس حلاً كاملاً. بشكل عام، يتطلب لغيم دالة تعتمد على متغيرات عامة طرقاً مخصصة.

convert و generic_args / impl_generic_args

هذه الخيارات غير متوافقة بالمعنى التالي. إذا كان نوع وسيط هدف التلغيم هو معامل نوع، فسيحاول convert مطابقة معامل النوع، وليس النوع الذي ضُبط عليه المعامل. يبدو أن دعم الحالة الأخيرة يتطلب محاكاة استبدال الأنواع كما قد ينفذه المترجم. ومع ذلك، فإن هذا غير مطبَّق حالياً.

نصائح وحيل

  • #[cfg(test)] is not enabled في اختبارات التكامل. إذا كان هدفك يُختبر فقط عبر اختبارات التكامل، ففكر في استخدام enable_in_production وTEST_FUZZ_WRITE لتوليد كوربوس. (لاحظ مع ذلك التحذير المصاحب لـ enable_in_production.)

  • إذا كنت تعرف الحزمة التي يوجد بها هدفك، فإن تمرير -p <package> إلى cargo test/cargo test-fuzz يمكن أن يقلل أوقات البناء بشكل ملحوظ. وبالمثل، إذا كنت تعلم أن هدفك يُستدعى من اختبار تكامل واحد فقط، فإن تمرير --test <name> يمكن أن يقلل أوقات البناء.

  • لن يسمح لك Rust won't allow you to بتنفيذ serde::Serialize لأنواع المستودعات الأخرى. لكن قد تتمكن من المستودعات الأخرى لجعل أنواعها قابلة للتسلسل. أيضاً، يمكن أن يكون مفيداً للحصول على مستودعات التبعيات.

سياسة الإصدارات الدلالية

نحتفظ بالحق في تغيير تنسيق ملفات الكوربوس والأعطال وحالات التعليق وقوائم انتظار العمل، واعتبار هذه التغييرات غير خارقة للتوافق.

الترخيص

يتم ترخيص test-fuzz وتوزيعه بموجب رخصة AGPLv3 مع Macros and Inline Functions Exception. بعبارة بسيطة، فإن استخدام test_fuzz macro أو test_fuzz_impl macro أو convenience functions and macros الخاصة بـ test-fuzz في برنامجك لا يتطلب أن يكون برنامجك مشمولاً برخصة AGPLv3.

السمة/السماتالقيمة/القيم
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()
  • Two - test_fuzz::runtime::traits::Two (أساساً Add + One)
  • patch
    cargo-clone
  • يمكن أن تكون Serde attributes مفيدة في تنفيذ serde::Serialize/serde::Deserialize للأنواع الصعبة.