Hypothesis-like property testing for Rust

Overview

Proptest

Build Status Build status

Introduction

Proptest is a property testing framework (i.e., the QuickCheck family) inspired by the Hypothesis framework for Python. It allows to test that certain properties of your code hold for arbitrary inputs, and if a failure is found, automatically finds the minimal test case to reproduce the problem. Unlike QuickCheck, generation and shrinking is defined on a per-value basis instead of per-type, which makes it more flexible and simplifies composition.

Status of this crate

The crate is fairly close to being feature-complete and has not seen substantial architectural changes in quite some time. At this point, it mainly sees passive maintenance.

See the changelog for a full list of substantial historical changes, breaking and otherwise.

What is property testing?

Property testing is a system of testing code by checking that certain properties of its output or behaviour are fulfilled for all inputs. These inputs are generated automatically, and, critically, when a failing input is found, the input is automatically reduced to a minimal test case.

Property testing is best used to complement traditional unit testing (i.e., using specific inputs chosen by hand). Traditional tests can test specific known edge cases, simple inputs, and inputs that were known in the past to reveal bugs, whereas property tests will search for more complicated inputs that cause problems.

Getting Started

Let's say we want to make a function that parses dates of the form YYYY-MM-DD. We're not going to worry about validating the date, any triple of integers is fine. So let's bang something out real quick.

fn parse_date(s: &str) -> Option<(u32, u32, u32)> {
    if 10 != s.len() { return None; }
    if "-" != &s[4..5] || "-" != &s[7..8] { return None; }

    let year = &s[0..4];
    let month = &s[6..7];
    let day = &s[8..10];

    year.parse::<u32>().ok().and_then(
        |y| month.parse::<u32>().ok().and_then(
            |m| day.parse::<u32>().ok().map(
                |d| (y, m, d))))
}

It compiles, that means it works, right? Maybe not, let's add some tests.

#[test]
fn test_parse_date() {
    assert_eq!(None, parse_date("2017-06-1"));
    assert_eq!(None, parse_date("2017-06-170"));
    assert_eq!(None, parse_date("2017006-17"));
    assert_eq!(None, parse_date("2017-06017"));
    assert_eq!(Some((2017, 06, 17)), parse_date("2017-06-17"));
}

Tests pass, deploy to production! But now your application starts crashing, and people are upset that you moved Christmas to February. Maybe we need to be a bit more thorough.

In Cargo.toml, add

[dev-dependencies]
proptest = "1.0.0"

Now we can add some property tests to our date parser. But how do we test the date parser for arbitrary inputs, without making another date parser in the test to validate it? We won't need to as long as we choose our inputs and properties correctly. But before correctness, there's actually an even simpler property to test: The function should not crash. Let's start there.

// Bring the macros and other important things into scope.
use proptest::prelude::*;

proptest! {
    #[test]
    fn doesnt_crash(s in "\\PC*") {
        parse_date(&s);
    }
}

What this does is take a literally random &String (ignore \\PC* for the moment, we'll get back to that — if you've already figured it out, contain your excitement for a bit) and give it to parse_date() and then throw the output away.

When we run this, we get a bunch of scary-looking output, eventually ending with

thread 'main' panicked at 'Test failed: byte index 4 is not a char boundary; it is inside 'ௗ' (bytes 2..5) of `aAௗ0㌀0`; minimal failing input: s = "aAௗ0㌀0"
	successes: 102
	local rejects: 0
	global rejects: 0
'

If we look at the top directory after the test fails, we'll see a new proptest-regressions directory, which contains some files corresponding to source files containing failing test cases. These are failure persistence files. The first thing we should do is add these to source control.

$ git add proptest-regressions

The next thing we should do is copy the failing case to a traditional unit test since it has exposed a bug not similar to what we've tested in the past.

#[test]
fn test_unicode_gibberish() {
    assert_eq!(None, parse_date("aAௗ0㌀0"));
}

Now, let's see what happened... we forgot about UTF-8! You can't just blindly slice strings since you could split a character, in this case that Tamil diacritic placed atop other characters in the string.

In the interest of making the code changes as small as possible, we'll just check that the string is ASCII and reject anything that isn't.

fn parse_date(s: &str) -> Option<(u32, u32, u32)> {
    if 10 != s.len() { return None; }

    // NEW: Ignore non-ASCII strings so we don't need to deal with Unicode.
    if !s.is_ascii() { return None; }

    if "-" != &s[4..5] || "-" != &s[7..8] { return None; }

    let year = &s[0..4];
    let month = &s[6..7];
    let day = &s[8..10];

    year.parse::<u32>().ok().and_then(
        |y| month.parse::<u32>().ok().and_then(
            |m| day.parse::<u32>().ok().map(
                |d| (y, m, d))))
}

The tests pass now! But we know there are still more problems, so let's test more properties.

Another property we want from our code is that it parses every valid date. We can add another test to the proptest! section:

proptest! {
    // snip...

    #[test]
    fn parses_all_valid_dates(s in "[0-9]{4}-[0-9]{2}-[0-9]{2}") {
        parse_date(&s).unwrap();
    }
}

The thing to the right-hand side of in is actually a regular expression, and s is chosen from strings which match it. So in our previous test, "\\PC*" was generating arbitrary strings composed of arbitrary non-control characters. Now, we generate things in the YYYY-MM-DD format.

The new test passes, so let's move on to something else.

The final property we want to check is that the dates are actually parsed correctly. Now, we can't do this by generating strings — we'd end up just reimplementing the date parser in the test! Instead, we start from the expected output, generate the string, and check that it gets parsed back.

proptest! {
    // snip...

    #[test]
    fn parses_date_back_to_original(y in 0u32..10000,
                                    m in 1u32..13, d in 1u32..32) {
        let (y2, m2, d2) = parse_date(
            &format!("{:04}-{:02}-{:02}", y, m, d)).unwrap();
        // prop_assert_eq! is basically the same as assert_eq!, but doesn't
        // cause a bunch of panic messages to be printed on intermediate
        // test failures. Which one to use is largely a matter of taste.
        prop_assert_eq!((y, m, d), (y2, m2, d2));
    }
}

Here, we see that besides regexes, we can use any expression which is a proptest::strategy::Strategy, in this case, integer ranges.

The test fails when we run it. Though there's not much output this time.

thread 'main' panicked at 'Test failed: assertion failed: `(left == right)` (left: `(0, 10, 1)`, right: `(0, 0, 1)`) at examples/dateparser_v2.rs:46; minimal failing input: y = 0, m = 10, d = 1
	successes: 2
	local rejects: 0
	global rejects: 0
', examples/dateparser_v2.rs:33
note: Run with `RUST_BACKTRACE=1` for a backtrace.

The failing input is (y, m, d) = (0, 10, 1), which is a rather specific output. Before thinking about why this breaks the code, let's look at what proptest did to arrive at this value. At the start of our test function, insert

    println!("y = {}, m = {}, d = {}", y, m, d);

Running the test again, we get something like this:

y = 2497, m = 8, d = 27
y = 9641, m = 8, d = 18
y = 7360, m = 12, d = 20
y = 3680, m = 12, d = 20
y = 1840, m = 12, d = 20
y = 920, m = 12, d = 20
y = 460, m = 12, d = 20
y = 230, m = 12, d = 20
y = 115, m = 12, d = 20
y = 57, m = 12, d = 20
y = 28, m = 12, d = 20
y = 14, m = 12, d = 20
y = 7, m = 12, d = 20
y = 3, m = 12, d = 20
y = 1, m = 12, d = 20
y = 0, m = 12, d = 20
y = 0, m = 6, d = 20
y = 0, m = 9, d = 20
y = 0, m = 11, d = 20
y = 0, m = 10, d = 20
y = 0, m = 10, d = 10
y = 0, m = 10, d = 5
y = 0, m = 10, d = 3
y = 0, m = 10, d = 2
y = 0, m = 10, d = 1

The test failure message said there were two successful cases; we see these at the very top, 2497-08-27 and 9641-08-18. The next case, 7360-12-20, failed. There's nothing immediately obviously special about this date. Fortunately, proptest reduced it to a much simpler case. First, it rapidly reduced the y input to 0 at the beginning, and similarly reduced the d input to the minimum allowable value of 1 at the end. Between those two, though, we see something different: it tried to shrink 12 to 6, but then ended up raising it back up to 10. This is because the 0000-06-20 and 0000-09-20 test cases passed.

In the end, we get the date 0000-10-01, which apparently gets parsed as 0000-00-01. Again, this failing case was added to the failure persistence file, and we should add this as its own unit test:

$ git add proptest-regressions
#[test]
fn test_october_first() {
    assert_eq!(Some((0, 10, 1)), parse_date("0000-10-01"));
}

Now to figure out what's broken in the code. Even without the intermediate input, we can say with reasonable confidence that the year and day parts don't come into the picture since both were reduced to the minimum allowable input. The month input was not, but was reduced to 10. This means we can infer that there's something special about 10 that doesn't hold for 9. In this case, that "special something" is being two digits wide. In our code:

    let month = &s[6..7];

We were off by one, and need to use the range 5..7. After fixing this, the test passes.

The proptest! macro has some additional syntax, including for setting configuration for things like the number of test cases to generate. See its documentation for more details.

Differences between QuickCheck and Proptest

QuickCheck and Proptest are similar in many ways: both generate random inputs for a function to check certain properties, and automatically shrink inputs to minimal failing cases.

The one big difference is that QuickCheck generates and shrinks values based on type alone, whereas Proptest uses explicit Strategy objects. The QuickCheck approach has a lot of disadvantages in comparison:

  • QuickCheck can only define one generator and shrinker per type. If you need a custom generation strategy, you need to wrap it in a newtype and implement traits on that by hand. In Proptest, you can define arbitrarily many different strategies for the same type, and there are plenty built-in.

  • For the same reason, QuickCheck has a single "size" configuration that tries to define the range of values generated. If you need an integer between 0 and 100 and another between 0 and 1000, you probably need to do another newtype. In Proptest, you can directly just express that you want a 0..100 integer and a 0..1000 integer.

  • Types in QuickCheck are not easily composable. Defining Arbitrary and Shrink for a new struct which is simply produced by the composition of its fields requires implementing both by hand, including a bidirectional mapping between the struct and a tuple of its fields. In Proptest, you can make a tuple of the desired components and then prop_map it into the desired form. Shrinking happens automatically in terms of the input types.

  • Because constraints on values cannot be expressed in QuickCheck, generation and shrinking may lead to a lot of input rejections. Strategies in Proptest are aware of simple constraints and do not generate or shrink to values that violate them.

The author of Hypothesis also has an article on this topic.

Of course, there's also some relative downsides that fall out of what Proptest does differently:

  • Generating complex values in Proptest can be up to an order of magnitude slower than in QuickCheck. This is because QuickCheck performs stateless shrinking based on the output value, whereas Proptest must hold on to all the intermediate states and relationships in order for its richer shrinking model to work.

Limitations of Property Testing

Given infinite time, property testing will eventually explore the whole input space to a test. However, time is not infinite, so only a randomly sampled portion of the input space can be explored. This means that property testing is extremely unlikely to find single-value edge cases in a large space. For example, the following test will virtually always pass:

use proptest::prelude::*;

proptest! {
    #[test]
    fn i64_abs_is_never_negative(a: i64) {
        // This actually fails if a == i64::MIN, but randomly picking one
        // specific value out of 2⁶⁴ is overwhelmingly unlikely.
        assert!(a.abs() >= 0);
    }
}

Because of this, traditional unit testing with intelligently selected cases is still necessary for many kinds of problems.

Similarly, in some cases it can be hard or impossible to define a strategy which actually produces useful inputs. A strategy of .{1,4096} may be great to fuzz a C parser, but is highly unlikely to produce anything that makes it to a code generator.

Acknowledgements

This crate wouldn't have come into existence had it not been for the Rust port of QuickCheck and the regex_generate crate which gave wonderful examples of what is possible.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • `sample()` and `select()` functions are missing

    `sample()` and `select()` functions are missing

    My use case is a graph, where all nodes are randomly created, and then I want to select a subset for each node to connect to when I create the actual graph.

    However, there doesn't seem to be either a sample() or select() api with which to do this.

    opened by vitiral 52
  • Is Proptest abandoned?

    Is Proptest abandoned?

    There are a lot of open PRs, the project's own tests no longer pass (since #258) (TBH I can't even get the tests to compile)

    Not to be one of those entitled downstream users, but can @AltSysrq please let us know the state of the project, or if someone should fork/takeover as the canonical crate?

    Many thanks in advance

    opened by russelldb 34
  • Tracking issue for `proptest_derive`

    Tracking issue for `proptest_derive`

    This issue tracks things we need to do before shipping proptest_derive 0.1:

    • [x] Setup workspace
    • [x] Test proptest_derive with (Travis) CI
    • [x] Invite @AltSysrq as crate owner on crates.io
    • [x] Implement #[proptest(regex = "...")]
      • PR in https://github.com/AltSysrq/proptest/pull/103.
    • [x] Review the base function of the macro... is there anything we want to change?
      • [x] Should the base attribute be proptest or prop? or something else?
      • [x] Are the "sub-attributes" appropriately named and do they function well?
        • [x] weight (shorthand: w)
        • [x] strategy
        • [x] value
        • [x] params
        • [x] no_params
        • [x] skip
        • [x] no_bound
        • [x] filter
    • [x] Write user facing documentation in the form of an mdBook akin to https://serde.rs/ or https://mcarton.github.io/rust-derivative/ (example: https://rust-lang-nursery.github.io/edition-guide/introduction.html).
      • [x] Flesh out basic structure; should we include all of proptest or just proptest_derive for now?
      • [x] Write the guide
    • [x] Issues
      • [x] #[proptest(value = "4a")] is accepted by the macro but of course is ultimately invalid syntax.
    opened by Centril 17
  • The proptest_derive crate & #[derive(Arbitrary)]

    The proptest_derive crate & #[derive(Arbitrary)]

    This PR adds the crate proptest_derive to this repo.

    The advantage of not having this in a separate repo is that I expect both crates will be easier to maintain and test if they are in a single place. Another crate that does this is serde which sports its serde_derive crate here.

    The PR is pretty massive in size (sorry about that) but it is 100% consisting of additions and no code is touched outside of the proptest-derive directory. I recommend checking out my branch and starting from the tests directory to see what is supported and what is explicitly rejected.

    I'm sure there are places where the code can be refactored and improved, but I'd like to avoid making too many changes to this PR. We can of course make design changes and code improvements later.

    Some things TODO after merging this PR (to a separate branch, not master):

    1. Setup a workspace. Ideally, all the code for the proptest crate should go in its own directory in the root and proptest-derive should also be in the root.

    2. Make sure proptest-derive is tested with Travis CI and AppVeyor CI. For now, I have not made any changes to .travis.yml but there are plenty of tests (+50% of the code). These should all be run with a nightly compiler (because compiletest_rs wants it for pretty tests and because attr_literals is unstable). Until we've ensured that tests are run, it would be inadvisable to make breaking changes to proptest itself.

    3. I have to give you perms on crates.io so you can publish updates to proptest-derive at the same time as proptest.

    4. Release a 0.1 of proptest-derive.

    Here are some TODOs into the future:

    1. We should figure out what to do with self-recursive and mutually-recursive types. These are not supported at all and will blow the stack if attempted.

    2. Write extensive documentation (ideally in the form of an mdbook (see #36)). I haven't had the time to do that yet but I'll start on it ASAP.

    3. Improve error messages with correct spans and such things.

    4. Eventually use the custom error message API in https://internals.rust-lang.org/t/custom-error-diagnostics-with-procedural-macros-on-almost-stable-rust/8113 to segregate errors by warnings and so on...

    opened by Centril 17
  • Help implementing Arbitrary on an array of ArrayVec

    Help implementing Arbitrary on an array of ArrayVec

    This is a helpful library, and in many cases, I've found it to be more ergonomic than the quickcheck library.

    One issue I'm struggling with, though, is implementing Arbitrary for an array of ArrayVec values. I think the ideal code would look like:

    struct MyArrayVec(ArrayVec<[u8; 16]>); // Newtype-style wrapper
    
    impl Arbitrary for MyArrayVec {
        // what goes here?
    }
    
    #[derive(Arbitrary)]
    struct MyStruct {
      items: [MyArrayVec; 10],
    }
    

    But, I don't know the idiomatic way to do it. I see that the arbitrary! macro is not public in this crate (not that I would know how to use it). Perhaps the answer to this question could be added to a FAQ or HOWTO document. Thanks!

    opened by rw 15
  • does this replace quickcheck completely?

    does this replace quickcheck completely?

    If the answer is yes, then I'd be happy to start directing users your way. In particular, I read your section on the differences between QuickCheck and Proptest and all of them seem like advantages in favor of proptest over quickcheck. Is this an exhaustive comparison? That is, does quickcheck have any advantages over proptest?

    Apologies for the drive by comment. I haven't actually tried to use proptest yet, but figured I'd just get the ball rolling here. :)

    opened by BurntSushi 13
  • Make union value trees lazily generated.

    Make union value trees lazily generated.

    I wanted to put this up to get some early opinions. Note that there's the one API change that happens: the type param for UnionValueTree is no longer the tree -- it's the strategy. I don't think this should affect any actual code, but wanted to flag this just in case.

    I'll do lazy tuples as well if this looks good.

    Closes #143.

    opened by sunshowers 12
  • Strategy::prop_and_then for composing strategies

    Strategy::prop_and_then for composing strategies

    It would be nice to have the equivalent of {Option, Future}::and_then for composing Strategies. Composition can already be done via prop_compose! (which is probably more flexible), but for simply gluing together two strategies in a straight line and_then can be more straightforward and readable. Here's a sketch of what the API might look like:

        /// Returns a strategy which chains another strategy produced by `f` to this one.
        ///
        /// TODO: describe shrinking behavior
        fn prop_and_then<T, U, F>(self, f: F) -> AndThen<Self, U>
        where
            U: Strategy<Value=T>,
            F: FnOnce(Self::Value) -> U
        {
            ...
        }
    
    
    question 
    opened by danburkert 11
  • Strategy does not implement Sync

    Strategy does not implement Sync

    I'm not sure if there is a technical reason this is not possible, but I thought I would check.

    I would like to create the regex strategy using lazy_static! but Strategies don't implement Sync.

    Thanks!

    error[E0277]: the trait bound `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static: std::marker::Sync` is not satisfied
      --> src/test_name.rs:38:1
       |
    38 | / lazy_static!{
    39 | |     static ref GEN_NAME_PROP: prop::string::RegexGeneratorStrategy<String> =
    40 | |         prop::string::string_regex(GEN_NAME_RE).unwrap();
    41 | | }
       | |_^ `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static` cannot be shared between threads safely
       |
       = help: the trait `std::marker::Sync` is not implemented for `proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static`
       = note: required because of the requirements on the impl of `std::marker::Sync` for `std::ptr::Unique<proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String
    > + 'static>> + 'static>`
       = note: required because it appears within the type `std::boxed::Box<proptest::strategy::Strategy<Value=std::boxed::Box<proptest::strategy::ValueTree<Value=std::string::String> + 'static>> + 'static>`
       = note: required because it appears within the type `proptest::string::RegexGeneratorStrategy<std::string::String>`
       = note: required by `lazy_static::lazy::Lazy`
       = note: this error originates in a macro outside of the current crate
    
    error: aborting due to previous error
    
    error: Could not compile `artifact-data`.
    
    opened by vitiral 11
  • Update to rand 0.7

    Update to rand 0.7

    The primary change is due to rand's new error handling. With rand 0.7, the rand::Error type now contains either a boxed Error (when std is available) or a NonZeroU32 (in no_std cases). As a result, I've introduced a new PassThroughExhaustedError type. When std is available, the implementation creates a rand::Error by boxing a PassThroughExhaustedError, while in no_std cases, it uses an error code representing the error.

    Fixes #168.

    opened by jturner314 10
  • 128-bit support

    128-bit support

    error[E0277]: the trait bound `std::ops::Range<u128>: proptest::strategy::Strategy` is not satisfied
      --> tests\jump_tests.rs:74:1
       |
    74 | / proptest! {
    75 | |   #[test]
    76 | |   fn prop_for_jump_lcg128(s in 0..core::u128::MAX, j in 0..core::u16::MAX) {
    77 | |     // Note(Lokathor): Yes, `j` is supposed to be only up to `u16`, or the test
    ...  |
    89 | |   }
    90 | | }
       | |_^ the trait `proptest::strategy::Strategy` is not implemented for `std::ops::Range<u128>
    
    opened by Lokathor 10
  • Multi-core testing

    Multi-core testing

    I found that proptest only utilizes one core. The task of running a function for a number of inputs seems embarassingly parallel. Is there a way to run proptest with multiple threads?

    opened by GoldsteinE 0
  • Provide a way to also supply multiple manual test cases, that is, parameterized or explicit cases.

    Provide a way to also supply multiple manual test cases, that is, parameterized or explicit cases.

    Often when writing tests, it's good practice to include specific known test cases (usually around boundaries).

    Currently, there seems to be these options:

    1. Manually write an individual test for each case. This works with one or a small number of boundaries, but becomes burdensome for any large number of similarly-structured cases.
    2. Use a macro to generate cases (or a crate that provides such a macro). This works, but generates additional methods under the covers. Failures refer to the failing line in the duplicated method, but picking the case out of the list may be hard in some cases. Too, this requires an additional crate, and almost certainly one that doesn't work with proptest.
    3. With proptest, use sample or uniform to select from a list of cases. At lower counts of cases, this should run all of them. However, this is really a misuse of those methods, and may end up confusing the engine besides. Additionally, it can be hard to spot which test case is failing with large manual lists. (4. Might be possible to add manual cases to the regression files? Haven't tried, but this seems like even more of a hack, and that you're more likely to lose cases when tests change)

    What I'd like is some way to provide explicit, multiple, test cases, in addition to the ones generated by proptest. All cases should be run (as opposed to only being maybe run, as with sample/uniform). Simplification scenarios would likely need to ignore the cases (especially for composed strategies), but being able to consider them as "known good" data would be a bonus. Ideally, it would also be possible to trace back to which manual case failed (eg, a line number, in addition to the data).

    opened by Clockwork-Muse 1
  • Improve float range sampling

    Improve float range sampling

    The current implementation has the flaw that it doesn't sample all the floating point values in the range. For example sampling from the f32 range [0.0, 16777216.0] will never generate any value with a fractional part even through around most of the floating point values in this range have fractional parts.

    This pull request addresses this by using a new algorithm that doesn't have that issue.

    opened by mikerite 0
  • Generating sorted sequences

    Generating sorted sequences

    What's the best way to generate sorted sequences of elements (integers, in my case)? The naive approach is just

    vec(element(), size).prop_map(|mut vec| {
        vec.sort();
        vec
    })
    

    but that's very sub-optimal in terms of shrinkage, is there a better approach?

    opened by Kixiron 2
  • Is it possible to run a test for particular seed?

    Is it possible to run a test for particular seed?

    On case of test failure hypothesis suggests to add decorator @reproduce_faliure("") to easily reproduce and debug a particular failure. This is very convenient for the usual pipeline Test -> Fix failure with debugger -> Look for the next failures.

    Do we have something similar? Or can we add this functionality?

    opened by Yamp 0
Releases(0.9.6)
Owner
Jason Lingle
Jason Lingle
A utility like pkg-audit for Arch Linux. Based on Arch Security Team data.

arch-audit pkg-audit-like utility for Arch Linux. Based on data from security.archlinux.org collected by the awesome Arch Security Team. Installation

Andrea Scarpino 316 Nov 22, 2022
Rslide - A web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app console or the browser. Currently only supports Windows.

rslide rslide is a web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app conso

Jason Dongheng Lee 3 Jan 1, 2022
Detects usage of unsafe Rust in a Rust crate and its dependencies.

cargo-geiger ☢️ Looking for maintainer: https://github.com/rust-secure-code/cargo-geiger/issues/210 A program that lists statistics related to the usa

Rust Secure Code Working Group 1.1k Jan 4, 2023
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Rust-verification-tools - RVT is a collection of tools/libraries to support both static and dynamic verification of Rust programs.

Rust verification tools This is a collection of tools/libraries to support both static and dynamic verification of Rust programs. We see static verifi

null 253 Dec 31, 2022
Rust bindings for libinjection

libinjection-rs Rust bindings for libinjection. How to use Add libinjection to dependencies of Cargo.toml: libinjection = "0.2" Import crate: extern c

ArvanCloud 35 Sep 24, 2022
A simple password manager written in Rust

ripasso A simple password manager written in Rust. The root crate ripasso is a library for accessing and decrypting passwords stored in pass format (G

Joakim Lundborg 548 Dec 26, 2022
tcp connection hijacker, rust rewrite of shijack

rshijack tcp connection hijacker, rust rewrite of shijack from 2001. This was written for TAMUctf 2018, brick house 100. The target was a telnet serve

null 377 Jan 1, 2023
A fast, simple, recursive content discovery tool written in Rust.

A simple, fast, recursive content discovery tool written in Rust ?? Releases ✨ Example Usage ✨ Contributing ✨ Documentation ?? ?? What the heck is a f

epi 3.6k Dec 30, 2022
link is a command and control framework written in rust

link link is a command and control framework written in rust. Currently in alpha. Table of Contents Introduction Features Feedback Build Process Ackno

null 427 Dec 24, 2022
CVEs for the Rust standard library

Rust CVE Preface This is a list of CVEs for unsound APIs in the Rust standard library. These bugs break Rust's memory safety guarantee and lead to sec

Yechan Bae 26 Dec 4, 2022
Rust bindings for VirusTotal/Yara

yara-rust Bindings for the Yara library from VirusTotal. More documentation can be found on the Yara's documentation. Example The implementation is in

null 43 Dec 17, 2022
Rust library for building and running BPF/eBPF modules

RedBPF A Rust eBPF toolchain. Overview The redbpf project is a collection of tools and libraries to build eBPF programs using Rust. It includes: redbp

foniod 1.5k Jan 1, 2023
Rust library for developing safe canisters.

IC Kit This library provides an alternative to ic-cdk that can help developers write canisters and unit test them in their Rust code. Install Add this

Psychedelic 26 Nov 28, 2022
MimiRust - Hacking the Windows operating system to hand us the keys to the kingdom with Rust.

MimiRust - Hacking the Windows operating system to hand us the keys to the kingdom with Rust. MimiRust is a program based on the wdigest attack vector

Thotty 0 Nov 29, 2022
simple multi-threaded port scanner written in rust

knockson simple multi-threaded port scanner written in rust Install Using AUR https://aur.archlinux.org/packages/knockson-bin/ yay -Syu knockson-bin M

Josh Münte 4 Oct 5, 2022
Rust TLS/SSL certificate expiration date from command-line checker

Rust TLS/SSL certificate expiration date from command-line checker

Jose Bovet Derpich 9 Nov 9, 2022
Lightweight slowloris (HTTP DoS) implementation in Rust.

slowlorust Lightweight slowloris (HTTP DoS) implementation in Rust. Slowloris is a denial-of-service attack program which allows an attacker to overwh

Michael Van Leeuwen 6 Sep 29, 2022
A simple port scanner built using rust-lang

A simple port scanner built using rust-lang

Krisna Pranav 1 Nov 6, 2021