extern crate nom;
extern crate classfile_parser;
use classfile_parser::class_parser;
use classfile_parser::constant_info::ConstantInfo;
#[test]
fn test_valid_class() {
let valid_class = include_bytes!("../java-assets/compiled-classes/BasicClass.class");
let res = class_parser(valid_class);
match res {
Result::Ok((_, c)) => {
println!("Valid class file, version {},{} const_pool({}), this=const[{}], super=const[{}], interfaces({}), fields({}), methods({}), attributes({}), access({:?})", c.major_version, c.minor_version, c.const_pool_size, c.this_class, c.super_class, c.interfaces_count, c.fields_count, c.methods_count, c.attributes_count, c.access_flags);
let mut code_const_index = 0;
println!("Constant pool:");
for (const_index, const_item) in c.const_pool.iter().enumerate() {
println!("\t[{}] = {:?}", (const_index + 1), const_item);
match *const_item {
ConstantInfo::Utf8(ref c) => {
if c.utf8_string == "Code" {
code_const_index = (const_index + 1) as u16;
}
},
_ => {},
}
}
println!("Code index = {}", code_const_index);
println!("Interfaces:");
let mut interface_index = 0;
for i in &c.interfaces {
println!("\t[{}] = const[{}] = {:?}", interface_index, i, c.const_pool[(i-1) as usize]);
interface_index += 1;
}
println!("Fields:");
let mut field_index = 0;
for f in &c.fields {
println!("\t[{}] Name(const[{}] = {:?}) - access({:?})", field_index, f.name_index, c.const_pool[(f.name_index - 1) as usize], f.access_flags);
field_index += 1;
}
println!("Methods:");
let mut method_index = 0;
for m in &c.methods {
println!("\t[{}] Name(const[{}] = {:?}) - access({:?})", method_index, m.name_index, c.const_pool[(m.name_index - 1) as usize], m.access_flags);
method_index += 1;
for a in &m.attributes {
if a.attribute_name_index == code_const_index {
println!("\t\tCode attr found, len = {}", a.attribute_length);
let code_result = classfile_parser::attribute_info::code_attribute_parser(&a.info);
match code_result {
Result::Ok((_, code)) => {
println!("\t\t\tCode! code_length = {}", code.code_length);
},
_ => panic!("Not a valid code attr?"),
}
}
else {
println!("\t\tAttribute: {:?}", a);
}
}
}
},
_ => panic!("Not a class file"),
};
}
#[test]
fn test_utf_string_constants() {
let valid_class = include_bytes!("../java-assets/compiled-classes/UnicodeStrings.class");
let res = class_parser(valid_class);
match res {
Result::Ok((_, c)) => {
let mut found_utf_maths_string = false;
let mut found_utf_runes_string = false;
let mut found_utf_braille_string = false;
for (const_index, const_item) in c.const_pool.iter().enumerate() {
println!("\t[{}] = {:?}", (const_index + 1), const_item);
match *const_item {
ConstantInfo::Utf8(ref c) => {
if c.utf8_string == "2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm" {
found_utf_maths_string = true;
}
if c.utf8_string == "ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ" {
found_utf_runes_string = true;
}
if c.utf8_string == "⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌" {
found_utf_braille_string = true;
}
},
_ => {},
}
}
assert!(found_utf_maths_string & found_utf_runes_string & found_utf_braille_string, "Failed to find unicode strings");
},
_ => panic!("Not a class file"),
}
}
#[test]
fn test_malformed_class() {
let malformed_class = include_bytes!("../java-assets/compiled-classes/malformed.class");
let res = class_parser(malformed_class);
match res {
Result::Ok((_, _)) => panic!("The file is not valid and shouldn't be parsed"),
_ => {},
};
}