#![no_main] //! The Source-2 SchemaSystem reader walks reloc-slot candidates as `SchemaClassInfoData_t` structs, //! chasing `m_pFields`/`m_pBaseClasses` pointers. A crafted (or truncated) `.so` can point those //! anywhere; the reader must survive it with `Err`/empty, never a panic. Also exercises the field and //! base-class accessors the derivation reads. use source2rosetta::elf::CodeImage; use source2rosetta::schema; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let Ok(img) = CodeImage::from_bytes(data.to_vec()) else { return; }; // The enum bindings are a SECOND table read the same reloc-driven way: a name pointer, a // width/count word, and an enumerator array whose length that word supplies. A crafted count is the // sharp edge — it drives the per-enumerator read loop — so the reader must bound it rather than // trust it. let classes = schema::enumerate_schema(&img); // The enum walk takes the classes because a class FIELD descriptor is byte-compatible with an enum // binding — so a crafted image can aim the field-array spans it derives from them anywhere too. for e in schema::enumerate_enums(&img, &classes) { let _ = (e.name.len(), e.size, e.align); for (n, v) in &e.values { let _ = (n.len(), *v); } } for c in &classes { let _ = c.primary_base(); for f in &c.fields { let _ = (f.offset, f.name.len()); } for b in &c.bases { let _ = (b.offset, b.name.len()); } } });