use std::{error::Error, fs::File, io::Cursor};
use jvmti::bytecode::{ClassReader, ClassWriter};
fn main() -> Result<(), Box<dyn Error>> {
let path = "XXX.class";
let class_file = ClassReader::read_class(&mut File::open(path).unwrap()).unwrap();
let mut data = Vec::new();
let mut w: ClassWriter = ClassWriter::new(&mut data);
w.write_class(&class_file).unwrap();
let mut reader = Cursor::new(data);
ClassReader::read_class(&mut reader).unwrap();
Ok(())
}
called `Result::unwrap()` on an `Err` value: Error { kind: UnexpectedEof, message: "failed to fill whole buffer" }
stack backtrace:
0: rust_begin_unwind
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
1: core::panicking::panic_fmt
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
2: core::result::unwrap_failed
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/result.rs:1653:5
3: core::result::Result<T,E>::unwrap
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/result.rs:1077:23
4: yms_launcher1::main
at ./examples/yms-launcher1.rs:15:5
5: core::ops::function::FnOnce::call_once
at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
MethodParameters read codes
"MethodParameters" => Some(Attribute::MethodParameters({
let n = reader.get_u8();
(0..n).map(|_| MethodParameter {
name_index: ConstantPoolIndex::new(reader.get_u16() as usize),
access_flags: AccessFlags::of(reader.get_u16())
}).collect()
})),
MethodParameters write codes:
&Attribute::MethodParameters(ref table) => self
.write_u16(cp.get_utf8_index("MethodParameters") as u16)
.and(self.write_u32(1 + table.len() as u32 * 4))
.and(table.iter().fold(Ok(0), |_, p| {
self.write_u16(p.name_index.idx as u16)
.and(self.write_u16(p.access_flags.flags as u16))
})),
I modified it like this and still got an error
self.write_u8(table.len() as u8)
Remove all MethodParameters, code runs just fine.
use std::{error::Error, fs::File, io::Cursor};
use jvmti::bytecode::{Attribute, ClassReader, ClassWriter};
fn main() -> Result<(), Box<dyn Error>> {
let path = "XXX.class";
let mut class_file = ClassReader::read_class(&mut File::open(path).unwrap()).unwrap();
//remove all MethodParameters
for method in &mut class_file.methods {
method.attributes.retain(|a| match a {
Attribute::MethodParameters(_) => false,
_ => true,
});
}
let mut data = Vec::new();
let mut w: ClassWriter = ClassWriter::new(&mut data);
w.write_class(&class_file).unwrap();
let mut reader = Cursor::new(data);
ClassReader::read_class(&mut reader).unwrap();
Ok(())
}
MethodParameters read codes
"MethodParameters" => Some(Attribute::MethodParameters({
let n = reader.get_u8();
(0..n).map(|_| MethodParameter {
name_index: ConstantPoolIndex::new(reader.get_u16() as usize),
access_flags: AccessFlags::of(reader.get_u16())
}).collect()
})),
MethodParameters write codes:
&Attribute::MethodParameters(ref table) => self
.write_u16(cp.get_utf8_index("MethodParameters") as u16)
.and(self.write_u32(1 + table.len() as u32 * 4))
.and(table.iter().fold(Ok(0), |_, p| {
self.write_u16(p.name_index.idx as u16)
.and(self.write_u16(p.access_flags.flags as u16))
})),
I modified it like this and still got an error
self.write_u8(table.len() as u8)
Remove all MethodParameters, code runs just fine.