1
2#[macro_use]
3extern crate log;
4
5mod model;
6mod result;
7mod decode;
8
9use std::char;
10use std::io::Read;
11use std::fs::File;
12
13pub use ::result::*;
14pub use ::model::*;
15pub use ::decode::*;
16
17pub struct ClassReader<'a> {
18 reader: Box<Read + 'a>,
19 position: usize
20}
21
22impl<'a> ClassReader<'a> {
23
24 pub fn new_from_path(path: &str) -> ParseResult<Class> {
25 let mut file = match File::open(path) {
26 Result::Ok(f) => f,
27 Result::Err(e) => { return Result::Err(ParseError::Io(e)); }
28 };
29 ClassReader::new_from_reader(&mut file)
30 }
31
32 pub fn new_from_reader<T: Read + 'a>(reader: &mut T) -> ParseResult<Class> {
33 let mut cr = ClassReader { reader: Box::new(reader), position: 0 };
34
35 let magic = try!(cr.read_u32());
36 let minor_version = try!(cr.read_u16());
37 let major_version = try!(cr.read_u16());
38 let constant_pool = try!(cr.read_constant_pool());
39 let access_flags = try!(cr.read_u16());
40 let this_class = try!(cr.read_u16());
41 let super_class = try!(cr.read_u16());
42 let interfaces = try!(cr.read_interfaces());
43 let fields = try!(cr.read_fields(&constant_pool));
44 let methods = try!(cr.read_methods(&constant_pool));
45 let attributes = try!(cr.read_attributes(&constant_pool));
46
47 Result::Ok(Class {
48 magic: magic,
49 major_version: major_version,
50 minor_version: minor_version,
51 constant_pool: constant_pool,
52 access_flags: access_flags,
53 this_class: this_class,
54 super_class: super_class,
55 interfaces: interfaces,
56 fields: fields,
57 methods: methods,
58 attributes: attributes
59 })
60 }
61
62 fn read_attribute(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Attribute> {
63 let name_index = try!(self.read_u16());
64 let length = try!(self.read_u32());
65
66 let name = match &constant_pool[name_index as usize - 1] {
67 &ConstantPoolInfo::Utf8(ref name) => { name },
68 i @ _ => {
69 let error_message = format!("expected utf8 at index {} but got {:?}", name_index, i);
70 return Result::Err(ParseError::Format(error_message));
71 }
72 };
73
74 let info = match name.as_str() {
75 "Code" => {
76 let max_stack = try!(self.read_u16());
77 let max_locals = try!(self.read_u16());
78 let code_length = try!(self.read_u32());
79 let code = try!(self.read_bytes(code_length));
80 let exception_table_length = try!(self.read_u16());
81 let mut exceptions = Vec::with_capacity(exception_table_length as usize);
82 for _ in 0..exception_table_length {
83 let start_pc = try!(self.read_u16());
84 let end_pc = try!(self.read_u16());
85 let handler_pc = try!(self.read_u16());
86 let catch_type = try!(self.read_u16());
87
88 let exception = Exception {
89 start_pc: start_pc,
90 end_pc: end_pc,
91 handler_pc: handler_pc,
92 catch_type: catch_type
93 };
94 exceptions.push(exception);
95 }
96 let attributes = try!(self.read_attributes(constant_pool));
97
98 let instructions = try!(decode_code(&code));
99
100 Attribute::Code {
101 max_stack: max_stack,
102 max_locals: max_locals,
103 code: instructions,
104 exception_table: exceptions,
105 attributes: attributes
106 }
107 },
108 "ConstantValue" => {
109 let constvalue_index = try!(self.read_u16());
110 Attribute::ConstantValue { constvalue_index: constvalue_index }
111 },
112 "StackMapTable" => {
113 let number_of_entries = try!(self.read_u16());
114 let mut entries = Vec::with_capacity(number_of_entries as usize);
115 for _ in 0..number_of_entries {
116 let frame_type = try!(self.read_u8());
117 let frame = match frame_type {
118 0...63 => StackMapFrame::SameFrame,
119 64...127 => {
120 let info = try!(self.read_verification_type_info());
121 StackMapFrame::SameLocals1StackItemFrame(info)
122 },
123 128...246 => {
124 let message = format!("reserved frame type {} used", frame_type);
125 return Result::Err(ParseError::Format(message));
126 }
127 247 => {
128 let offset_delta = try!(self.read_u16());
129 let info = try!(self.read_verification_type_info());
130 StackMapFrame::SameLocals1StackItemFrameExtended {
131 offset_delta: offset_delta,
132 stack: info
133 }
134 },
135 248...250 => {
136 let offset_delta = try!(self.read_u16());
137 StackMapFrame::ChopFrame { offset_delta: offset_delta }
138 },
139 251 => {
140 let offset_delta = try!(self.read_u16());
141 StackMapFrame::SameFrameExtended { offset_delta: offset_delta }
142 },
143 252...254 => {
144 let offset_delta = try!(self.read_u16());
145 let infos = try!(self.read_verification_type_infos(frame_type as u16 - 251));
146 StackMapFrame::AppendFrame {
147 offset_delta: offset_delta,
148 locals: infos
149 }
150 },
151 255 => {
152 let offset_delta = try!(self.read_u16());
153 let number_of_locals = try!(self.read_u16());
154 let locals = try!(self.read_verification_type_infos(number_of_locals));
155 let number_of_stack_items = try!(self.read_u16());
156 let stack = try!(self.read_verification_type_infos(number_of_stack_items));
157 StackMapFrame::FullFrame {
158 offset_delta: offset_delta,
159 locals: locals,
160 stack: stack
161 }
162 },
163 _ => panic!("unknown frame type {}", frame_type) };
165 entries.push(frame);
166 }
167 Attribute::StackMapTable(entries)
168 },
169 "Exceptions" => {
170 let number_of_exceptions = try!(self.read_u16());
171 let mut exception_index_table = Vec::with_capacity(number_of_exceptions as usize);
172 for _ in 0..number_of_exceptions {
173 let exception_index = try!(self.read_u16());
174 exception_index_table.push(exception_index);
175 }
176 Attribute::Exceptions { exception_index_table: exception_index_table }
177 },
178 "InnerClasses" => {
179 let number_of_classes = try!(self.read_u16());
180 let mut classes = Vec::with_capacity(number_of_classes as usize);
181 for _ in 0..number_of_classes {
182 let inner_class_info_index = try!(self.read_u16());
183 let outer_class_info_index = try!(self.read_u16());
184 let inner_name_index = try!(self.read_u16());
185 let inner_class_access_flags = try!(self.read_u16());
186
187 let class = InnerClass {
188 inner_class_info_index: inner_class_info_index,
189 outer_class_info_index: outer_class_info_index,
190 inner_name_index: inner_name_index,
191 inner_class_access_flags: inner_class_access_flags
192 };
193 classes.push(class);
194 }
195 Attribute::InnerClasses {
196 classes: classes
197 }
198 },
199 "EnclosingMethod" => {
200 let class_index = try!(self.read_u16());
201 let method_index = try!(self.read_u16());
202 Attribute::EnclosingMethod {
203 class_index: class_index,
204 method_index: method_index
205 }
206 },
207 "Synthetic" => {
208 Attribute::Synthetic
209 },
210 "Signature" => {
211 let signature_index = try!(self.read_u16());
212 Attribute::Signature { signature_index: signature_index }
213 },
214 "SourceFile" => {
215 let sourcefile_index = try!(self.read_u16());
216 Attribute::SourceFile { sourcefile_index: sourcefile_index }
217 },
218 "SourceDebugExtension" => {
219 let data = try!(self.read_bytes(length));
220 Attribute::SourceDebugExtension(data)
221 },
222 "LineNumberTable" => {
223 let table_length = try!(self.read_u16());
224 let mut entries = Vec::with_capacity(table_length as usize);
225 for _ in 0..table_length {
226 let start_pc = try!(self.read_u16());
227 let line_number = try!(self.read_u16());
228 let entry = LineNumber {
229 start_pc: start_pc,
230 line_number: line_number
231 };
232 entries.push(entry);
233 }
234 Attribute::LineNumberTable(entries)
235 },
236 "LocalVariableTable" | "LocalVariableTypeTable" => {
237 let table_length = try!(self.read_u16());
238 let mut entries = Vec::with_capacity(table_length as usize);
239 for _ in 0..table_length {
240 let start_pc = try!(self.read_u16());
241 let length = try!(self.read_u16());
242 let name_index = try!(self.read_u16());
243 let descriptor_or_signature_index = try!(self.read_u16());
244 let index = try!(self.read_u16());
245 let entry = LocalVariable {
246 start_pc: start_pc,
247 length: length,
248 name_index: name_index,
249 descriptor_or_signature_index: descriptor_or_signature_index,
250 index: index
251 };
252 entries.push(entry);
253 }
254 if name == "LocalVariableTable" {
255 Attribute::LocalVariableTable(entries)
256 } else {
257 Attribute::LocalVariableTypeTable(entries)
258 }
259 },
260 "Deprecated" => {
261 Attribute::Deprecated
262 },
263 "RuntimeVisibleAnnotations" => {
264 let annotations = try!(self.read_annotations(constant_pool));
265 Attribute::RuntimeVisibleAnnotations(annotations)
266 },
267 "RuntimeInvisibleAnnotations" => {
268 let annotations = try!(self.read_annotations(constant_pool));
269 Attribute::RuntimeInvisibleAnnotations(annotations)
270 },
271 "RuntimeVisibleParameterAnnotations" => {
272 let parameter_annotations = try!(self.read_parameter_annotations(constant_pool));
273 Attribute::RuntimeVisibleParameterAnnotations(parameter_annotations)
274 },
275 "RuntimeInvisibleParameterAnnotations" => {
276 let parameter_annotations = try!(self.read_parameter_annotations(constant_pool));
277 Attribute::RuntimeInvisibleParameterAnnotations(parameter_annotations)
278 },
279 "RuntimeVisibleTypeAnnotations" => {
280 let type_annotations = try!(self.read_type_annotations(constant_pool));
281 Attribute::RuntimeVisibleTypeAnnotations(type_annotations)
282 },
283 "RuntimeInvisibleTypeAnnotations" => {
284 let type_annotations = try!(self.read_type_annotations(constant_pool));
285 Attribute::RuntimeInvisibleTypeAnnotations(type_annotations)
286 },
287 "AnnotationDefault" => {
288 let element_value = try!(self.read_element_value(constant_pool));
289 Attribute::AnnotationDefault { element_value: element_value }
290 },
291 "BootstrapMethods" => {
292 let num_bootstrap_methods = try!(self.read_u16());
293 let mut bootstrap_methods = Vec::with_capacity(num_bootstrap_methods as usize);
294 for _ in 0..num_bootstrap_methods {
295 let bootstrap_method_ref = try!(self.read_u16());
296 let num_bootstrap_arguments = try!(self.read_u16());
297 let mut bootstrap_arguments = Vec::with_capacity(num_bootstrap_arguments as usize);
298 for _ in 0..num_bootstrap_arguments {
299 let bootstrap_argument = try!(self.read_u16());
300 bootstrap_arguments.push(bootstrap_argument);
301 }
302 let bootstrap_method = BootstrapMethod {
303 method_ref: bootstrap_method_ref,
304 arguments: bootstrap_arguments
305 };
306 bootstrap_methods.push(bootstrap_method);
307 }
308 Attribute::BootstrapMethods(bootstrap_methods)
309 },
310 "MethodParameters" => {
311 let num_parameters = try!(self.read_u8());
312 let mut parameters = Vec::with_capacity(num_parameters as usize);
313 for _ in 0..num_parameters {
314 let name_index = try!(self.read_u16());
315 let access_flags = try!(self.read_u16());
316 let parameter = MethodParameter {
317 name_index: name_index,
318 access_flags: access_flags
319 };
320 parameters.push(parameter);
321 }
322 Attribute::MethodParameters(parameters)
323 },
324 _ => {
325 let info = try!(self.read_bytes(length));
326 Attribute::Unknown(info)
327 }
328 };
329 Result::Ok(info)
330 }
331
332 fn read_verification_type_info(self: &mut ClassReader<'a>) -> ParseResult<VerificationType> {
333 let tag = try!(self.read_u8());
334 let verification_type_info = match tag {
335 0 => VerificationType::Top,
336 1 => VerificationType::Integer,
337 2 => VerificationType::Float,
338 3 => VerificationType::Double,
339 4 => VerificationType::Long,
340 5 => VerificationType::Null,
341 6 => VerificationType::UninitializedThis,
342 7 => {
343 let index = try!(self.read_u16());
344 VerificationType::Object { index: index }
345 }
346 8 => {
347 let offset = try!(self.read_u16());
348 VerificationType::UninitializedVariable { offset: offset }
349 }
350 _ => {
351 let error_message = format!("unknown verification type info tag {}", tag);
352 return Result::Err(ParseError::Format(error_message));
353 }
354 };
355 Result::Ok(verification_type_info)
356 }
357
358 fn read_verification_type_infos(self: &mut ClassReader<'a>, num: u16) -> ParseResult<Vec<VerificationType>> {
359 let mut infos = Vec::with_capacity(num as usize);
360 for _ in 0..num {
361 let info = try!(self.read_verification_type_info());
362 infos.push(info);
363 }
364 Result::Ok(infos)
365 }
366
367 fn read_type_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<TypeAnnotation>> {
368 let num_annotations = try!(self.read_u16());
369 let mut annotations = Vec::with_capacity(num_annotations as usize);
370 for _ in 0..num_annotations {
371 let annotation = try!(self.read_type_annotation(constant_pool));
372 annotations.push(annotation);
373 }
374 Result::Ok(annotations)
375 }
376
377 fn read_type_annotation(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<TypeAnnotation> {
378 let target_type_tag = try!(self.read_u8());
379 let target_type = match target_type_tag {
380 0x00 => TargetType::Type,
381 0x01 => TargetType::Method,
382 0x10 => TargetType::Supertype,
383 0x11 => TargetType::TypeBound,
384 0x12 => TargetType::MethodBound,
385 0x13 => TargetType::Field,
386 0x14 => TargetType::MethodReturnType,
387 0x15 => TargetType::ReceiverType,
388 0x16 => TargetType::Parameter,
389 0x17 => TargetType::Throws,
390 0x40 => TargetType::LocalVariableDeclaration,
391 0x41 => TargetType::ResourceVariableDeclaration,
392 0x42 => TargetType::ExceptionParameterDeclaration,
393 0x43 => TargetType::Instanceof,
394 0x44 => TargetType::New,
395 0x45 => TargetType::MethodReferenceNew,
396 0x46 => TargetType::MethodReference,
397 0x47 => TargetType::Cast,
398 0x48 => TargetType::ConstructorArgument,
399 0x49 => TargetType::MethodArgument,
400 0x4A => TargetType::MethodReferenceNewArgument,
401 0x4B => TargetType::MethodReferenceArgument,
402 _ => {
403 let message = format!("unknown target type {}", target_type_tag);
404 return Result::Err(ParseError::Format(message));
405 }
406 };
407 let target_info = match target_type_tag {
408 0x00 | 0x01 => {
409 let type_parameter_index = try!(self.read_u8());
410 TargetInfo::TypeParameter { index: type_parameter_index }
411 },
412 0x10 => {
413 let supertype_index = try!(self.read_u16());
414 TargetInfo::Supertype { index: supertype_index }
415 },
416 0x11 | 0x12 => {
417 let type_parameter_index = try!(self.read_u8());
418 let bound_index = try!(self.read_u8());
419 TargetInfo::TypeParameterBound { index: type_parameter_index, bound_index: bound_index }
420 },
421 0x13...0x15 => {
422 TargetInfo::Empty
423 },
424 0x16 => {
425 let formal_parameter_index = try!(self.read_u8());
426 TargetInfo::MethodFormalParameter { index: formal_parameter_index }
427 },
428 0x17 => {
429 let throws_type_index = try!(self.read_u16());
430 TargetInfo::Throws { type_index: throws_type_index }
431 },
432 0x40 | 0x41 => {
433 let table_length = try!(self.read_u16());
434 let mut table = Vec::with_capacity(table_length as usize);
435 for _ in 0..table_length {
436 let start_pc = try!(self.read_u16());
437 let length = try!(self.read_u16());
438 let index = try!(self.read_u16());
439 let entry = LocalVariableTarget {
440 start_pc: start_pc,
441 length: length,
442 index: index
443 };
444 table.push(entry);
445 }
446 TargetInfo::Localvar(table)
447 },
448 0x42 => {
449 let exception_table_index = try!(self.read_u16());
450 TargetInfo::Catch { exception_table_index : exception_table_index }
451 },
452 0x43...0x46 => {
453 let offset = try!(self.read_u16());
454 TargetInfo::Offset(offset)
455 },
456 0x47...0x4B => {
457 let offset = try!(self.read_u16());
458 let type_argument_index = try!(self.read_u8());
459 TargetInfo::TypeArgument { offset: offset, index: type_argument_index }
460 },
461 _ => {
462 let error_message = format!("unknown target type {}", target_type_tag);
463 return Result::Err(ParseError::Format(error_message));
464 }
465 };
466 let path_length = try!(self.read_u8());
467 let mut path = Vec::with_capacity(path_length as usize);
468 for _ in 0..path_length {
469 let type_path_kind_tag = try!(self.read_u8());
470 let type_path_kind = match type_path_kind_tag {
471 0 => TypePathKind::Array,
472 1 => TypePathKind::Nested,
473 2 => TypePathKind::WildcardBound,
474 3 => TypePathKind::TypeArgument,
475 _ => {
476 let error_message = format!("unknown type path kind {}", type_path_kind_tag);
477 return Result::Err(ParseError::Format(error_message));
478 }
479 };
480 let type_argument_index = try!(self.read_u8());
481 let path_element = PathElement { kind: type_path_kind, argument_index: type_argument_index };
482 path.push(path_element);
483 }
484 let type_index = try!(self.read_u16());
485 let element_value_pairs = try!(self.read_element_value_pairs(constant_pool));
486 Result::Ok(TypeAnnotation {
487 target_type: target_type,
488 target_info: target_info,
489 type_path: TypePath { path: path },
490 type_index: type_index,
491 element_value_pairs: element_value_pairs
492 })
493 }
494
495 fn read_parameter_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Vec<Annotation>>> {
496 let num_parameters = try!(self.read_u8());
497 let mut parameter_annotations = Vec::with_capacity(num_parameters as usize);
498 for _ in 0..num_parameters {
499 let annotations = try!(self.read_annotations(constant_pool));
500 parameter_annotations.push(annotations);
501 }
502 Result::Ok(parameter_annotations)
503 }
504
505 fn read_annotations(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Annotation>> {
506 let num_annotations = try!(self.read_u16());
507 let mut annotations = Vec::with_capacity(num_annotations as usize);
508 for _ in 0..num_annotations {
509 let annotation = try!(self.read_annotation(constant_pool));
510 annotations.push(annotation);
511 }
512 Result::Ok(annotations)
513 }
514
515 fn read_annotation(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Annotation> {
516 let type_index = try!(self.read_u16());
517 let element_value_pairs = try!(self.read_element_value_pairs(constant_pool));
518 Result::Ok(Annotation {
519 type_index: type_index,
520 element_value_pairs: element_value_pairs
521 })
522 }
523
524 fn read_element_value_pairs(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<ElementValuePair>> {
525 let num_evps = try!(self.read_u16());
526 let mut element_value_pairs = Vec::with_capacity(num_evps as usize);
527 for _ in 0..num_evps {
528 let element_name_index = try!(self.read_u16());
529 let element_value = try!(self.read_element_value(constant_pool));
530
531 let element_value_pair = ElementValuePair {
532 element_name_index: element_name_index,
533 value: element_value
534 };
535 element_value_pairs.push(element_value_pair);
536 }
537 Result::Ok(element_value_pairs)
538 }
539
540 fn read_element_value(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<ElementValue> {
541 let tag = try!(self.read_u8()) as char;
542 let value = match tag {
543 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z' | 's' => {
544 let const_value_index = try!(self.read_u16());
545 ElementValue::Constant { const_value_index: const_value_index }
546 },
547 'e' => {
548 let type_name_index = try!(self.read_u16());
549 let const_name_index = try!(self.read_u16());
550 ElementValue::EnumConstant {
551 type_name_index: type_name_index,
552 const_name_index: const_name_index
553 }
554 },
555 'c' => {
556 let class_info_index = try!(self.read_u16());
557 ElementValue::Class { class_info_index: class_info_index }
558 },
559 '@' => {
560 let annotation = try!(self.read_annotation(constant_pool));
561 ElementValue::Annotation(annotation)
562 },
563 '[' => {
564 let num_values = try!(self.read_u16());
565 let mut element_values = Vec::with_capacity(num_values as usize);
566 for _ in 0..num_values {
567 let array_value = try!(self.read_element_value(constant_pool));
568 element_values.push(array_value);
569 }
570 ElementValue::Array(element_values)
571 },
572 _ => {
573 let message = format!("unknown element value tag {}", tag);
574 return Result::Err(ParseError::Format(message));
575 }
576 };
577 Result::Ok(value)
578 }
579
580 fn read_attributes(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Attribute>> {
581 let attribute_count = try!(self.read_u16());
582 let mut attributes = Vec::with_capacity(attribute_count as usize);
583 for _ in 0..attribute_count {
584 let attribute = try!(self.read_attribute(constant_pool));
585 attributes.push(attribute);
586 }
587 Result::Ok(attributes)
588 }
589
590 fn read_methods(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Method>> {
591 let method_count = try!(self.read_u16());
592 let mut methods = Vec::with_capacity(method_count as usize);
593 for _ in 0..method_count {
594 let access_flags = try!(self.read_u16());
595 let name_index = try!(self.read_u16());
596 let descriptor_index = try!(self.read_u16());
597 let attributes = try!(self.read_attributes(&constant_pool));
598
599 let method = Method {
600 access_flags: access_flags,
601 name_index: name_index,
602 descriptor_index: descriptor_index,
603 attributes: attributes
604 };
605 methods.push(method);
606 }
607 Result::Ok(methods)
608 }
609
610 fn read_fields(self: &mut ClassReader<'a>, constant_pool: &Vec<ConstantPoolInfo>) -> ParseResult<Vec<Field>> {
611 let field_count = try!(self.read_u16());
612 let mut fields = Vec::with_capacity(field_count as usize);
613 for _ in 0..field_count {
614 let access_flags = try!(self.read_u16());
615 let name_index = try!(self.read_u16());
616 let descriptor_index = try!(self.read_u16());
617 let attributes = try!(self.read_attributes(&constant_pool));
618
619 let field = Field {
620 access_flags: access_flags,
621 name_index: name_index,
622 descriptor_index:
623 descriptor_index,
624 attributes: attributes };
625 fields.push(field);
626 }
627 Result::Ok(fields)
628 }
629
630 fn read_interfaces(self: &mut ClassReader<'a>) -> ParseResult<Vec<u16>> {
631 let interfaces_count = try!(self.read_u16());
632 let mut interfaces = Vec::with_capacity(interfaces_count as usize);
633 for _ in 0..interfaces_count {
634 let interface = try!(self.read_u16());
635 interfaces.push(interface);
636 }
637 Result::Ok(interfaces)
638 }
639
640 fn read_constant_pool(self: &mut ClassReader<'a>) -> ParseResult<Vec<ConstantPoolInfo>> {
641 let cp_count = try!(self.read_u16()) - 1;
642 let mut cp: Vec<ConstantPoolInfo> = Vec::with_capacity(cp_count as usize);
643
644 let mut i = 0;
645 while i < cp_count {
646 let cp_info = try!(self.read_constant_pool_info());
647 let is_double_length = cp_info.is_double_length();
648
649 cp.push(cp_info);
650 if is_double_length {
651 cp.push(ConstantPoolInfo::Invalid);
652 i += 1;
653 }
654
655 i += 1;
656 }
657
658 Result::Ok(cp)
659 }
660
661 fn read_constant_pool_info(self: &mut ClassReader<'a>) -> ParseResult<ConstantPoolInfo> {
662 let tag = try!(self.read_u8());
663 debug!("read constant pool info tag {}", tag);
664 let info = match tag {
665 1 => {
666 let length = try!(self.read_u16());
667 let data = try!(self.read_bytes(length as u32));
668 let string = read_modified_utf8(&data.clone());
669 trace!("read {} utf8 bytes {:?} -> {}", length, data, string);
670 ConstantPoolInfo::Utf8(string)
671 },
672 3 => {
673 let value = try!(self.read_u32()) as i32;
674 ConstantPoolInfo::Integer(value)
675 },
676 4 => {
677 let value = try!(self.read_u32()) as f32;
678 ConstantPoolInfo::Float(value)
679 },
680 5 => {
681 let value = try!(self.read_u64()) as i64;
682 ConstantPoolInfo::Long(value)
683 },
684 6 => {
685 let value = try!(self.read_u64()) as f64;
686 ConstantPoolInfo::Double(value)
687 },
688 7 => {
689 let name_index = try!(self.read_u16());
690 ConstantPoolInfo::Class(name_index)
691 },
692 8 => {
693 let string_index = try!(self.read_u16());
694 ConstantPoolInfo::String(string_index)
695 },
696 9 => {
697 let class_index = try!(self.read_u16());
698 let name_and_type_index = try!(self.read_u16());
699 ConstantPoolInfo::Fieldref(class_index, name_and_type_index)
700 },
701 10 => {
702 let class_index = try!(self.read_u16());
703 let name_and_type_index = try!(self.read_u16());
704 ConstantPoolInfo::Methodref(class_index, name_and_type_index)
705 },
706 11 => {
707 let class_index = try!(self.read_u16());
708 let name_and_type_index = try!(self.read_u16());
709 ConstantPoolInfo::InterfaceMethodref(class_index, name_and_type_index)
710 },
711 12 => {
712 let name_index = try!(self.read_u16());
713 let descriptor_index = try!(self.read_u16());
714 ConstantPoolInfo::NameAndType(name_index, descriptor_index)
715 },
716 15 => {
717 let reference_kind = try!(self.read_u8());
718 let reference_index = try!(self.read_u16());
719 ConstantPoolInfo::MethodHandle(reference_kind, reference_index)
720 },
721 16 => {
722 let descriptor_index = try!(self.read_u16());
723 ConstantPoolInfo::MethodType(descriptor_index)
724 },
725 18 => {
726 let bootstrap_method_attr_index = try!(self.read_u16());
727 let name_and_type_index = try!(self.read_u16());
728 ConstantPoolInfo::InvokeDynamic(bootstrap_method_attr_index, name_and_type_index)
729 },
730 _ => {
731 let message = format!("unknown constant pool item with tag {}", tag);
732 return Result::Err(ParseError::Format(message));
733 }
734 };
735 Result::Ok(info)
736 }
737
738 fn read_bytes(self: &mut ClassReader<'a>, length: u32) -> ParseResult<Vec<u8>> {
739 let mut vec: Vec<u8> = Vec::with_capacity(length as usize);
740 try!(self.reader.by_ref().take(length as u64).read_to_end(&mut vec));
741
742 self.position += length as usize;
743 Result::Ok(vec)
744 }
745
746 fn read_u64(self: &mut ClassReader<'a>) -> ParseResult<u64> {
747 let mut buf: Vec<u8> = Vec::with_capacity(8);
748 try!(self.reader.by_ref().take(8).read_to_end(&mut buf));
749
750 self.position += 8;
751 Result::Ok((buf[0] as u64) << 56 | (buf[1] as u64) << 48
752 | (buf[2] as u64) << 40 | (buf[3] as u64) << 32
753 | (buf[4] as u64) << 24 | (buf[5] as u64) << 16
754 | (buf[6] as u64) << 8 | (buf[7] as u64))
755 }
756
757 fn read_u32(self: &mut ClassReader<'a>) -> ParseResult<u32> {
758 let mut buf: Vec<u8> = Vec::with_capacity(4);
759 try!(self.reader.by_ref().take(4).read_to_end(&mut buf));
760
761 self.position += 4;
762 Result::Ok((buf[0] as u32) << 24 | (buf[1] as u32) << 16
763 | (buf[2] as u32) << 8 | (buf[3] as u32))
764 }
765
766 fn read_u16(self: &mut ClassReader<'a>) -> ParseResult<u16> {
767 let mut buf: Vec<u8> = Vec::with_capacity(2);
768 try!(self.reader.by_ref().take(2).read_to_end(&mut buf));
769
770 self.position += 2;
771 Result::Ok((buf[0] as u16) << 8 | (buf[1] as u16))
772 }
773
774 fn read_u8(self: &mut ClassReader<'a>) -> ParseResult<u8> {
775 let mut buf: Vec<u8> = Vec::with_capacity(1);
776 try!(self.reader.by_ref().take(1).read_to_end(&mut buf));
777
778 self.position += 1;
779 Result::Ok(buf[0] as u8)
780 }
781
782}
783
784fn read_modified_utf8(buf: &Vec<u8>) -> String {
785 let mut string = String::with_capacity(buf.len());
786
787 let mut i = 0;
788 while i < buf.len() {
789 let b0 = buf[i] as u32;
790 let decoded_char = if (b0 >> 7) == 0 {
791 trace!("read byte {:08.b}", b0);
792 char::from_u32(b0)
793 } else if (b0 >> 5) == 0b110 {
794 i += 1;
795 let b1 = buf[i] as u32; let code_point = ((b0 & 0b0001_1111) << 6)
797 + (b1 & 0b0011_1111);
798 trace!("read bytes {:08.b} {:08.b} -> {:032.b}", b0, b1, code_point);
799 char::from_u32(code_point)
800 } else if (b0 >> 4) == 0b1110 {
801 i += 1;
802 let b1 = buf[i] as u32; i += 1;
804 let b2 = buf[i] as u32; let check_for_surrogate = i < (buf.len() - 2);
806 if (b0 == 0b11101101) && ((b1 >> 4) == 0b1010) && check_for_surrogate && (buf[i+1] == 0b1110_1101) { i += 1;
808 let b3 = buf[i] as u32; i += 1;
810 let b4 = buf[i] as u32; i += 1;
812 let b5 = buf[i] as u32; let code_point = 0b1_0000_0000_0000_0000
814 + ((b1 & 0b0000_1111) << 16)
815 + ((b2 & 0b0011_1111) << 10)
816 + ((b4 & 0b0000_1111) << 6)
817 + (b5 & 0x0011_1111);
818 trace!("read bytes {:08.b} {:08.b} {:08.b} {:08.b} {:08.b} {:08.b} -> {:032.b}", b0, b1, b2, b3, b4, b5, code_point);
819 trace!(" -> {} {:x}", code_point, code_point);
820 char::from_u32(code_point)
821 } else {
822 let code_point = ((b0 & 0b0000_1111) << 12)
823 + ((b1 & 0b0011_1111) << 6)
824 + (b2 & 0b0011_1111);
825 if ((code_point >= 0xD800) && (code_point <= 0xDBFF))
826 || ((code_point >= 0xDC00) && (code_point <= 0xDFFF)) {
827 info!("encountered surrogate code point {:x} which is invalid for UTF-8", code_point);
828 Option::None
829 } else {
830 trace!("read bytes {:08.b} {:08.b} {:08.b} -> {:032.b}", b0, b1, b2, code_point);
831 trace!(" -> {} {:x}", code_point, code_point);
832 char::from_u32(code_point)
833 }
834 }
835 } else {
836 Option::None
837 };
838 match decoded_char {
839 Option::None => string.push('\u{FFFD}'),
840 Option::Some(c) => string.push(c)
841 }
842 i += 1;
843 }
844 string
845}