Skip to content

Commit

Permalink
Merge branch 'main' into patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
C0D3-M4513R authored Aug 24, 2024
2 parents 9c1c8be + 428dc02 commit 3dc37cd
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 160 deletions.
14 changes: 13 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cafebabe"
version = "0.7.0"
version = "0.7.1"
authors = ["Kartikaya Gupta"]
edition = "2018"
license = "0BSD"
Expand All @@ -16,6 +16,18 @@ exclude = [".gitignore", ".github/**", "examples/**", "tests/**"]
[badges]
maintenance = { status = "passively-maintained" }

[features]
default = []
threadsafe = []

[dependencies]
bitflags = "1.0"
cesu8 = "1.1.0"

[dev-dependencies]
rayon = "1.10.0"

[[example]]
name = "threadsafe"
path = "examples/threadsafe.rs"
required-features = ["threadsafe"]
31 changes: 31 additions & 0 deletions examples/threadsafe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use rayon::prelude::*;
use std::env;
use std::fs::File;
use std::io::Read;

fn main() {
let mut class_data = Vec::new();
for arg in env::args().skip(1) {
let mut file = File::open(&arg).unwrap();
let mut bytes = Vec::new();
file.read_to_end(&mut bytes).unwrap();
class_data.push(bytes);
}

let results: Vec<Result<_, _>> = class_data
.par_iter()
.map(|data| {
cafebabe::parse_class_with_options(
&data,
cafebabe::ParseOptions::default().parse_bytecode(true),
)
})
.collect();

for result in results {
match result {
Ok(class) => println!("Successfully parsed {:?}\n{:#?}", class.this_class, class),
Err(e) => println!("Error: {}", e),
}
}
}
43 changes: 21 additions & 22 deletions src/attributes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::ops::Deref;
use std::rc::Rc;

use crate::bytecode::ByteCode;
use crate::constant_pool::{
Expand All @@ -14,7 +13,7 @@ use crate::constant_pool::{
};
use crate::descriptor::FieldType;
use crate::names::{is_return_descriptor, is_unqualified_name};
use crate::{read_u1, read_u2, read_u4, AccessFlags, ParseError, ParseOptions};
use crate::{read_u1, read_u2, read_u4, AccessFlags, CafeRc, ParseError, ParseOptions};

#[derive(Debug)]
pub struct ExceptionTableEntry<'a> {
Expand Down Expand Up @@ -368,7 +367,7 @@ fn ensure_length(length: usize, expected: usize) -> Result<(), ParseError> {
fn read_code_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
opts: &ParseOptions,
) -> Result<CodeData<'a>, ParseError> {
let max_stack = read_u2(bytes, ix)?;
Expand Down Expand Up @@ -417,7 +416,7 @@ fn read_code_data<'a>(
fn read_stackmaptable_verification<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<VerificationType<'a>, ParseError> {
let verification_type = match read_u1(bytes, ix)? {
0 => VerificationType::Top,
Expand All @@ -444,7 +443,7 @@ fn read_stackmaptable_verification<'a>(
fn read_stackmaptable_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<StackMapEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut stackmapframes = Vec::with_capacity(count.into());
Expand Down Expand Up @@ -537,7 +536,7 @@ fn read_stackmaptable_data<'a>(
fn read_exceptions_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<Cow<'a, str>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut exceptions = Vec::with_capacity(count.into());
Expand All @@ -552,7 +551,7 @@ fn read_exceptions_data<'a>(
fn read_innerclasses_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<InnerClassEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut innerclasses = Vec::with_capacity(count.into());
Expand Down Expand Up @@ -591,7 +590,7 @@ fn read_linenumber_data(bytes: &[u8], ix: &mut usize) -> Result<Vec<LineNumberEn
fn read_localvariable_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<LocalVariableEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut localvariables = Vec::with_capacity(count.into());
Expand Down Expand Up @@ -620,7 +619,7 @@ fn read_localvariable_data<'a>(
fn read_localvariabletype_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<LocalVariableTypeEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut localvariabletypes = Vec::with_capacity(count.into());
Expand Down Expand Up @@ -648,7 +647,7 @@ fn read_localvariabletype_data<'a>(
fn read_annotation_element_value<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<AnnotationElementValue<'a>, ParseError> {
let value = match read_u1(bytes, ix)? as char {
'B' => AnnotationElementValue::ByteConstant(read_cp_integer(bytes, ix, pool)?),
Expand Down Expand Up @@ -697,7 +696,7 @@ fn read_annotation_element_value<'a>(
fn read_annotation<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Annotation<'a>, ParseError> {
let type_descriptor = read_cp_utf8(bytes, ix, pool)
.and_then(|descriptor| FieldType::parse(&descriptor))
Expand All @@ -719,7 +718,7 @@ fn read_annotation<'a>(
fn read_annotation_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<Annotation<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut annotations = Vec::with_capacity(count.into());
Expand All @@ -733,7 +732,7 @@ fn read_annotation_data<'a>(
fn read_parameter_annotation_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<ParameterAnnotation<'a>>, ParseError> {
let count = read_u1(bytes, ix)?;
let mut parameters = Vec::with_capacity(count.into());
Expand All @@ -754,7 +753,7 @@ fn read_parameter_annotation_data<'a>(
fn read_type_annotation_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<TypeAnnotation<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut annotations = Vec::with_capacity(count.into());
Expand Down Expand Up @@ -840,7 +839,7 @@ fn read_type_annotation_data<'a>(
fn read_bootstrapmethods_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<BootstrapMethodEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut bootstrapmethods = Vec::with_capacity(count.into());
Expand All @@ -862,7 +861,7 @@ fn read_bootstrapmethods_data<'a>(
fn read_methodparameters_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<MethodParameterEntry<'a>>, ParseError> {
let count = read_u1(bytes, ix)?;
let mut methodparameters = Vec::with_capacity(count.into());
Expand All @@ -882,7 +881,7 @@ fn read_methodparameters_data<'a>(
fn read_module_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<ModuleData<'a>, ParseError> {
let name = read_cp_moduleinfo(bytes, ix, pool).map_err(|e| err!(e, "name"))?;
let access_flags = ModuleAccessFlags::from_bits(read_u2(bytes, ix)?)
Expand Down Expand Up @@ -983,7 +982,7 @@ fn read_module_data<'a>(
fn read_modulepackages_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<Cow<'a, str>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut packages = Vec::with_capacity(count.into());
Expand All @@ -997,7 +996,7 @@ fn read_modulepackages_data<'a>(
fn read_nestmembers_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<Cow<'a, str>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut members = Vec::with_capacity(count.into());
Expand All @@ -1010,7 +1009,7 @@ fn read_nestmembers_data<'a>(
fn read_permitted_subclasses_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<Cow<'a, str>>, ParseError> {
let count = read_u2(bytes, ix)?;
let mut permitted_subclasses = Vec::with_capacity(count.into());
Expand All @@ -1025,7 +1024,7 @@ fn read_permitted_subclasses_data<'a>(
fn read_record_data<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
opts: &ParseOptions,
) -> Result<Vec<RecordComponentEntry<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
Expand All @@ -1052,7 +1051,7 @@ fn read_record_data<'a>(
pub(crate) fn read_attributes<'a>(
bytes: &'a [u8],
ix: &mut usize,
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
opts: &ParseOptions,
) -> Result<Vec<AttributeInfo<'a>>, ParseError> {
let count = read_u2(bytes, ix)?;
Expand Down
7 changes: 3 additions & 4 deletions src/bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::convert::TryFrom;
use std::rc::Rc;

use crate::constant_pool::{
get_cp_loadable, read_cp_classinfo, read_cp_invokedynamic, read_cp_memberref,
Expand All @@ -9,7 +8,7 @@ use crate::constant_pool::{
ConstantPoolEntry, ConstantPoolEntryTypes, InvokeDynamic, Loadable, MemberRef,
};
use crate::descriptor::ReferenceType;
use crate::{read_u1, read_u2, read_u4, ParseError};
use crate::{read_u1, read_u2, read_u4, CafeRc, ParseError};

pub type JumpOffset = i32;

Expand Down Expand Up @@ -217,7 +216,7 @@ pub struct ByteCode<'a> {
impl<'a> ByteCode<'a> {
pub(crate) fn from(
code: &'a [u8],
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Self, ParseError> {
let bytecode = Self {
opcodes: read_opcodes(code, pool)?,
Expand Down Expand Up @@ -312,7 +311,7 @@ impl<'a> ByteCode<'a> {

fn read_opcodes<'a>(
code: &'a [u8],
pool: &[Rc<ConstantPoolEntry<'a>>],
pool: &[CafeRc<ConstantPoolEntry<'a>>],
) -> Result<Vec<(usize, Opcode<'a>)>, ParseError> {
let mut opcodes = Vec::new();
let mut ix = 0;
Expand Down
Loading

0 comments on commit 3dc37cd

Please sign in to comment.