Added rust solver to the repository
This commit is contained in:
4
solver-rs/lib/board/fuzz/.gitignore
vendored
Normal file
4
solver-rs/lib/board/fuzz/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
target
|
||||
corpus
|
||||
artifacts
|
||||
216
solver-rs/lib/board/fuzz/Cargo.lock
generated
Normal file
216
solver-rs/lib/board/fuzz/Cargo.lock
generated
Normal file
@@ -0,0 +1,216 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed"
|
||||
|
||||
[[package]]
|
||||
name = "board"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enum-iterator",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "board-fuzz"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"board",
|
||||
"enum-iterator",
|
||||
"libfuzzer-sys",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c79a6321a1197d7730510c7e3f6cb80432dfefecb32426de8cea0aa19b4bb8d7"
|
||||
dependencies = [
|
||||
"enum-iterator-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator-derive"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e94aa31f7c0dc764f57896dc615ddd76fc13b0d5dca7eb6cc5e018a5a09ec06"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d718794b8e23533b9069bd2c4597d69e41cc7ab1c02700a502971aca0cdcf24"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
26
solver-rs/lib/board/fuzz/Cargo.toml
Normal file
26
solver-rs/lib/board/fuzz/Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
[package]
|
||||
name = "board-fuzz"
|
||||
version = "0.0.0"
|
||||
authors = ["Automatically generated"]
|
||||
publish = false
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.3"
|
||||
rand = "*"
|
||||
enum-iterator = "*"
|
||||
|
||||
[dependencies.board]
|
||||
path = ".."
|
||||
|
||||
# Prevent this from interfering with workspaces
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_target_1"
|
||||
path = "fuzz_targets/fuzz_target_1.rs"
|
||||
127
solver-rs/lib/board/fuzz/fuzz_targets/fuzz_target_1.rs
Normal file
127
solver-rs/lib/board/fuzz/fuzz_targets/fuzz_target_1.rs
Normal file
@@ -0,0 +1,127 @@
|
||||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
use board::{Board, CardType};
|
||||
use enum_iterator::IntoEnumIterator;
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
struct RandomBytes<'a> {
|
||||
data: &'a [u8],
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> rand::RngCore for RandomBytes<'a> {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
if let Option::Some(x) = self.data.get(self.index..self.index + 4) {
|
||||
self.index += 4;
|
||||
return (u32::from(x[3]) << 24)
|
||||
| (u32::from(x[2]) << 16)
|
||||
| (u32::from(x[1]) << 8)
|
||||
| u32::from(x[0]);
|
||||
} else {
|
||||
self.index = self.data.len();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
return u64::from(self.next_u32()) << 32 | u64::from(self.next_u32());
|
||||
}
|
||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
||||
if (self.index >= self.data.len()) || (dest.len() > self.data.len() - self.index) {
|
||||
for cell in dest.iter_mut() {
|
||||
*cell = 0;
|
||||
}
|
||||
}
|
||||
if dest.len() < self.data.len() - self.index {
|
||||
dest.clone_from_slice(&self.data[self.index..self.index + dest.len()]);
|
||||
self.index += dest.len()
|
||||
}
|
||||
}
|
||||
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
|
||||
self.fill_bytes(dest);
|
||||
return Result::Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
fn correct_board_permutation(data: &[u8]) -> Board {
|
||||
if let Option::Some(remove_info) = data.get(0..2) {
|
||||
let remove_info: u16 = u16::from(remove_info[1]) << 8 | u16::from(remove_info[0]);
|
||||
let mut result = Board::default();
|
||||
let mut whole_vec = Vec::<CardType>::new();
|
||||
if remove_info & 1 == 1 {
|
||||
result.hua_set = true;
|
||||
} else {
|
||||
whole_vec.push(CardType::Hua);
|
||||
result.hua_set = false;
|
||||
}
|
||||
for (index, card) in (1_u8..).zip(board::SpecialCardType::into_enum_iter()) {
|
||||
if remove_info & (1 << index) == 0 {
|
||||
result.bunker[usize::from(index - 1)] =
|
||||
board::BunkerSlot::Blocked(Option::Some(card.clone()));
|
||||
} else {
|
||||
whole_vec.push(CardType::Special(card.clone()));
|
||||
whole_vec.push(CardType::Special(card.clone()));
|
||||
whole_vec.push(CardType::Special(card.clone()));
|
||||
whole_vec.push(CardType::Special(card.clone()));
|
||||
result.bunker[usize::from(index - 1)] = board::BunkerSlot::Empty;
|
||||
}
|
||||
}
|
||||
for (index, suit) in (4_u8..)
|
||||
.step_by(4)
|
||||
.zip(board::NumberCardColor::into_enum_iter())
|
||||
{
|
||||
let value = (((remove_info >> index) & 0b1111) % 10) as u8;
|
||||
let slot_index = usize::from((index - 4) / 4);
|
||||
if value == 0 {
|
||||
result.goal[slot_index] = Option::None;
|
||||
} else {
|
||||
result.goal[slot_index] = Option::Some(board::NumberCard {
|
||||
value,
|
||||
suit: suit.clone(),
|
||||
});
|
||||
}
|
||||
for value in (value + 1)..10 {
|
||||
whole_vec.push(board::CardType::Number(board::NumberCard {
|
||||
value,
|
||||
suit: suit.clone(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
whole_vec.shuffle(&mut RandomBytes { data, index: 2 });
|
||||
for ((index_start, index_end), slot) in (0..)
|
||||
.step_by(8)
|
||||
.zip((8..).step_by(8))
|
||||
.zip(result.field.iter_mut())
|
||||
{
|
||||
if let Option::Some(tasty_slice) = whole_vec.get(index_start..index_end) {
|
||||
slot.extend_from_slice(tasty_slice);
|
||||
} else if let Option::Some(tasty_slice) = whole_vec.get(index_start..) {
|
||||
slot.extend_from_slice(tasty_slice);
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return Board::default();
|
||||
}
|
||||
}
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
if data.len() == 0 {
|
||||
return;
|
||||
}
|
||||
let x = correct_board_permutation(&data[1..]);
|
||||
assert_eq!(x.check(), Result::Ok(()));
|
||||
if let Option::Some(action) = board::possibilities::all_actions(&x).choose(&mut RandomBytes {
|
||||
data: &data[0..1],
|
||||
index: 0,
|
||||
}) {
|
||||
let mut action_board = x.clone();
|
||||
action.apply(&mut action_board);
|
||||
assert_ne!(action_board, x);
|
||||
action.undo(&mut action_board);
|
||||
assert_eq!(action_board, x);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user