jbcrs_basic/parser/
mod.rs

1mod decode;
2mod class;
3mod method;
4mod code;
5mod annotation;
6
7use result::*;
8use super::constpool::*;
9use super::tree::*;
10use self::class::*;
11use self::method::*;
12use self::code::*;
13use self::annotation::*;
14use self::decode::Decoder;
15
16/// Parses the class file, which is represented as a byte array.
17/// The constant pool and the class is returned, if no error occurred.
18pub fn parse(input: &[u8]) -> Result<(Pool, Class)> {
19    // create a new decoder from the byte array
20    let mut cursor = 0;
21    let mut decoder = Decoder::new(input, &mut cursor);
22
23    // check if input is a class file
24    if decoder.read_bytes(4)? != MAGIC {
25        return Err(Error::NotAClass);
26    }
27
28    let minor_version = decoder.read_u16()?;
29    let major_version = decoder.read_u16()?;
30
31    let constant_pool = read_constant_pool(&mut decoder)?;
32
33    let access_flags = AccessFlags::from_bits_truncate(decoder.read_u16()?);
34
35    let name = decoder.read_u16()?;
36    let super_name = decoder.read_u16()?;
37
38    // Read interfaces
39    let interface_count = decoder.read_u16()?;
40    let mut interfaces = Vec::with_capacity(interface_count as usize);
41    for _ in 0..interface_count {
42        interfaces.push(decoder.read_u16()?);
43    }
44
45    let fields = parse_fields(&mut decoder, &constant_pool)?;
46    let methods = parse_methods(&mut decoder, &constant_pool)?;
47    let attributes = parse_attributes(&mut decoder, &constant_pool)?;
48
49    let class = Class {
50        minor_version,
51        major_version,
52
53        access_flags,
54        name,
55        super_name,
56
57        interfaces,
58
59        fields,
60        methods,
61        attributes,
62    };
63
64    Ok((constant_pool, class))
65}
66
67/// Reads the entire constant pool
68fn read_constant_pool(decoder: &mut Decoder) -> Result<Pool> {
69    let size = decoder.read_u16()?;
70    let mut pool = Pool::new();
71
72    let mut index = 1;
73    while index < size {
74        let tag = decoder.read_u8()?;
75
76        // match a tag and read the additional information
77        let item = match tag {
78            1 => {
79                let length = decoder.read_u16()?;
80                Item::UTF8(decoder.read_str(length as usize)?)
81            }
82            3 => Item::Integer(decoder.read_i32()?),
83            4 => Item::Float(decoder.read_f32()?),
84            5 => Item::Long(decoder.read_i64()?),
85            6 => Item::Double(decoder.read_f64()?),
86            7 => Item::Class(decoder.read_u16()?),
87            8 => Item::String(decoder.read_u16()?),
88            9 => {
89                let class = decoder.read_u16()?;
90                let name_and_type = decoder.read_u16()?;
91
92                Item::FieldRef {
93                    class,
94                    name_and_type,
95                }
96            }
97            10 => {
98                let class = decoder.read_u16()?;
99                let name_and_type = decoder.read_u16()?;
100
101                Item::MethodRef {
102                    class,
103                    name_and_type,
104                }
105            }
106            11 => {
107                let class = decoder.read_u16()?;
108                let name_and_type = decoder.read_u16()?;
109
110                Item::InterfaceMethodRef {
111                    class,
112                    name_and_type,
113                }
114            }
115            12 => {
116                let name = decoder.read_u16()?;
117                let desc = decoder.read_u16()?;
118
119                Item::NameAndType { name, desc }
120            }
121            15 => {
122                let kind = match decoder.read_u8()? {
123                    1 => ReferenceKind::GetField,
124                    2 => ReferenceKind::GetStatic,
125                    3 => ReferenceKind::PutField,
126                    4 => ReferenceKind::PutStatic,
127                    5 => ReferenceKind::InvokeVirtual,
128                    6 => ReferenceKind::InvokeStatic,
129                    7 => ReferenceKind::InvokeSpecial,
130                    8 => ReferenceKind::NewInvokeSpecial,
131                    9 => ReferenceKind::InvokeInterface,
132
133                    _ => return Err(Error::InvalidCPItem(index)),
134                };
135                let index = decoder.read_u16()?;
136
137                Item::MethodHandle { kind, index }
138            }
139            16 => Item::MethodType(decoder.read_u16()?),
140            18 => {
141                let bootstrap_method = decoder.read_u16()?;
142                let name_and_type = decoder.read_u16()?;
143
144                Item::InvokeDynamic {
145                    bootstrap_method,
146                    name_and_type,
147                }
148            }
149            19 => Item::Module(decoder.read_u16()?),
150            20 => Item::Package(decoder.read_u16()?),
151
152            _ => return Err(Error::InvalidCPItem(index)),
153        };
154
155        pool.push_duplicate(item)?;
156        index += 1;
157    }
158
159    Ok(pool)
160}
161
162/// Parses all fields and their attributes
163fn parse_fields(decoder: &mut Decoder, constant_pool: &Pool) -> Result<Vec<Field>> {
164    let count = decoder.read_u16()?;
165    let mut fields = Vec::with_capacity(count as usize);
166    for _ in 0..count {
167        let access_flags = AccessFlags::from_bits_truncate(decoder.read_u16()?);
168        let name = decoder.read_u16()?;
169        let desc = decoder.read_u16()?;
170        let attributes = parse_attributes(decoder, constant_pool)?;
171
172        fields.push(Field {
173            access_flags,
174            name,
175            desc,
176            attributes,
177        })
178    }
179
180    Ok(fields)
181}
182
183/// Parses all methods and their attributes
184fn parse_methods(decoder: &mut Decoder, constant_pool: &Pool) -> Result<Vec<Method>> {
185    let count = decoder.read_u16()?;
186    let mut fields = Vec::with_capacity(count as usize);
187    for _ in 0..count {
188        let access_flags = AccessFlags::from_bits_truncate(decoder.read_u16()?);
189        let name = decoder.read_u16()?;
190        let desc = decoder.read_u16()?;
191        let attributes = parse_attributes(decoder, constant_pool)?;
192
193        fields.push(Method {
194            access_flags,
195            name,
196            desc,
197            attributes,
198        })
199    }
200
201    Ok(fields)
202}
203
204/// Parses all attributes
205fn parse_attributes(decoder: &mut Decoder, constant_pool: &Pool) -> Result<Vec<Attribute>> {
206    let count = decoder.read_u16()?;
207    let mut attributes = Vec::with_capacity(count as usize);
208    for _ in 0..count {
209        let name_index = decoder.read_u16()?;
210        let name = constant_pool.get_utf8(name_index)?;
211        let length = decoder.read_u32()?;
212
213        // limit attribute length
214        let mut attr_decoder = decoder.limit(length as usize)?;
215
216        let attribute = match name.as_ref() {
217            "AnnotationDefault" => {
218                Attribute::AnnotationDefault(parse_element_value(&mut attr_decoder)?)
219            }
220            "BootstrapMethods" => parse_bootstrap_methods(&mut attr_decoder)?,
221            "Code" => parse_code(&mut attr_decoder, constant_pool)?,
222            "ConstantValue" => {
223                let index = attr_decoder.read_u16()?;
224                Attribute::ConstantValue(index)
225            }
226            "Deprecated" => Attribute::Deprecated,
227            "EnclosingMethods" => parse_enclosing_method(&mut attr_decoder)?,
228            "Exceptions" => parse_exceptions(&mut attr_decoder)?,
229            "InnerClasses" => parse_inner_classes(&mut attr_decoder)?,
230            "LineNumberTable" => parse_line_number_table(&mut attr_decoder)?,
231            "LocalVariableTable" => parse_local_variable_table(&mut attr_decoder)?,
232            "LocalVariableTypeTable" => parse_local_variable_type_table(&mut attr_decoder)?,
233            "MethodParameters" => parse_method_parameters(&mut attr_decoder)?,
234            "Module" => parse_module(&mut attr_decoder)?,
235            "ModuleMainClass" => {
236                let index = attr_decoder.read_u16()?;
237                Attribute::ModuleMainClass(index)
238            }
239            "ModulePackages" => parse_module_packages(&mut attr_decoder)?,
240            "RuntimeVisibleAnnotations" => {
241                let annotations = parse_annotations(&mut attr_decoder)?;
242                Attribute::RuntimeVisibleAnnotations(annotations)
243            }
244            "RuntimeInvisibleAnnotations" => {
245                let annotations = parse_annotations(&mut attr_decoder)?;
246                Attribute::RuntimeInvisibleAnnotations(annotations)
247            }
248            "RuntimeVisibleParameterAnnotations" => {
249                let annotations = parse_parameter_annotations(&mut attr_decoder)?;
250                Attribute::RuntimeVisibleParameterAnnotations(annotations)
251            }
252            "RuntimeInvisibleParameterAnnotations" => {
253                let annotations = parse_parameter_annotations(&mut attr_decoder)?;
254                Attribute::RuntimeInvisibleParameterAnnotations(annotations)
255            }
256            "RuntimeVisibleTypeAnnotations" => {
257                let annotations = parse_type_annotations(&mut attr_decoder)?;
258                Attribute::RuntimeVisibleTypeAnnotations(annotations)
259            }
260            "RuntimeInvisibleTypeAnnotations" => {
261                let annotations = parse_type_annotations(&mut attr_decoder)?;
262                Attribute::RuntimeInvisibleTypeAnnotations(annotations)
263            }
264            "SourceFile" => {
265                let index = attr_decoder.read_u16()?;
266                Attribute::SourceFile(index)
267            }
268            "Signature" => {
269                let index = attr_decoder.read_u16()?;
270                Attribute::Signature(index)
271            }
272            "StackMapTable" => parse_stack_map_table(&mut attr_decoder)?,
273            "Synthetic" => Attribute::Synthetic,
274            "SourceDebugExtension" => {
275                Attribute::SourceDebugExtension(attr_decoder.read_str(length as usize)?)
276            }
277
278            _ => {
279                let bytes = attr_decoder.read_bytes(length as usize)?;
280                Attribute::Unknown(name_index, bytes.to_vec())
281            }
282        };
283        attributes.push(attribute);
284
285        // go on
286        attr_decoder.remove_limit()?;
287    }
288
289    Ok(attributes)
290}