| 
 | 1 | +use honggfuzz::fuzz;  | 
 | 2 | +use sp_npos_elections::generate_solution_type;  | 
 | 3 | +use sp_npos_elections::sp_arithmetic::Percent;  | 
 | 4 | +use sp_runtime::codec::{Encode, Error};  | 
 | 5 | + | 
 | 6 | +fn main() {  | 
 | 7 | +	generate_solution_type!(#[compact] pub struct InnerTestSolutionCompact::<u32, u32, Percent>(16));  | 
 | 8 | +	loop {  | 
 | 9 | +		fuzz!(|fuzzer_data: &[u8]| {  | 
 | 10 | +			let result_decoded: Result<InnerTestSolutionCompact, Error> =  | 
 | 11 | +				<InnerTestSolutionCompact as codec::Decode>::decode(&mut &fuzzer_data[..]);  | 
 | 12 | +			// Ignore errors as not every random sequence of bytes can be decoded as InnerTestSolutionCompact  | 
 | 13 | +			if let Ok(decoded) = result_decoded {  | 
 | 14 | +				// Decoding works, let's re-encode it and compare results.  | 
 | 15 | +				let reencoded: std::vec::Vec<u8> = decoded.encode();  | 
 | 16 | +				// The reencoded value may or may not be equal to the original fuzzer output. However, the  | 
 | 17 | +				// original decoder should be optimal (in the sense that there is no shorter encoding of  | 
 | 18 | +				// the same object). So let's see if the fuzzer can find something shorter:  | 
 | 19 | +				if fuzzer_data.len() < reencoded.len() {  | 
 | 20 | +					panic!("fuzzer_data.len() < reencoded.len()");  | 
 | 21 | +				}  | 
 | 22 | +				// The reencoded value should definitely be decodable (if unwrap() fails that is a valid  | 
 | 23 | +				// panic/finding for the fuzzer):  | 
 | 24 | +				let decoded2: InnerTestSolutionCompact =  | 
 | 25 | +					<InnerTestSolutionCompact as codec::Decode>::decode(  | 
 | 26 | +						&mut reencoded.as_slice(),  | 
 | 27 | +					).unwrap();  | 
 | 28 | +				// And it should be equal to the original decoded object (resulting from directly  | 
 | 29 | +				// decoding fuzzer_data):  | 
 | 30 | +				assert_eq!(decoded, decoded2);  | 
 | 31 | +			}  | 
 | 32 | +		});  | 
 | 33 | +	}  | 
 | 34 | +}  | 
0 commit comments