In some cases ObjectHandler::peak_name will return String contains NUL character.
Using example code from README:
test/test1.rs
use std::{
fs::{DirBuilder, File},
io::{Seek, Write},
path::Path,
};
use rabex::config::ExtractionConfig;
use rabex::files::{BundleFile, SerializedFile};
#[test]
#[ignore = "Enable this to see output"]
fn test1() {
let mut reader = File::open(r"buli_super").unwrap();
let export_dir = Path::new("dump");
// parse the bundle file
let config = ExtractionConfig::new(None, "".to_string());
let mut bundle = BundleFile::from_reader(&mut reader, &config).unwrap();
// iterate over the files in the bundle
for directory in &bundle.m_DirectoryInfo {
if directory.path.ends_with(".resS") {
continue;
}
// generate export dir for cab
let export_cab_dir = export_dir.join(&directory.path);
// seek to the start of the file in the bundle
bundle
.m_BlockReader
.seek(std::io::SeekFrom::Start(directory.offset as u64))
.unwrap();
// try to parse the file as a SerializedFile
match SerializedFile::from_reader(&mut bundle.m_BlockReader, &config) {
Ok(serialized) => {
// iterate over objects
for object in &serialized.m_Objects {
// get a helper object to parse the object
let mut handler =
serialized.get_object_handler(object, &mut bundle.m_BlockReader);
// try to get the name
let name = match handler.peak_name() {
Ok(name) => format!("{}_{}", object.m_PathID, name),
Err(_) => format!("{}", object.m_PathID),
};
// ensure that the parent directory exists
let dst_path = export_cab_dir.join(name);
DirBuilder::new()
.recursive(true)
.create(dst_path.parent().unwrap())
.unwrap_or_else(|_| panic!("Failed to create {:?}", dst_path.parent()));
// parse the object as json
let json = handler.parse_as_json().unwrap();
// println!("{:?}", json);
File::create(format!("{}.json", dst_path.to_string_lossy()))
.unwrap()
.write_all(json.to_string().as_bytes())
.unwrap();
// parse the object as yaml
let yaml = handler.parse_as_yaml().unwrap().unwrap();
// println!("{:?}", yaml);
File::create(format!("{}.yaml", dst_path.to_string_lossy()))
.unwrap()
.write_all(serde_yaml::to_string(&yaml).unwrap().as_bytes())
.unwrap();
// parse the object as msgpack
let msgpack = handler.parse_as_msgpack().unwrap();
File::create(format!("{}.msgpack", dst_path.to_string_lossy()))
.unwrap()
.write_all(&msgpack)
.unwrap();
// serialize as actual class
// note: a small part of the object classes isn't implemented yet
if object.m_ClassID == rabex::objects::map::AssetBundle {
let ab = handler
.parse::<rabex::objects::classes::AssetBundle>()
.unwrap();
println!("{:?}", ab);
}
}
}
Err(e) => {
// TODO - try to filter out resource files
println!(
"Failed to parse {} as SerializedFile.",
&directory.path.to_string()
);
}
}
}
}
Specifically, in this code
// try to get the name
let name = match handler.peak_name() {
Ok(name) => format!("{}_{}", object.m_PathID, name),
Err(_) => format!("{}", object.m_PathID),
};
// ensure that the parent directory exists
let dst_path = export_cab_dir.join(name);
DirBuilder::new()
.recursive(true)
.create(dst_path.parent().unwrap())
.unwrap_or_else(|_| panic!("Failed to create {:?}", dst_path.parent()));
// parse the object as json
let json = handler.parse_as_json().unwrap();
// println!("{:?}", json);
File::create(format!("{}.json", dst_path.to_string_lossy()))
.unwrap()
.write_all(json.to_string().as_bytes())
.unwrap();
name could contain \0 thus dst_path would also contain \0 char which results in the following error on windows
thread 'test1' panicked at tests\test1.rs:65:26:
called `Result::unwrap()` on an `Err` value: Error { kind: InvalidInput, message: "strings passed to WinAPI cannot contain NULs" }
Related file
buli_super.zip
In some cases
ObjectHandler::peak_namewill returnStringcontains NUL character.Using example code from README:
test/test1.rs
Specifically, in this code
namecould contain\0thusdst_pathwould also contain\0char which results in the following error on windowsRelated file
buli_super.zip