diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 6b08eaf..f847a17 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -21,26 +21,26 @@ jobs:
os: windows-latest
host_target: x86_64-pc-windows-msvc
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v2
- - name: Install latest nightly
- uses: actions-rs/toolchain@v1
- with:
- toolchain: nightly
- target: ${{ matrix.host_target }}
- override: true
+ - name: Install latest nightly
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: nightly
+ target: ${{ matrix.host_target }}
+ override: true
- - name: build
- uses: actions-rs/cargo@v1
- with:
- command: build
- args: --target=${{ matrix.host_target }} --release
+ - name: build
+ uses: actions-rs/cargo@v1
+ with:
+ command: build
+ args: --target=${{ matrix.host_target }} --release
- - name: test
- uses: actions-rs/cargo@v1
- with:
- command: test
- args: --release
+ - name: test
+ uses: actions-rs/cargo@v1
+ with:
+ command: test
+ args: --release
fmt:
name: check formatting
@@ -57,4 +57,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: fmt
- args: --all -- --check
\ No newline at end of file
+ args: --all -- --check
diff --git a/.github/workflows/just-ci.yml b/.github/workflows/just-ci.yml
new file mode 100644
index 0000000..4db7109
--- /dev/null
+++ b/.github/workflows/just-ci.yml
@@ -0,0 +1,33 @@
+name: Just CI
+
+on:
+ push:
+ branches: ["main", "master"]
+ pull_request:
+ branches: ["main", "master"]
+
+jobs:
+ just-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install Rust Nightly
+ uses: dtolnay/rust-toolchain@nightly
+ with:
+ components: clippy, rustfmt
+
+ - name: Install tools
+ uses: taiki-e/install-action@v2
+ with:
+ tool: just,taplo
+
+ - name: Run just fmt-check
+ run: just fmt-check
+
+ - name: Run just clippy
+ run: just clippy
+
+ - name: Run just test
+ run: just test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9bf2d5f..728f076 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,47 +1,40 @@
-## 0.5.3 (2020-11-09)
-* Fix some general bugs with resizing `Vec`
+## 0.5.3 (2020-11-09)
+- Fix some general bugs with resizing `Vec`
-## 0.5.2 (2020-07-07)
+## 0.5.2 (2020-07-07)
#### Features
-* **mutations:** add support for Box ([d6a2cc76](https://github.com/microsoft/lain/commit/d6a2cc76a3bffdb9719c9a385be33f4e29f70769))
-
-
+- **mutations:** add support for Box ([d6a2cc76](https://github.com/microsoft/lain/commit/d6a2cc76a3bffdb9719c9a385be33f4e29f70769))
-## 0.5.1 (2020-06-18)
+## 0.5.1 (2020-06-18)
#### Bug Fixes
-* **mutations:**
- * change how/when fixups are performed ([f51644e1](https://github.com/microsoft/lain/commit/f51644e1bd86f46586a7b24e26183082f6b33a94))
- * revert 1d79b7e0 which inlined generated mutations ([bf7ed1e7](https://github.com/microsoft/lain/commit/bf7ed1e77de5f29bc37ac06a2016b01734478545))
-* **serialization:** revert 2076d121 which inlined generated serde code ([917c1baa](https://github.com/microsoft/lain/commit/917c1baa7d4a54c5faf404542e7ac3609741ebba))
-
-
+- **mutations:**
+ - change how/when fixups are performed ([f51644e1](https://github.com/microsoft/lain/commit/f51644e1bd86f46586a7b24e26183082f6b33a94))
+ - revert 1d79b7e0 which inlined generated mutations ([bf7ed1e7](https://github.com/microsoft/lain/commit/bf7ed1e77de5f29bc37ac06a2016b01734478545))
+- **serialization:** revert 2076d121 which inlined generated serde code ([917c1baa](https://github.com/microsoft/lain/commit/917c1baa7d4a54c5faf404542e7ac3609741ebba))
-## 0.5 (2020-06-16)
+## 0.5 (2020-06-16)
#### Bug Fixes
-* **constraints:** Mutating now strictly respects max size constraint ([2e487784](https://github.com/microsoft/lain/commit/2e4877845d9a02df736944dbe09e56f3daf86cab))
-* **mutations:**
- * ignore_chance should now be working for enum variants ([a97cb173](https://github.com/microsoft/lain/commit/a97cb173f4b20f6f1923279d007a9fe9538c94fb))
- * partially fix regression where ignore_chance did not work for enum variants ([e8d23ae2](https://github.com/microsoft/lain/commit/e8d23ae2768292a89e015b3faf73eee4bc9ca3af))
+- **constraints:** Mutating now strictly respects max size constraint ([2e487784](https://github.com/microsoft/lain/commit/2e4877845d9a02df736944dbe09e56f3daf86cab))
+- **mutations:**
+ - ignore_chance should now be working for enum variants ([a97cb173](https://github.com/microsoft/lain/commit/a97cb173f4b20f6f1923279d007a9fe9538c94fb))
+ - partially fix regression where ignore_chance did not work for enum variants ([e8d23ae2](https://github.com/microsoft/lain/commit/e8d23ae2768292a89e015b3faf73eee4bc9ca3af))
#### Performance
-* **mutations:** hint to inline struct fuzzing functions ([1d79b7e0](https://github.com/microsoft/lain/commit/1d79b7e0732f6a3ef39e302e50fd5f79640cd143))
-* **serialization:** inline generated serialization code ([2076d121](https://github.com/microsoft/lain/commit/2076d121caaab15300163e284a706a55b42553c6))
-
-
-
+- **mutations:** hint to inline struct fuzzing functions ([1d79b7e0](https://github.com/microsoft/lain/commit/1d79b7e0732f6a3ef39e302e50fd5f79640cd143))
+- **serialization:** inline generated serialization code ([2076d121](https://github.com/microsoft/lain/commit/2076d121caaab15300163e284a706a55b42553c6))
diff --git a/Cargo.lock b/Cargo.lock
index 27598f3..075f719 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,27 +3,46 @@
version = 4
[[package]]
-name = "atty"
-version = "0.2.14"
+name = "aho-corasick"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
+ "memchr",
]
[[package]]
-name = "autocfg"
-version = "1.3.0"
+name = "alloca"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4"
+dependencies = [
+ "cc",
+]
[[package]]
-name = "bitflags"
-version = "1.3.2"
+name = "anes"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "anstyle"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
+
+[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
+[[package]]
+name = "autocfg"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "bitflags"
@@ -39,11 +58,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cast"
-version = "0.2.7"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
+name = "cc"
+version = "1.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
dependencies = [
- "rustc_version",
+ "find-msvc-tools",
+ "shlex",
]
[[package]]
@@ -53,102 +79,128 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "clap"
-version = "2.34.0"
+name = "chacha20"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
- "bitflags 1.3.2",
- "textwrap",
- "unicode-width",
+ "cfg-if",
+ "cpufeatures",
+ "rand_core",
]
[[package]]
-name = "cloudabi"
-version = "0.0.3"
+name = "ciborium"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
- "bitflags 1.3.2",
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
]
[[package]]
-name = "criterion"
-version = "0.2.11"
+name = "ciborium-io"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
+checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
- "atty",
- "cast",
- "clap",
- "csv",
- "itertools",
- "lazy_static",
- "libc",
- "num-traits",
- "rand_core 0.3.1",
- "rand_os",
- "rand_xoshiro",
- "rayon",
- "rayon-core",
- "serde",
- "serde_derive",
- "serde_json",
- "walkdir",
+ "ciborium-io",
+ "half",
]
[[package]]
-name = "crossbeam-deque"
-version = "0.8.6"
+name = "clap"
+version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
+checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
- "crossbeam-epoch",
- "crossbeam-utils",
+ "clap_builder",
]
[[package]]
-name = "crossbeam-epoch"
-version = "0.9.18"
+name = "clap_builder"
+version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
- "crossbeam-utils",
+ "anstyle",
+ "clap_lex",
]
[[package]]
-name = "crossbeam-utils"
-version = "0.8.21"
+name = "clap_lex"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
-name = "csv"
-version = "1.3.1"
+name = "cpufeatures"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
- "csv-core",
- "itoa",
- "ryu",
+ "libc",
+]
+
+[[package]]
+name = "criterion"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3"
+dependencies = [
+ "alloca",
+ "anes",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "itertools",
+ "num-traits",
+ "oorandom",
+ "page_size",
+ "regex",
"serde",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
]
[[package]]
-name = "csv-core"
-version = "0.1.11"
+name = "criterion-plot"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
+checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea"
dependencies = [
- "memchr",
+ "cast",
+ "itertools",
]
+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
[[package]]
name = "either"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
[[package]]
name = "field-offset"
version = "0.3.6"
@@ -160,37 +212,86 @@ dependencies = [
]
[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
+name = "find-msvc-tools"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
+[[package]]
+name = "foldhash"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
-version = "0.3.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"libc",
- "wasi",
- "windows-targets",
+ "r-efi",
+ "rand_core",
+ "wasip2",
+ "wasip3",
]
[[package]]
-name = "hermit-abi"
-version = "0.1.19"
+name = "half"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
- "libc",
+ "cfg-if",
+ "crunchy",
+ "zerocopy",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
+dependencies = [
+ "foldhash",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
+name = "indexmap"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.17.0",
+ "serde",
+ "serde_core",
]
[[package]]
name = "itertools"
-version = "0.8.2"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
@@ -235,17 +336,23 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+[[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+
[[package]]
name = "libc"
-version = "0.2.154"
+version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
+checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "log"
-version = "0.4.25"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
@@ -301,9 +408,9 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
- "proc-macro2 1.0.93",
- "quote 1.0.38",
- "syn 2.0.96",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
]
[[package]]
@@ -346,6 +453,22 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "oorandom"
+version = "11.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
+
+[[package]]
+name = "page_size"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
[[package]]
name = "paste"
version = "1.0.15"
@@ -353,10 +476,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
-name = "ppv-lite86"
-version = "0.2.17"
+name = "prettyplease"
+version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
+dependencies = [
+ "proc-macro2 1.0.106",
+ "syn 2.0.117",
+]
[[package]]
name = "proc-macro2"
@@ -364,14 +491,14 @@ version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
dependencies = [
- "unicode-xid",
+ "unicode-xid 0.1.0",
]
[[package]]
name = "proc-macro2"
-version = "1.0.93"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
@@ -387,111 +514,64 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.38"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
- "proc-macro2 1.0.93",
+ "proc-macro2 1.0.106",
]
[[package]]
-name = "rand"
-version = "0.9.0"
+name = "r-efi"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
-dependencies = [
- "rand_chacha",
- "rand_core 0.9.0",
- "zerocopy",
-]
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
-name = "rand_chacha"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.9.0",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
-[[package]]
-name = "rand_core"
-version = "0.9.0"
+name = "rand"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [
+ "chacha20",
"getrandom",
- "zerocopy",
+ "rand_core",
]
[[package]]
-name = "rand_os"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
-dependencies = [
- "cloudabi",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.4.2",
- "rdrand",
- "winapi",
-]
-
-[[package]]
-name = "rand_xoshiro"
-version = "0.1.0"
+name = "rand_core"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929"
-dependencies = [
- "byteorder",
- "rand_core 0.3.1",
-]
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
[[package]]
-name = "rayon"
-version = "1.10.0"
+name = "regex"
+version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
- "either",
- "rayon-core",
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
]
[[package]]
-name = "rayon-core"
-version = "1.12.1"
+name = "regex-automata"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
- "crossbeam-deque",
- "crossbeam-utils",
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
]
[[package]]
-name = "rdrand"
-version = "0.4.0"
+name = "regex-syntax"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
-dependencies = [
- "rand_core 0.3.1",
-]
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rustc_version"
@@ -525,22 +605,32 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
-version = "1.0.217"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.217"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
- "proc-macro2 1.0.93",
- "quote 1.0.38",
- "syn 2.0.96",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
]
[[package]]
@@ -554,6 +644,12 @@ dependencies = [
"serde",
]
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
[[package]]
name = "syn"
version = "0.15.44"
@@ -562,17 +658,17 @@ checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
- "unicode-xid",
+ "unicode-xid 0.1.0",
]
[[package]]
name = "syn"
-version = "2.0.96"
+version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
- "proc-macro2 1.0.93",
- "quote 1.0.38",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
"unicode-ident",
]
@@ -585,12 +681,13 @@ dependencies = [
]
[[package]]
-name = "textwrap"
-version = "0.11.0"
+name = "tinytemplate"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
- "unicode-width",
+ "serde",
+ "serde_json",
]
[[package]]
@@ -600,16 +697,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
-name = "unicode-width"
-version = "0.1.14"
+name = "unicode-xid"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
-version = "0.1.0"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "walkdir"
@@ -622,12 +719,55 @@ dependencies = [
]
[[package]]
-name = "wasi"
-version = "0.13.3+wasi-0.2.2"
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
- "wit-bindgen-rt",
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
]
[[package]]
@@ -735,30 +875,109 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
-name = "wit-bindgen-rt"
-version = "0.33.0"
+name = "wit-bindgen"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
- "bitflags 2.8.0",
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn 2.0.117",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-parser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid 0.2.6",
+ "wasmparser",
]
[[package]]
name = "zerocopy"
-version = "0.8.14"
+version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
+checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.14"
+version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
+checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
dependencies = [
- "proc-macro2 1.0.93",
- "quote 1.0.38",
- "syn 2.0.96",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
]
diff --git a/Cargo.toml b/Cargo.toml
index 18ce4cd..0f9d415 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,12 +1,8 @@
[workspace]
-members = [
- 'testsuite',
- 'lain',
- 'lain_derive',
-]
+members = ['testsuite', 'lain', 'lain_derive']
[workspace.package]
-version = "0.5.7"
+version = "0.5.7"
authors = ["Lain Devs", "AFLplusplus"]
edition = "2018"
homepage = "https://github.com/AFLplusplus/lain"
diff --git a/Justfile b/Justfile
new file mode 100644
index 0000000..83f2668
--- /dev/null
+++ b/Justfile
@@ -0,0 +1,74 @@
+# Default recipe to list all available tasks
+default:
+ @just --list
+
+# Run all tests (clippy, unit tests, and example fuzzer verification)
+@test duration="5": clippy test-unit (test-fuzzer duration)
+
+# Check code formatting and lints
+clippy:
+ cargo clippy --workspace --all-targets -- -D warnings
+
+# Format codebase (Rust, TOML, YAML, Markdown, Justfile)
+fmt:
+ cargo fmt --all
+ taplo format
+ npx prettier --write "**/*.yml" "**/*.yaml" "**/*.md"
+ just --fmt --unstable
+
+# Check codebase formatting (Rust, TOML, YAML, Markdown, Justfile)
+fmt-check:
+ cargo fmt --all -- --check
+ taplo format --check
+ npx prettier --check "**/*.yml" "**/*.yaml" "**/*.md"
+ just --fmt --check --unstable
+
+# Run unit tests across the workspace
+test-unit:
+ cargo test --workspace
+
+# Build the example target server
+build-target:
+ cd examples/example_target && make
+
+# Build the example fuzzer
+build-fuzzer:
+ cd examples/example_fuzzer && cargo build
+
+# Run the example fuzzer for a specified duration to ensure it runs successfully without crashing
+@test-fuzzer duration="5": build-target build-fuzzer
+ #!/usr/bin/env bash
+ set -euo pipefail
+
+ echo "Starting example target server..."
+ ./examples/example_target/server &
+ SERVER_PID=$!
+
+ # Ensure server is cleaned up on exit
+ trap 'kill $SERVER_PID 2>/dev/null || true' EXIT
+
+ # Wait for server to start listening
+ sleep 1
+
+ echo "Running example fuzzer for {{ duration }} seconds..."
+ # Run the fuzzer binary directly to avoid cargo overhead and accurately capture PID
+ ./examples/target/debug/example_fuzzer &
+ FUZZER_PID=$!
+
+ # Sleep for the specified duration
+ sleep {{ duration }}
+
+ echo "Checking if fuzzer is still running..."
+ if kill -0 $FUZZER_PID 2>/dev/null; then
+ echo "Fuzzer is running fine. Stopping it gracefully..."
+ kill -INT $FUZZER_PID
+ wait $FUZZER_PID || true
+ echo "Fuzzer ran successfully for {{ duration }} seconds."
+ else
+ echo "Error: Fuzzer crashed or stopped prematurely!"
+ # Check if server crashed
+ if ! kill -0 $SERVER_PID 2>/dev/null; then
+ echo "Error: Server crashed!"
+ fi
+ exit 1
+ fi
diff --git a/examples/Cargo.lock b/examples/Cargo.lock
index f9f813a..83dbcd3 100644
--- a/examples/Cargo.lock
+++ b/examples/Cargo.lock
@@ -1,392 +1,690 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
[[package]]
name = "autocfg"
-version = "0.1.4"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
-version = "1.1.0"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
+
+[[package]]
+name = "block2"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
+dependencies = [
+ "objc2",
+]
[[package]]
name = "byteorder"
-version = "1.3.2"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
-name = "c2-chacha"
-version = "0.2.2"
+name = "cfg-if"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
+name = "chacha20"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if",
+ "cpufeatures",
+ "rand_core",
]
[[package]]
-name = "cc"
-version = "1.0.37"
+name = "cpufeatures"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
[[package]]
-name = "cfg-if"
-version = "0.1.9"
+name = "ctrlc"
+version = "3.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162"
+dependencies = [
+ "dispatch2",
+ "nix",
+ "windows-sys",
+]
[[package]]
-name = "ctrlc"
-version = "3.1.3"
+name = "dispatch2"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [
- "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags",
+ "block2",
+ "libc",
+ "objc2",
]
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
[[package]]
name = "example_fuzzer"
version = "0.1.0"
dependencies = [
- "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lain 0.2.0",
+ "ctrlc",
+ "lain",
]
[[package]]
name = "field-offset"
-version = "0.1.1"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
+dependencies = [
+ "memoffset",
+ "rustc_version",
+]
+
+[[package]]
+name = "foldhash"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
-version = "0.1.6"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "rand_core",
+ "wasip2",
+ "wasip3",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
+ "foldhash",
]
+[[package]]
+name = "hashbrown"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
+name = "indexmap"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.17.0",
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
[[package]]
name = "lain"
-version = "0.2.0"
+version = "0.5.7"
dependencies = [
- "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lain_derive 0.2.0",
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder",
+ "field-offset",
+ "lain_derive",
+ "lazy_static",
+ "log",
+ "num",
+ "num-derive",
+ "num-traits",
+ "paste",
+ "rand",
]
[[package]]
name = "lain_derive"
-version = "0.2.0"
+version = "0.5.7"
dependencies = [
- "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder",
+ "log",
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "syn 0.15.39",
]
[[package]]
name = "lazy_static"
-version = "1.3.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
-version = "0.2.59"
+version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "log"
-version = "0.4.7"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
-name = "mashup"
-version = "0.1.9"
+name = "memchr"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
-name = "mashup-impl"
-version = "0.1.9"
+name = "memoffset"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
- "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg",
]
[[package]]
name = "nix"
-version = "0.14.1"
+version = "0.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
dependencies = [
- "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
- "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
]
[[package]]
name = "num"
-version = "0.2.0"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
dependencies = [
- "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint",
+ "num-complex",
+ "num-integer",
+ "num-iter",
+ "num-rational",
+ "num-traits",
]
[[package]]
name = "num-bigint"
-version = "0.2.2"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
- "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer",
+ "num-traits",
]
[[package]]
name = "num-complex"
-version = "0.2.3"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits",
]
[[package]]
name = "num-derive"
-version = "0.2.5"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
]
[[package]]
name = "num-integer"
-version = "0.1.41"
+version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits",
]
[[package]]
name = "num-iter"
-version = "0.1.39"
+version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg",
+ "num-integer",
+ "num-traits",
]
[[package]]
name = "num-rational"
-version = "0.2.2"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint",
+ "num-integer",
+ "num-traits",
]
[[package]]
name = "num-traits"
-version = "0.2.8"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "objc2"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc2-encode",
]
[[package]]
-name = "ppv-lite86"
-version = "0.2.5"
+name = "objc2-encode"
+version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
-name = "proc-macro-hack"
-version = "0.4.1"
+name = "paste"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
+[[package]]
+name = "prettyplease"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
- "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.106",
+ "syn 2.0.117",
]
[[package]]
-name = "proc-macro-hack-impl"
-version = "0.4.1"
+name = "proc-macro2"
+version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+dependencies = [
+ "unicode-xid 0.1.0",
+]
[[package]]
name = "proc-macro2"
-version = "0.4.30"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-ident",
]
[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
dependencies = [
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.30",
]
[[package]]
-name = "rand"
-version = "0.7.0"
+name = "quote"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
- "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.106",
]
[[package]]
-name = "rand_chacha"
-version = "0.2.0"
+name = "r-efi"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+
+[[package]]
+name = "rand"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chacha20",
+ "getrandom",
+ "rand_core",
]
[[package]]
name = "rand_core"
-version = "0.5.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
- "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "semver",
]
[[package]]
-name = "rand_hc"
-version = "0.2.0"
+name = "semver"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+
+[[package]]
+name = "serde"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
- "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_core",
]
[[package]]
-name = "rand_pcg"
-version = "0.2.0"
+name = "serde_core"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
- "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive",
]
[[package]]
-name = "spin"
-version = "0.5.0"
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
[[package]]
name = "syn"
version = "0.15.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
dependencies = [
- "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "unicode-xid 0.1.0",
]
+[[package]]
+name = "syn"
+version = "2.0.117"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+dependencies = [
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
-name = "void"
-version = "1.0.2"
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "wit-bindgen"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
+dependencies = [
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn 2.0.117",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2 1.0.106",
+ "quote 1.0.45",
+ "syn 2.0.117",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
+]
[[package]]
-name = "winapi"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[metadata]
-"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
-"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
-"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
-"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
-"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
-"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
-"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f"
-"checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68"
-"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55"
-"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
-"checksum libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "3262021842bf00fe07dbd6cf34ff25c99d7a7ebef8deea84db72be3ea3bb0aff"
-"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3"
-"checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b"
-"checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb"
-"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
-"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
-"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
-"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
-"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
-"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
-"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
-"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
-"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
-"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
-"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
-"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
-"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
-"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
-"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
-"checksum rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e193067942ef6f485a349a113329140d0ab9e2168ce92274499bb0e9a4190d9d"
-"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca"
-"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-"checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6"
-"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
-"checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
-"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
-"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+name = "wit-parser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid 0.2.6",
+ "wasmparser",
+]
+
+[[package]]
+name = "zmij"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
index 59f1606..5eeb174 100644
--- a/examples/Cargo.toml
+++ b/examples/Cargo.toml
@@ -1,4 +1,2 @@
[workspace]
-members = [
- 'example_fuzzer',
-]
+members = ['example_fuzzer']
diff --git a/examples/example_fuzzer/src/main.rs b/examples/example_fuzzer/src/main.rs
index 8dbaa7e..ece3c01 100644
--- a/examples/example_fuzzer/src/main.rs
+++ b/examples/example_fuzzer/src/main.rs
@@ -80,7 +80,10 @@ fn main() {
fn fuzzer_routine(mutator: &mut Mutator, thread_context: &mut FuzzerThreadContext, _global_context: Option>>) -> Result<(), ()> {
// TODO: we have overhead here of re-estabilishing the connection every time
- let mut stream = TcpStream::connect("127.0.0.1:8080").expect("server isn't running. possible crash?");
+ let mut stream = match TcpStream::connect("127.0.0.1:8080") {
+ Ok(s) => s,
+ Err(_) => return Err(()),
+ };
let packet = match thread_context.last_packet {
Some(ref mut last_packet) => {
@@ -88,7 +91,7 @@ fn fuzzer_routine(mutator: &mut Mutator, thread_context: &mut FuzzerT
last_packet
}
_ => {
- mutator.begin_new_corpus();
+ mutator.random_flags();
thread_context.last_packet = Some(PacketData::new_fuzzed(mutator, None));
thread_context.last_packet.as_mut().unwrap()
@@ -100,10 +103,12 @@ fn fuzzer_routine(mutator: &mut Mutator, thread_context: &mut FuzzerT
println!("Sending packet: {:?}", packet);
- stream.write(&serialized_data).expect("failed to write data");
+ if stream.write(&serialized_data).is_err() {
+ return Err(());
+ }
let mut response_data = Vec::new();
- stream.read(&mut response_data);
+ let _ = stream.read(&mut response_data);
thread_context.thread_packet_iterations += 1;
diff --git a/examples/example_target/main.c b/examples/example_target/main.c
index 6133cb7..c70f520 100644
--- a/examples/example_target/main.c
+++ b/examples/example_target/main.c
@@ -84,15 +84,14 @@ int main(int argc, char **argv) {
switch (datagram->type) {
case data_read:
LOG("got a data read packet\n");
- if (saved_data != NULL && datagram->offset + datagram->length <= saved_data_length) {
- write(connfd, packet_buffer + datagram->offset, datagram->length);
+ if (saved_data != NULL && datagram->offset + datagram->length >= datagram->offset && datagram->offset + datagram->length <= saved_data_length) {
+ write(connfd, saved_data + datagram->offset, datagram->length);
}
break;
case data_write:
LOG("got a data write packet\n");
- // NOTE: Who cares about checking the offset? Nobody would ever provide bad data
- if (saved_data != NULL && datagram->length <= saved_data_length) {
+ if (saved_data != NULL && datagram->offset + datagram->length >= datagram->offset && datagram->offset + datagram->length <= saved_data_length) {
memcpy(saved_data + datagram->offset, datagram->data, datagram->length);
}
break;
diff --git a/lain/Cargo.toml b/lain/Cargo.toml
index b311082..3b01884 100644
--- a/lain/Cargo.toml
+++ b/lain/Cargo.toml
@@ -9,16 +9,16 @@ keywords.workspace = true
license.workspace = true
[dependencies]
-rand = { version = "0.9", features = ["small_rng"] }
+rand = { version = "0.10.1" }
byteorder = "1.5.0"
paste = "1.0.15"
lain_derive = { version = "0.5.7", path = "../lain_derive" }
-log = "0.4"
+log = "0.4.29"
num-traits = "0.2.19"
num-derive = "0.4.2"
num = "0.4.3"
lazy_static = "1.5.0"
-serde = { version = "1.0.217", optional = true, features = ["derive"] }
+serde = { version = "1.0.228", optional = true, features = ["derive"] }
field-offset = "0.3.6"
[features]
diff --git a/lain/src/buffer.rs b/lain/src/buffer.rs
index f717845..3417cd5 100644
--- a/lain/src/buffer.rs
+++ b/lain/src/buffer.rs
@@ -36,46 +36,31 @@ where
}
}
-macro_rules! impl_serialized_size_array {
- ( $($size:expr),* ) => {
- $(
- impl SerializedSize for [T; $size]
- where T: SerializedSize {
- #[inline]
- fn serialized_size(&self) -> usize {
- trace!("using default serialized_size for array");
- if $size == 0 {
- return 0;
- }
-
- let size = self
- .iter()
- .map(SerializedSize::serialized_size)
- .fold(0, |sum, i| sum + i);
+impl SerializedSize for [T; SIZE]
+where
+ T: SerializedSize,
+{
+ #[inline]
+ fn serialized_size(&self) -> usize {
+ trace!("using default serialized_size for array");
+ if SIZE == 0 {
+ return 0;
+ }
- size
- }
+ self.iter().map(SerializedSize::serialized_size).sum()
+ }
- #[inline]
- fn min_nonzero_elements_size() -> usize {
- T::min_nonzero_elements_size() * $size
- }
+ #[inline]
+ fn min_nonzero_elements_size() -> usize {
+ T::min_nonzero_elements_size() * SIZE
+ }
- #[inline]
- fn max_default_object_size() -> usize {
- T::max_default_object_size() * $size
- }
- }
- )*
+ #[inline]
+ fn max_default_object_size() -> usize {
+ T::max_default_object_size() * SIZE
}
}
-impl_serialized_size_array!(
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
-);
-
impl SerializedSize for Vec
where
T: SerializedSize,
@@ -415,10 +400,10 @@ where
#[inline]
fn serialized_size(&self) -> usize {
if let Some(ref inner) = self {
- inner.serialized_size();
+ inner.serialized_size()
+ } else {
+ 0
}
-
- 0
}
#[inline]
diff --git a/lain/src/dangerous_numbers.rs b/lain/src/dangerous_numbers.rs
index dc29801..e7d9102 100644
--- a/lain/src/dangerous_numbers.rs
+++ b/lain/src/dangerous_numbers.rs
@@ -1,4 +1,4 @@
-use crate::rand::Rng;
+use crate::rand::{Rng, RngExt};
use crate::traits::*;
static DANGEROUS_NUMBERS_U8: &[u8] = &[
diff --git a/lain/src/driver.rs b/lain/src/driver.rs
index 34d5424..830684b 100644
--- a/lain/src/driver.rs
+++ b/lain/src/driver.rs
@@ -1,6 +1,6 @@
use crate::mutator::Mutator;
use rand::rngs::StdRng;
-use rand::{Rng, SeedableRng};
+use rand::{RngExt, SeedableRng};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, RwLock};
use std::thread;
diff --git a/lain/src/lib.rs b/lain/src/lib.rs
index c2184a2..19048cc 100644
--- a/lain/src/lib.rs
+++ b/lain/src/lib.rs
@@ -4,6 +4,7 @@
//! Please consider this crate in "beta" and subject to breaking changes for minor version releases for pre-1.0.
#![feature(specialization)]
+#![allow(dead_code, unused_variables, incomplete_features)]
extern crate num;
extern crate num_derive;
@@ -58,7 +59,7 @@ pub fn hexdump(data: &[u8]) -> String {
}
}
- if data.len() % 16 != 0 {
+ if !data.len().is_multiple_of(16) {
for _i in 0..16 - (data.len() % 16) {
ret += " ";
}
diff --git a/lain/src/mutatable.rs b/lain/src/mutatable.rs
index 37670b7..d68f7dd 100644
--- a/lain/src/mutatable.rs
+++ b/lain/src/mutatable.rs
@@ -32,6 +32,74 @@ enum VecResizeType {
Shrink,
}
+/// Performs robust, structural resizing on character sequences.
+/// Supports stochastic splicing, raw element injection, and multi-mode shrinkage.
+fn advanced_resize(vec: &mut Vec, mutator: &mut Mutator, mut gen: F)
+where
+ T: Clone,
+ F: FnMut(&mut Mutator) -> T,
+{
+ if vec.is_empty() || mutator.gen_chance(0.5) {
+ // Growing
+ if vec.is_empty() || mutator.gen_chance(0.5) {
+ let grow_by = mutator.random_range(1, 16);
+ for _ in 0..grow_by {
+ vec.push(gen(mutator));
+ }
+ } else {
+ let start = mutator.random_range(0, vec.len());
+ let end = mutator.random_range(start, vec.len() + 1);
+ let chunk = vec[start..end].to_vec();
+ let insert_at = mutator.random_range(0, vec.len() + 1);
+ vec.splice(insert_at..insert_at, chunk);
+ }
+ } else if !vec.is_empty() {
+ // Shrinking
+ if mutator.gen_chance(0.5) {
+ let start = mutator.random_range(0, vec.len());
+ let end = mutator.random_range(start, vec.len() + 1);
+ vec.drain(start..end);
+ } else {
+ let remove_count = mutator.random_range(1, vec.len() + 1);
+ if mutator.gen_chance(0.5) {
+ vec.drain(0..remove_count);
+ } else {
+ vec.truncate(vec.len() - remove_count);
+ }
+ }
+ }
+}
+
+/// Encapsulates entire character fuzzing process for structural string buffers.
+fn mutate_char_vec(vec: &mut Vec, mutator: &mut Mutator, mut gen: F)
+where
+ T: Clone,
+ F: FnMut(&mut Mutator) -> T,
+{
+ const CHANCE_TO_RESIZE: f64 = 0.01;
+ const CHANCE_TO_RESIZE_EMPTY: f64 = 0.33;
+
+ let should_resize = if vec.is_empty() {
+ mutator.gen_chance(CHANCE_TO_RESIZE_EMPTY)
+ } else {
+ mutator.gen_chance(CHANCE_TO_RESIZE)
+ };
+
+ if should_resize {
+ advanced_resize(vec, mutator, &mut gen);
+ return;
+ }
+
+ if vec.is_empty() {
+ return;
+ }
+
+ let num_mutations = mutator.random_range(1, vec.len());
+ for idx in index::sample(&mut mutator.rng, vec.len(), num_mutations).iter() {
+ vec[idx] = gen(mutator);
+ }
+}
+
/// Grows a `Vec`.
/// This will randomly select to grow by a factor of 1/4, 1/2, 3/4, or a fixed number of bytes
/// in the range of [1, 8]. Elements may be added randomly to the beginning or end of the the vec
@@ -539,12 +607,7 @@ impl Mutatable for AsciiString {
_constraints: Option<&Constraints>,
) {
trace!("performing mutation on an AsciiString");
-
- // TODO: Implement logic for resizing?
- let num_mutations = mutator.random_range(1, self.inner.len());
- for idx in index::sample(&mut mutator.rng, self.inner.len(), num_mutations).iter() {
- self.inner[idx] = AsciiChar::new_fuzzed(mutator, None);
- }
+ mutate_char_vec(&mut self.inner, mutator, |m| AsciiChar::new_fuzzed(m, None));
}
}
@@ -557,12 +620,22 @@ impl Mutatable for Utf8String {
_constraints: Option<&Constraints>,
) {
trace!("performing mutation on a Utf8String");
+ mutate_char_vec(&mut self.inner, mutator, |m| Utf8Char::new_fuzzed(m, None));
+ }
+}
- // TODO: Implement logic for resizing?
- let num_mutations = mutator.random_range(1, self.inner.len());
- for idx in index::sample(&mut mutator.rng, self.inner.len(), num_mutations).iter() {
- self.inner[idx] = Utf8Char::new_fuzzed(mutator, None);
- }
+impl Mutatable for String {
+ type RangeType = usize;
+
+ fn mutate(
+ &mut self,
+ mutator: &mut Mutator,
+ _constraints: Option<&Constraints>,
+ ) {
+ trace!("performing mutation on a String");
+ let mut chars: Vec = self.chars().collect();
+ mutate_char_vec(&mut chars, mutator, |m| char::new_fuzzed(m, None));
+ *self = chars.into_iter().collect();
}
}
@@ -643,18 +716,41 @@ impl Mutatable for i64 {
}
}
-impl Mutatable for [T; 0]
-where
- T: Mutatable,
-{
- type RangeType = u8;
+impl Mutatable for f32 {
+ type RangeType = f32;
+ #[inline(always)]
fn mutate(
&mut self,
- _mutator: &mut Mutator,
+ mutator: &mut Mutator,
_constraints: Option<&Constraints>,
) {
- // nop
+ if mutator.gen_chance(0.01) {
+ *self = f32::select_dangerous_number(&mut mutator.rng);
+ return;
+ }
+ let mut val = self.to_bits();
+ mutator.mutate(&mut val);
+ *self = f32::from_bits(val);
+ }
+}
+
+impl Mutatable for f64 {
+ type RangeType = f64;
+
+ #[inline(always)]
+ fn mutate(
+ &mut self,
+ mutator: &mut Mutator,
+ _constraints: Option<&Constraints>,
+ ) {
+ if mutator.gen_chance(0.01) {
+ *self = f64::select_dangerous_number(&mut mutator.rng);
+ return;
+ }
+ let mut val = self.to_bits();
+ mutator.mutate(&mut val);
+ *self = f64::from_bits(val);
}
}
@@ -730,28 +826,20 @@ where
}
}
-macro_rules! impl_mutatable_array {
- ( $($size:expr),* ) => {
- $(
- impl Mutatable for [T; $size]
- where
- T: Mutatable + SerializedSize,
- T::RangeType: Clone,
- {
- type RangeType = T::RangeType;
+impl Mutatable for [T; SIZE]
+where
+ T: Mutatable + SerializedSize,
+ T::RangeType: Clone,
+{
+ type RangeType = T::RangeType;
- #[inline(always)]
- fn mutate(&mut self, mutator: &mut Mutator, constraints: Option<&Constraints>) {
- // Treat this as a slice
- self[..].mutate(mutator, constraints);
- }
- }
- )*
+ #[inline(always)]
+ fn mutate(
+ &mut self,
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) {
+ // Treat this as a slice
+ self[..].mutate(mutator, constraints);
}
}
-
-impl_mutatable_array!(
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
-);
diff --git a/lain/src/mutator.rs b/lain/src/mutator.rs
index 863abae..809a086 100644
--- a/lain/src/mutator.rs
+++ b/lain/src/mutator.rs
@@ -1,5 +1,5 @@
use rand::seq::SliceRandom;
-use rand::Rng;
+use rand::{Rng, RngExt};
use crate::rand::distr::uniform::{SampleBorrow, SampleUniform};
use crate::traits::*;
@@ -163,9 +163,11 @@ impl Mutator {
let (bit_indices, _) = potential_bit_indices[0..num_bits as usize]
.partial_shuffle(&mut self.rng, num_bits as usize);
+ let mut mask = 0u64;
for idx in bit_indices {
- *num = (*num) ^ num::cast(1u64 << *idx).unwrap()
+ mask |= 1u64 << *idx;
}
+ *num = (*num) ^ num::cast(mask).unwrap();
}
/// Perform a simple arithmetic operation on the number (+ or -)
diff --git a/lain/src/new_fuzzed.rs b/lain/src/new_fuzzed.rs
index 68b7c6b..c028b61 100644
--- a/lain/src/new_fuzzed.rs
+++ b/lain/src/new_fuzzed.rs
@@ -1,6 +1,6 @@
use crate::mutator::Mutator;
-use crate::rand::Rng;
+use crate::rand::{Rng, RngExt};
use crate::traits::*;
use crate::types::*;
use num_traits::Bounded;
@@ -81,11 +81,11 @@ where
min = 0;
}
- if constraints.max.is_some()
- && mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX)
- {
- if let Some(new_max) = constraints.max.unwrap().checked_mul(2) {
- max = new_max;
+ if let Some(current_max) = constraints.max {
+ if mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX) {
+ if let Some(new_max) = current_max.checked_mul(2) {
+ max = new_max;
+ }
}
}
}
@@ -191,11 +191,11 @@ where
min = 0;
}
- if constraints.max.is_some()
- && mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX)
- {
- // we just hope this doesn't overflow.
- max = constraints.max.unwrap() * 2;
+ if let Some(current_max) = constraints.max {
+ if mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX) {
+ // we just hope this doesn't overflow.
+ max = current_max * 2;
+ }
}
}
@@ -294,46 +294,6 @@ where
}
}
-// TODO: Uncomment once const generics are more stable
-// impl NewFuzzed for [T; SIZE]
-// where T: NewFuzzed + Clone {
-// type RangeType = usize;
-
-// fn new_fuzzed(mutator: &mut Mutator, constraints: Option<&Constraints>) -> [T; SIZE] {
-// if constraints.is_some() {
-// warn!("Constraints passed to new_fuzzed on fixed-size array do nothing");
-// }
-
-// let mut output: MaybeUninit<[T; SIZE]> = MaybeUninit::uninit();
-// let arr_ptr = output.as_mut_ptr() as *mut T;
-
-// let mut idx = 0;
-// let mut element: T = T::new_fuzzed(mutator, None);
-// while idx < SIZE {
-// arr_ptr.add(idx).write(element.clone());
-
-// idx += 1;
-// if SIZE - idx > 0 {
-// if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
-// let repeat_end_idx = mutator.random_range(idx, SIZE);
-// while idx < repeat_end_idx {
-// arr_ptr.add(idx).write(element.clone());
-// idx += 1;
-// }
-
-// if SIZE - idx > 0 {
-// element = T::new_fuzzed(mutator, None);
-// }
-// } else {
-// element = T::new_fuzzed(mutator, None);
-// }
-// }
-// }
-
-// unsafe { output.assume_init() }
-// }
-// }
-
impl NewFuzzed for UnsafeEnum
where
T: NewFuzzed,
@@ -361,6 +321,68 @@ where
}
}
+impl NewFuzzed for String {
+ type RangeType = usize;
+
+ fn new_fuzzed(
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) -> Self {
+ let min: Self::RangeType;
+ let max: Self::RangeType;
+ let weight: Weighted;
+ let mut output: String;
+
+ trace!(
+ "Generating random String with constraints: {:#?}",
+ constraints
+ );
+
+ // if no min/max were supplied, we'll take a conservative approach
+ match constraints {
+ Some(constraints) => {
+ min = constraints.min.unwrap_or(0);
+ max = constraints.max.unwrap_or(256);
+ weight = constraints.weighted;
+ }
+ None => {
+ min = 0;
+ max = 256;
+ weight = Weighted::None;
+ }
+ }
+
+ let string_length = mutator.gen_weighted_range(min, max, weight);
+
+ output = String::with_capacity(string_length);
+
+ let mut idx = 0;
+ let mut chr = char::new_fuzzed(mutator, None);
+
+ while idx < string_length {
+ output.push(chr);
+
+ idx += 1;
+ if string_length - idx > 0 {
+ if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
+ let repeat_end_idx = mutator.random_range(idx, string_length);
+ while idx < repeat_end_idx {
+ output.push(chr);
+ idx += 1;
+ }
+ if string_length - idx > 0 {
+ chr = char::new_fuzzed(mutator, None);
+ }
+ } else {
+ chr = char::new_fuzzed(mutator, None);
+ }
+ }
+ }
+
+ output
+ }
+}
+
impl NewFuzzed for Utf8String {
type RangeType = usize;
@@ -408,9 +430,9 @@ impl NewFuzzed for Utf8String {
if string_length - idx > 0 {
if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
let repeat_end_idx = mutator.random_range(idx, string_length);
- while idx < repeat_end_idx {
- output.inner.push(chr.clone());
- idx += 1;
+ if repeat_end_idx > idx {
+ output.inner.resize(repeat_end_idx, chr.clone());
+ idx = repeat_end_idx;
}
if string_length - idx > 0 {
chr = Utf8Char::new_fuzzed(mutator, None);
@@ -472,9 +494,9 @@ impl NewFuzzed for AsciiString {
if string_length - idx > 0 {
if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
let repeat_end_idx = mutator.random_range(idx, string_length);
- while idx < repeat_end_idx {
- output.inner.push(chr.clone());
- idx += 1;
+ if repeat_end_idx > idx {
+ output.inner.resize(repeat_end_idx, chr.clone());
+ idx = repeat_end_idx;
}
if string_length - idx > 0 {
chr = AsciiChar::new_fuzzed(mutator, None);
@@ -749,91 +771,135 @@ macro_rules! impl_new_fuzzed {
// BUG: f32/f64 generate a number between 0/1 when no constraints are supplied,
// otherwise they generate an *integer* between min/max.
-impl_new_fuzzed!(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64);
+impl_new_fuzzed!(u8, i8, u16, i16, u32, i32, u64, i64);
-impl NewFuzzed for [T; 0]
-where
- T: NewFuzzed + Clone,
-{
- type RangeType = usize;
+// Static safe float boundary limits to prevent division/calc overhead at runtime
+const DEFAULT_F32_MIN: f32 = -1.692947e38;
+const DEFAULT_F32_MAX: f32 = 1.692947e38;
+const DEFAULT_F64_MIN: f64 = -8.94374693961351e307;
+const DEFAULT_F64_MAX: f64 = 8.94374693961351e307;
+impl NewFuzzed for f32 {
+ type RangeType = f32;
+
+ #[inline(always)]
fn new_fuzzed(
- _mutator: &mut Mutator,
- _constraints: Option<&Constraints>,
- ) -> [T; 0] {
- // no-op
- []
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) -> Self {
+ if mutator.gen_chance(0.10) {
+ return f32::select_dangerous_number(&mut mutator.rng);
+ }
+ if let Some(constraints) = constraints {
+ let min = constraints.min.unwrap_or(DEFAULT_F32_MIN);
+ let max = constraints.max.unwrap_or(DEFAULT_F32_MAX);
+ if min >= max {
+ return min;
+ }
+ return mutator.gen_weighted_range(min, max, constraints.weighted);
+ }
+
+ // Unconstrained Smart Mode Strategy
+ let mode = mutator.rng.random_range(0..100);
+ match mode {
+ 0..=49 => {
+ // 50%: Float-specific standardized high-fidelity programmatic ranges
+ mutator.gen_weighted_range(-100000.0, 100000.0, Weighted::None)
+ }
+ 50..=74 => {
+ // 25%: Unadulterated bitwise float noise (exponents, extreme fractions)
+ f32::from_bits(mutator.rng.random::())
+ }
+ _ => {
+ // 25%: Pure corner boundaries (1.0, 0.0, -1.0, MIN_POSITIVE)
+ [1.0, 0.0, -1.0, f32::MIN_POSITIVE]
+ .choose(&mut mutator.rng)
+ .unwrap()
+ .to_owned()
+ }
+ }
}
}
-macro_rules! impl_new_fuzzed_array {
- ( $($size:expr),* ) => {
- $(
- impl NewFuzzed for [T; $size]
- where T: NewFuzzed + Clone + SerializedSize {
- type RangeType = usize;
-
- fn new_fuzzed(mutator: &mut Mutator, constraints: Option<&Constraints>) -> [T; $size] {
- let per_item_max_size: Option = constraints.and_then(|c| c.max_size.as_ref().and_then(|size| Some(*size / $size)));
+impl NewFuzzed for f64 {
+ type RangeType = f64;
- let mut output: MaybeUninit<[T; $size]> = MaybeUninit::uninit();
- let arr_ptr = output.as_mut_ptr() as *mut T;
+ #[inline(always)]
+ fn new_fuzzed(
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) -> Self {
+ if mutator.gen_chance(0.10) {
+ return f64::select_dangerous_number(&mut mutator.rng);
+ }
+ if let Some(constraints) = constraints {
+ let min = constraints.min.unwrap_or(DEFAULT_F64_MIN);
+ let max = constraints.max.unwrap_or(DEFAULT_F64_MAX);
+ if min >= max {
+ return min;
+ }
+ return mutator.gen_weighted_range(min, max, constraints.weighted);
+ }
- let constraints = per_item_max_size.as_ref().map(|size| {
- let mut constraints = Constraints::new();
- constraints.max_size(*size);
- constraints.set_base_size_accounted_for();
+ let mode = mutator.rng.random_range(0..100);
+ match mode {
+ 0..=49 => mutator.gen_weighted_range(-100000.0, 100000.0, Weighted::None),
+ 50..=74 => f64::from_bits(mutator.rng.random::()),
+ _ => [1.0, 0.0, -1.0, f64::MIN_POSITIVE]
+ .choose(&mut mutator.rng)
+ .unwrap()
+ .to_owned(),
+ }
+ }
+}
- constraints
- });
+impl NewFuzzed for [T; SIZE]
+where
+ T: NewFuzzed + Clone + SerializedSize,
+{
+ type RangeType = usize;
- let mut idx = 0;
- let mut element: T = T::new_fuzzed(mutator, constraints.as_ref());
+ fn new_fuzzed(
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) -> [T; SIZE] {
+ let per_item_max_size: Option = constraints.and_then(|c| {
+ c.max_size
+ .as_ref()
+ .map(|size| size.checked_div(SIZE).unwrap_or(0))
+ });
- while idx < $size {
- unsafe {
- arr_ptr.add(idx).write(element.clone());
- }
+ let mut output: MaybeUninit<[T; SIZE]> = MaybeUninit::uninit();
+ let arr_ptr = output.as_mut_ptr() as *mut T;
- idx += 1;
- if $size - idx > 0 {
- if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
- let repeat_end_idx = mutator.random_range(idx, $size);
- while idx < repeat_end_idx {
- unsafe {
- arr_ptr.add(idx).write(element.clone());
- }
- idx += 1;
- }
- } else {
- let constraints = per_item_max_size.as_ref().map(|size| {
- let mut constraints = Constraints::new();
- constraints.max_size(*size);
- constraints.set_base_size_accounted_for();
+ let constraints = per_item_max_size.as_ref().map(|size| {
+ let mut constraints = Constraints::new();
+ constraints.max_size(*size);
+ constraints.set_base_size_accounted_for();
- constraints
- });
+ constraints
+ });
- element = T::new_fuzzed(mutator, constraints.as_ref());
- }
- }
- }
+ let mut idx = 0;
+ if SIZE > 0 {
+ let mut element: T = T::new_fuzzed(mutator, constraints.as_ref());
- unsafe { output.assume_init() }
+ while idx < SIZE {
+ unsafe {
+ arr_ptr.add(idx).write(element.clone());
}
- }
-
- impl NewFuzzed for [T; $size]
- where T: NewFuzzed + SerializedSize {
- default type RangeType = usize;
-
- default fn new_fuzzed(mutator: &mut Mutator, constraints: Option<&Constraints>) -> [T; $size] {
- let per_item_max_size: Option = constraints.and_then(|c| c.max_size.as_ref().and_then(|size| Some(*size / $size)));
-
- let mut output: MaybeUninit<[T; $size]> = MaybeUninit::uninit();
- let arr_ptr = output.as_mut_ptr() as *mut T;
- for i in 0..$size {
+ idx += 1;
+ if SIZE - idx > 0 {
+ if mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE) {
+ let repeat_end_idx = mutator.random_range(idx, SIZE);
+ while idx < repeat_end_idx {
+ unsafe {
+ arr_ptr.add(idx).write(element.clone());
+ }
+ idx += 1;
+ }
+ } else {
let constraints = per_item_max_size.as_ref().map(|size| {
let mut constraints = Constraints::new();
constraints.max_size(*size);
@@ -841,25 +907,54 @@ macro_rules! impl_new_fuzzed_array {
constraints
});
- let element = T::new_fuzzed(mutator, constraints.as_ref());
- unsafe {
- arr_ptr.offset(i).write(element);
- }
+ element = T::new_fuzzed(mutator, constraints.as_ref());
}
-
- unsafe { output.assume_init() }
}
}
- )*
+ }
+
+ unsafe { output.assume_init() }
}
}
-impl_new_fuzzed_array!(
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
-);
+impl NewFuzzed for [T; SIZE]
+where
+ T: NewFuzzed + SerializedSize,
+{
+ default type RangeType = usize;
+
+ default fn new_fuzzed(
+ mutator: &mut Mutator,
+ constraints: Option<&Constraints>,
+ ) -> [T; SIZE] {
+ let per_item_max_size: Option = constraints.and_then(|c| {
+ c.max_size
+ .as_ref()
+ .map(|size| size.checked_div(SIZE).unwrap_or(0))
+ });
+
+ let mut output: MaybeUninit<[T; SIZE]> = MaybeUninit::uninit();
+ let arr_ptr = output.as_mut_ptr() as *mut T;
+
+ for i in 0..SIZE {
+ let constraints = per_item_max_size.as_ref().map(|size| {
+ let mut constraints = Constraints::new();
+ constraints.max_size(*size);
+ constraints.set_base_size_accounted_for();
+
+ constraints
+ });
+ let element = T::new_fuzzed(mutator, constraints.as_ref());
+
+ unsafe {
+ arr_ptr.add(i).write(element);
+ }
+ }
+
+ unsafe { output.assume_init() }
+ }
+}
impl NewFuzzed for *mut std::ffi::c_void {
type RangeType = usize;
diff --git a/lain_derive/Cargo.toml b/lain_derive/Cargo.toml
index 6fe4da2..eed994e 100644
--- a/lain_derive/Cargo.toml
+++ b/lain_derive/Cargo.toml
@@ -13,7 +13,7 @@ syn = { version = "0.15", features = ["extra-traits"] }
quote = "0.6"
proc-macro2 = "0.4"
byteorder = "1.5.0"
-log = "0.4.25"
+log = "0.4.29"
[lib]
proc-macro = true
diff --git a/lain_derive/src/internals/attr.rs b/lain_derive/src/internals/attr.rs
index bc341bf..946f348 100644
--- a/lain_derive/src/internals/attr.rs
+++ b/lain_derive/src/internals/attr.rs
@@ -124,7 +124,7 @@ impl Container {
self.min_serialized_size
}
- pub fn lain_path(&self) -> Cow {
+ pub fn lain_path(&self) -> Cow<'_, syn::Path> {
Cow::Owned(parse_quote!(_lain))
}
}
diff --git a/lain_derive/src/lib.rs b/lain_derive/src/lib.rs
index 4f3ba0f..89ecca3 100644
--- a/lain_derive/src/lib.rs
+++ b/lain_derive/src/lib.rs
@@ -1,5 +1,6 @@
// required for using the quote!{} macro for large invocations
#![recursion_limit = "256"]
+#![allow(dead_code)]
extern crate proc_macro;
extern crate proc_macro2;
diff --git a/lain_derive/src/mutations.rs b/lain_derive/src/mutations.rs
index d5561a0..0cac0ab 100644
--- a/lain_derive/src/mutations.rs
+++ b/lain_derive/src/mutations.rs
@@ -217,14 +217,10 @@ fn mutatable_unit_enum_visitor(
let variants = variants
.iter()
- .filter_map(|variant| {
- //if variant.attrs.ignore() {
- // None
- //} else {
+ .map(|variant| {
let variant_ident = &variant.ident;
weights.push(variant.attrs.weight().unwrap_or(1));
- Some(quote! {#cont_ident::#variant_ident})
- //}
+ quote! {#cont_ident::#variant_ident}
})
.collect();
@@ -234,13 +230,10 @@ fn mutatable_unit_enum_visitor(
fn mutatable_enum_visitor(variants: &[Variant], cont_ident: &syn::Ident) -> Vec {
let match_arms = variants
.iter()
- .filter_map(|variant| {
- // if variant.attrs.ignore() {
- // return None;
- // }
-
+ .map(|variant| {
let variant_ident = &variant.ident;
let full_ident = quote! {#cont_ident::#variant_ident};
+ let is_struct = variant.style == crate::internals::ast::Style::Struct;
let mut field_identifiers = vec![];
let field_mutators: Vec = variant
@@ -249,19 +242,35 @@ fn mutatable_enum_visitor(variants: &[Variant], cont_ident: &syn::Ident) -> Vec<
.map(|field| {
let (value_ident, _field_ident_string, initializer) =
field_mutator(field, "__field", true);
- field_identifiers.push(quote_spanned! { field.member.span() => #value_ident });
- initializer
+ if is_struct {
+ let member = &field.member;
+ field_identifiers.push(quote_spanned! { field.original.span() => #member: ref mut #value_ident });
+ } else {
+ field_identifiers.push(quote_spanned! { field.original.span() => ref mut #value_ident });
+ }
+
+ if field.attrs.ignore() {
+ TokenStream::new()
+ } else {
+ initializer
+ }
})
.collect();
- let match_arm = quote! {
- #full_ident(#(ref mut #field_identifiers,)*) => {
- #(#field_mutators)*
+ if is_struct {
+ quote! {
+ #full_ident { #(#field_identifiers,)* } => {
+ #(#field_mutators)*
+ }
}
- };
-
- Some(match_arm)
+ } else {
+ quote! {
+ #full_ident(#(#field_identifiers,)*) => {
+ #(#field_mutators)*
+ }
+ }
+ }
})
.collect();
@@ -764,10 +773,23 @@ fn new_fuzzed_enum_visitor(
// using the same code for both code paths generates an error
// when mixing enum variants with and without fields because
// of the function call syntax
+ let is_struct = variant.style == crate::internals::ast::Style::Struct;
let initializer = if field_initializers.is_empty() {
quote! {
let mut value = #full_ident;
}
+ } else if is_struct {
+ let mut struct_fields = vec![];
+ for (field, ident) in variant.fields.iter().zip(field_identifiers.iter()) {
+ let member = &field.member;
+ struct_fields.push(quote! { #member: #ident });
+ }
+ quote! {
+ #(#field_initializers)*
+
+ _lain::log::trace!("Initializing {}", #full_ident_string);
+ let mut value = #full_ident { #(#struct_fields,)* };
+ }
} else {
quote! {
#(#field_initializers)*
diff --git a/lain_derive/src/serialize.rs b/lain_derive/src/serialize.rs
index 7ae2253..c1d21aa 100644
--- a/lain_derive/src/serialize.rs
+++ b/lain_derive/src/serialize.rs
@@ -318,9 +318,23 @@ fn binary_serialize_enum_visitor(
})
.collect();
- let match_arm = quote! {
- #full_ident(#(ref #field_identifiers,)*) => {
- #(#field_serializers)*
+ let is_struct = variant.style == crate::internals::ast::Style::Struct;
+ let match_arm = if is_struct {
+ let mut struct_fields = vec![];
+ for (field, ident) in variant.fields.iter().zip(field_identifiers.iter()) {
+ let member = &field.member;
+ struct_fields.push(quote! { #member: ref #ident });
+ }
+ quote! {
+ #full_ident { #(#struct_fields,)* } => {
+ #(#field_serializers)*
+ }
+ }
+ } else {
+ quote! {
+ #full_ident(#(ref #field_identifiers,)*) => {
+ #(#field_serializers)*
+ }
}
};
@@ -585,9 +599,23 @@ fn serialized_size_enum_visitor(
match visitor_type {
SerializedSizeVisitorType::SerializedSize
| SerializedSizeVisitorType::MinEnumVariantSize => {
- quote_spanned! { variant.original.span() =>
- #full_ident(#(ref #field_identifiers,)*) => {
- 0 #(+#field_sizes)*
+ let is_struct = variant.style == crate::internals::ast::Style::Struct;
+ if is_struct {
+ let mut struct_fields = vec![];
+ for (field, ident) in variant.fields.iter().zip(field_identifiers.iter()) {
+ let member = &field.member;
+ struct_fields.push(quote! { #member: ref #ident });
+ }
+ quote_spanned! { variant.original.span() =>
+ #full_ident { #(#struct_fields,)* } => {
+ 0 #(+#field_sizes)*
+ }
+ }
+ } else {
+ quote_spanned! { variant.original.span() =>
+ #full_ident(#(ref #field_identifiers,)*) => {
+ 0 #(+#field_sizes)*
+ }
}
}
}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..18ca692
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,27 @@
+{
+ "name": "lain",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "prettier": "^3.8.3"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
+ "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3e5346a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,5 @@
+{
+ "dependencies": {
+ "prettier": "^3.8.3"
+ }
+}
diff --git a/testsuite/Cargo.toml b/testsuite/Cargo.toml
index 5074fc2..0d134cc 100644
--- a/testsuite/Cargo.toml
+++ b/testsuite/Cargo.toml
@@ -11,7 +11,7 @@ lain = { path = "../lain" }
# this brings in a LOT of dependencies (like 110)... maybe avoid
[dev-dependencies.criterion]
-version = "0.2"
+version = "0.8.2"
# disabling default features brings packages down from 120 to 108 (at the time of writing)
# wtf man
default-features = false
diff --git a/testsuite/benches/benchmark_generating_fuzzed_struct.rs b/testsuite/benches/benchmark_generating_fuzzed_struct.rs
index 031b2dd..9fa6c08 100644
--- a/testsuite/benches/benchmark_generating_fuzzed_struct.rs
+++ b/testsuite/benches/benchmark_generating_fuzzed_struct.rs
@@ -1,9 +1,10 @@
-#![feature(specialization)]
+#![allow(incomplete_features)]
extern crate criterion;
extern crate lain;
use criterion::*;
+use std::hint::black_box;
use lain::prelude::*;
use lain::rand::SeedableRng;
@@ -49,54 +50,51 @@ fn bench_new_fuzzed_1000(c: &mut Criterion) {
let struct_size = std::mem::size_of::();
let function_name = format!("bench_new_fuzzed struct of size 0x{:X}", struct_size);
- c.bench(
- function_name.as_ref(),
- Benchmark::new("fuzz", move |b| {
- let mut mutator = Mutator::new(lain::rand::rngs::SmallRng::from_seed([0u8; 32]));
- b.iter(|| {
- let s = NestedStruct::new_fuzzed(&mut mutator, None);
- black_box(s);
- });
- })
- .throughput(Throughput::Bytes(struct_size as u32)),
- );
+ let mut group = c.benchmark_group(&function_name);
+ group.throughput(Throughput::Bytes(struct_size as u64));
+ group.bench_function("fuzz", |b| {
+ let mut mutator = Mutator::new(lain::rand::rngs::SmallRng::from_seed([0u8; 32]));
+ b.iter(|| {
+ let s = NestedStruct::new_fuzzed(&mut mutator, None);
+ black_box(s);
+ });
+ });
+ group.finish();
}
fn bench_in_place_mutation(c: &mut Criterion) {
let struct_size = std::mem::size_of::();
let function_name = format!("bench_in_place_mutation struct of size 0x{:X}", struct_size);
- c.bench(
- function_name.as_ref(),
- Benchmark::new("fuzz", move |b| {
- let mut mutator = Mutator::new(lain::rand::rngs::SmallRng::from_seed([0u8; 32]));
- let s = NestedStruct::new_fuzzed(&mut mutator, None);
- b.iter(|| {
- let mut s = s.clone();
- let state = mutator.get_corpus_state();
- s.mutate(&mut mutator, None);
- black_box(&s);
- mutator.set_corpus_state(state);
- });
- })
- .throughput(Throughput::Bytes(struct_size as u32)),
- );
+ let mut group = c.benchmark_group(&function_name);
+ group.throughput(Throughput::Bytes(struct_size as u64));
+ group.bench_function("fuzz", |b| {
+ let mut mutator = Mutator::new(lain::rand::rngs::SmallRng::from_seed([0u8; 32]));
+ let s = NestedStruct::new_fuzzed(&mut mutator, None);
+ b.iter(|| {
+ let mut s = s.clone();
+ let state = mutator.get_corpus_state();
+ s.mutate(&mut mutator, None);
+ black_box(&s);
+ mutator.set_corpus_state(state);
+ });
+ });
+ group.finish();
}
fn bench_default_1000(c: &mut Criterion) {
let struct_size = std::mem::size_of::();
let function_name = format!("bench_default_1000 struct of size 0x{:X}", struct_size);
- c.bench(
- function_name.as_ref(),
- Benchmark::new("fuzz", move |b| {
- b.iter(|| {
- let s = NestedStruct::default();
- black_box(s);
- });
- })
- .throughput(Throughput::Bytes(struct_size as u32)),
- );
+ let mut group = c.benchmark_group(&function_name);
+ group.throughput(Throughput::Bytes(struct_size as u64));
+ group.bench_function("fuzz", |b| {
+ b.iter(|| {
+ let s = NestedStruct::default();
+ black_box(s);
+ });
+ });
+ group.finish();
}
criterion_group!(
diff --git a/testsuite/benches/benchmark_serialization_throughput.rs b/testsuite/benches/benchmark_serialization_throughput.rs
index 95cd50b..5e7507d 100644
--- a/testsuite/benches/benchmark_serialization_throughput.rs
+++ b/testsuite/benches/benchmark_serialization_throughput.rs
@@ -1,11 +1,10 @@
-#![feature(specialization)]
+#![allow(incomplete_features)]
-#[macro_use]
extern crate criterion;
-#[macro_use]
extern crate lain;
use criterion::*;
+use std::hint::black_box;
use lain::byteorder::BigEndian;
use lain::prelude::*;
@@ -73,18 +72,17 @@ fn bench_serialize_1000(c: &mut Criterion) {
..Default::default()
};
- c.bench(
- function_name.as_ref(),
- Benchmark::new("serialize", move |b| {
- let mut buffer = Vec::with_capacity(struct_size);
- b.iter(|| {
- parent.binary_serialize::<_, BigEndian>(&mut buffer);
- black_box(&buffer);
- buffer.clear();
- });
- })
- .throughput(Throughput::Bytes(struct_size as u32)),
- );
+ let mut group = c.benchmark_group(&function_name);
+ group.throughput(Throughput::Bytes(struct_size as u64));
+ group.bench_function("serialize", |b| {
+ let mut buffer = Vec::with_capacity(struct_size);
+ b.iter(|| {
+ parent.binary_serialize::<_, BigEndian>(&mut buffer);
+ black_box(&buffer);
+ buffer.clear();
+ });
+ });
+ group.finish();
}
criterion_group!(benches, bench_serialize_1000);
diff --git a/testsuite/src/lib.rs b/testsuite/src/lib.rs
index ebe75fc..ebd12cb 100644
--- a/testsuite/src/lib.rs
+++ b/testsuite/src/lib.rs
@@ -1,4 +1,10 @@
#![feature(min_specialization)]
+#![allow(
+ clippy::erasing_op,
+ clippy::identity_op,
+ clippy::assign_op_pattern,
+ dead_code
+)]
extern crate lain;
@@ -164,12 +170,12 @@ mod test {
// no assert or anything here since the concern is whether or not
// the rng had bounds that cause a panic
- assert!(initialized_struct.bool_field == true || initialized_struct.bool_field == false);
+ let _ = initialized_struct.bool_field;
}
#[test]
fn test_ignored_fields() {
- #[derive(NewFuzzed, BinarySerialize, Clone)]
+ #[derive(NewFuzzed, BinarySerialize, Clone, Mutatable)]
struct IgnoredFieldsStruct {
#[lain(ignore)]
ignored: u8,
@@ -177,9 +183,34 @@ mod test {
let mut mutator = get_mutator();
- let initialized_struct = IgnoredFieldsStruct::new_fuzzed(&mut mutator, None);
+ let mut initialized_struct = IgnoredFieldsStruct::new_fuzzed(&mut mutator, None);
assert_eq!(initialized_struct.ignored, 0);
+
+ initialized_struct.mutate(&mut mutator, None);
+ assert_eq!(initialized_struct.ignored, 0);
+ }
+
+ #[test]
+ fn test_ignored_fields_enum() {
+ #[derive(NewFuzzed, BinarySerialize, Clone, Mutatable, PartialEq, Debug)]
+ enum IgnoredFieldsEnum {
+ Variant1(#[lain(ignore)] u8),
+ }
+
+ let mut mutator = get_mutator();
+
+ let mut initialized_enum = IgnoredFieldsEnum::new_fuzzed(&mut mutator, None);
+
+ match &initialized_enum {
+ IgnoredFieldsEnum::Variant1(ignored) => assert_eq!(*ignored, 0),
+ }
+
+ initialized_enum.mutate(&mut mutator, None);
+
+ match &initialized_enum {
+ IgnoredFieldsEnum::Variant1(ignored) => assert_eq!(*ignored, 0),
+ }
}
#[test]
@@ -440,23 +471,19 @@ mod test {
#[test]
fn mutating_string() {
- // TODO: Fix mutation methods
-
- // let mut my_string = String::from("Hello, world");
- // let mut mutator = get_mutator();
+ let mut my_string = String::from("Hello, world");
+ let mut mutator = get_mutator();
- // my_string.mutate(&mut mutator);
+ my_string.mutate(&mut mutator, None);
- // assert!(my_string != "Hello, world");
+ assert!(my_string != "Hello, world");
}
#[test]
fn string_serialized_size() {
- // TODO: FIx
-
- // let my_string = String::from("Hello, world");
+ let my_string = String::from("Hello, world");
- // assert!(my_string.serialized_size() == my_string.as_bytes().len());
+ assert!(my_string.serialized_size() == my_string.len());
}
#[test]
@@ -468,7 +495,7 @@ mod test {
#[test]
fn driver_can_reproduce_mutations() {
- use lain::rand::Rng;
+ use lain::rand::RngExt;
use std::sync::{Arc, RwLock};
#[derive(Debug, Default, NewFuzzed, Mutatable, Clone, PartialEq, BinarySerialize)]
@@ -592,6 +619,20 @@ mod test {
println!("{:?}", ascii_str);
}
+ #[test]
+ fn test_large_array_mutation_support() {
+ #[derive(NewFuzzed, Mutatable, BinarySerialize)]
+ struct StructWithHugeArray {
+ pub huge: [u8; 128],
+ }
+
+ let mut mutator = get_mutator();
+ let mut instance = StructWithHugeArray::new_fuzzed(&mut mutator, None);
+
+ assert_eq!(instance.huge.serialized_size(), 128);
+ instance.mutate(&mut mutator, None);
+ }
+
#[test]
fn test_max_size_constraint_seems_to_work() {
#[derive(NewFuzzed, BinarySerialize)]
@@ -977,6 +1018,67 @@ mod test {
}
}
+ #[test]
+ fn test_string_mutation_resizes_eventually() {
+ let mut mutator = get_mutator();
+ let mut s = String::from("Hello, world");
+ let original_len = s.len();
+ let mut grew = false;
+ let mut shrank = false;
+
+ // 1% chance per mutation, running 5000 iterations should guarantee hitting both.
+ for _ in 0..5000 {
+ s.mutate(&mut mutator, None);
+ if s.len() > original_len {
+ grew = true;
+ }
+ if s.len() < original_len {
+ shrank = true;
+ }
+ if grew && shrank {
+ break;
+ }
+ }
+
+ assert!(grew, "string never grew in size during aggressive mutation");
+ assert!(
+ shrank,
+ "string never shrank in size during aggressive mutation"
+ );
+ }
+
+ #[test]
+ fn test_float_behavior() {
+ let mut mutator = get_mutator();
+
+ let mut has_nan = false;
+ let mut has_inf = false;
+ let mut has_neg_inf = false;
+ let mut has_regular = false;
+
+ // 5000 iterations to confidently hit all branches of the new Smart Mode
+ for _ in 0..5000 {
+ let val = f32::new_fuzzed(&mut mutator, None);
+ if val.is_nan() {
+ has_nan = true;
+ } else if val == f32::INFINITY {
+ has_inf = true;
+ } else if val == f32::NEG_INFINITY {
+ has_neg_inf = true;
+ } else if val.is_normal() {
+ has_regular = true;
+ }
+ }
+
+ assert!(has_nan, "Fuzzer failed to generate f32::NAN");
+ assert!(has_inf, "Fuzzer failed to generate f32::INFINITY");
+ assert!(has_neg_inf, "Fuzzer failed to generate f32::NEG_INFINITY");
+ assert!(
+ has_regular,
+ "Fuzzer failed to generate standard normal floats"
+ );
+ }
+
fn compare_slices(expected: &[u8], actual: &[u8]) {
assert_eq!(actual.len(), expected.len());