mirror of
https://github.com/forkless/NotAlterra.git
synced 2026-08-18 17:22:32 +02:00
add full_metadata fuzz target, fix OOB crash in property extractors
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "notalterra-fuzz"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.4"
|
||||
|
||||
[dependencies.notalterra]
|
||||
path = ".."
|
||||
|
||||
[[bin]]
|
||||
name = "parse_gvas"
|
||||
path = "fuzz_targets/parse_gvas.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "full_metadata"
|
||||
path = "fuzz_targets/full_metadata.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
// Exercises extract_full_metadata — covers IntProperty, DoubleProperty,
|
||||
// additional StrProperty (GameMode, LevelName, BuildBranch) and
|
||||
// BoolProperty (bIsMultiplayerSave, bWasMultiplayerSave) code paths
|
||||
// not reached by the existing parse_gvas target.
|
||||
let tmp = std::env::temp_dir();
|
||||
let path = tmp.join("notalterra_fuzz_full_meta.sav");
|
||||
let _ = std::fs::write(&path, data);
|
||||
let _ = notalterra::gvas::extract_full_metadata(&path);
|
||||
let _ = std::fs::remove_file(&path);
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
#[fuzz]
|
||||
mod target {
|
||||
#[fuzz]
|
||||
fn parse_gvas(data: &[u8]) {
|
||||
let _ = notalterra::gvas::extract_metadata_from_bytes(data);
|
||||
}
|
||||
}
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
let _ = notalterra::gvas::extract_metadata_from_bytes(data);
|
||||
});
|
||||
|
||||
+4
-4
@@ -140,7 +140,7 @@ fn extract_str_property(data: &[u8], prop_name: &str) -> Result<String, String>
|
||||
attempts += 1;
|
||||
continue;
|
||||
}
|
||||
if data[found + target.len()] != 0 {
|
||||
if found + target.len() >= data.len() || data[found + target.len()] != 0 {
|
||||
offset = found + 1;
|
||||
attempts += 1;
|
||||
continue;
|
||||
@@ -187,7 +187,7 @@ fn extract_bool_property(data: &[u8], prop_name: &str) -> Option<bool> {
|
||||
if found < 4 { offset = found + 1; attempts += 1; continue; }
|
||||
let name_len_field = read_u32(data, found - 4);
|
||||
if name_len_field != Some(target.len() + 1) { offset = found + 1; attempts += 1; continue; }
|
||||
if data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
if found + target.len() >= data.len() || data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
let after_name = found + target.len() + 1;
|
||||
let (next_name, next_offset) = read_fname(data, after_name);
|
||||
if next_name.as_deref() != Some("BoolProperty") { offset = found + 1; attempts += 1; continue; }
|
||||
@@ -223,7 +223,7 @@ fn extract_double_property(data: &[u8], prop_name: &str) -> Option<f64> {
|
||||
if found < 4 { offset = found + 1; attempts += 1; continue; }
|
||||
let expected: usize = target.len() + 1;
|
||||
if read_u32(data, found - 4) != Some(expected) { offset = found + 1; attempts += 1; continue; }
|
||||
if data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
if found + target.len() >= data.len() || data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
let (next_name, next_offset) = read_fname(data, found + target.len() + 1);
|
||||
if next_name.as_deref() != Some("DoubleProperty") { offset = found + 1; attempts += 1; continue; }
|
||||
let val_offset = next_offset + 9;
|
||||
@@ -243,7 +243,7 @@ fn extract_int_property(data: &[u8], prop_name: &str) -> Option<u32> {
|
||||
let found = match found { Some(p) => offset + p, None => return None };
|
||||
if found < 4 { offset = found + 1; attempts += 1; continue; }
|
||||
if read_u32(data, found - 4) != Some(target.len() + 1) { offset = found + 1; attempts += 1; continue; }
|
||||
if data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
if found + target.len() >= data.len() || data[found + target.len()] != 0 { offset = found + 1; attempts += 1; continue; }
|
||||
let (next_name, next_offset) = read_fname(data, found + target.len() + 1);
|
||||
if next_name.as_deref() != Some("IntProperty") { offset = found + 1; attempts += 1; continue; }
|
||||
let val_offset = next_offset + 9;
|
||||
|
||||
Reference in New Issue
Block a user