942 generic_signature_index = parse_generic_signature_attribute(CHECK); |
942 generic_signature_index = parse_generic_signature_attribute(CHECK); |
943 } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { |
943 } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) { |
944 runtime_visible_annotations_length = attribute_length; |
944 runtime_visible_annotations_length = attribute_length; |
945 runtime_visible_annotations = cfs->get_u1_buffer(); |
945 runtime_visible_annotations = cfs->get_u1_buffer(); |
946 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
946 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
|
947 cfs->guarantee_more(runtime_visible_annotations_length, CHECK); |
947 parse_annotations(runtime_visible_annotations, |
948 parse_annotations(runtime_visible_annotations, |
948 runtime_visible_annotations_length, |
949 runtime_visible_annotations_length, |
949 parsed_annotations, |
950 parsed_annotations, |
950 CHECK); |
951 CHECK); |
951 cfs->skip_u1(runtime_visible_annotations_length, CHECK); |
952 cfs->skip_u1_fast(runtime_visible_annotations_length); |
952 } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { |
953 } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { |
953 runtime_invisible_annotations_length = attribute_length; |
954 runtime_invisible_annotations_length = attribute_length; |
954 runtime_invisible_annotations = cfs->get_u1_buffer(); |
955 runtime_invisible_annotations = cfs->get_u1_buffer(); |
955 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
956 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
956 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); |
957 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); |
1653 index = skip_annotation_value(buffer, limit, index); |
1654 index = skip_annotation_value(buffer, limit, index); |
1654 } |
1655 } |
1655 return index; |
1656 return index; |
1656 } |
1657 } |
1657 |
1658 |
|
1659 // Safely increment index by val if does not pass limit |
|
1660 #define SAFE_ADD(index, limit, val) \ |
|
1661 if (index >= limit - val) return limit; \ |
|
1662 index += val; |
|
1663 |
1658 // Skip an annotation value. Return >=limit if there is any problem. |
1664 // Skip an annotation value. Return >=limit if there is any problem. |
1659 int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { |
1665 int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { |
1660 // value := switch (tag:u1) { |
1666 // value := switch (tag:u1) { |
1661 // case B, C, I, S, Z, D, F, J, c: con:u2; |
1667 // case B, C, I, S, Z, D, F, J, c: con:u2; |
1662 // case e: e_class:u2 e_name:u2; |
1668 // case e: e_class:u2 e_name:u2; |
1663 // case s: s_con:u2; |
1669 // case s: s_con:u2; |
1664 // case [: do(nval:u2) {value}; |
1670 // case [: do(nval:u2) {value}; |
1665 // case @: annotation; |
1671 // case @: annotation; |
1666 // case s: s_con:u2; |
1672 // case s: s_con:u2; |
1667 // } |
1673 // } |
1668 if ((index += 1) >= limit) return limit; // read tag |
1674 SAFE_ADD(index, limit, 1); // read tag |
1669 u1 tag = buffer[index-1]; |
1675 u1 tag = buffer[index-1]; |
1670 switch (tag) { |
1676 switch (tag) { |
1671 case 'B': case 'C': case 'I': case 'S': case 'Z': |
1677 case 'B': case 'C': case 'I': case 'S': case 'Z': |
1672 case 'D': case 'F': case 'J': case 'c': case 's': |
1678 case 'D': case 'F': case 'J': case 'c': case 's': |
1673 index += 2; // skip con or s_con |
1679 SAFE_ADD(index, limit, 2); // skip con or s_con |
1674 break; |
1680 break; |
1675 case 'e': |
1681 case 'e': |
1676 index += 4; // skip e_class, e_name |
1682 SAFE_ADD(index, limit, 4); // skip e_class, e_name |
1677 break; |
1683 break; |
1678 case '[': |
1684 case '[': |
1679 { |
1685 { |
1680 if ((index += 2) >= limit) return limit; // read nval |
1686 SAFE_ADD(index, limit, 2); // read nval |
1681 int nval = Bytes::get_Java_u2(buffer+index-2); |
1687 int nval = Bytes::get_Java_u2(buffer+index-2); |
1682 while (--nval >= 0 && index < limit) { |
1688 while (--nval >= 0 && index < limit) { |
1683 index = skip_annotation_value(buffer, limit, index); |
1689 index = skip_annotation_value(buffer, limit, index); |
1684 } |
1690 } |
1685 } |
1691 } |
1697 // Sift through annotations, looking for those significant to the VM: |
1703 // Sift through annotations, looking for those significant to the VM: |
1698 void ClassFileParser::parse_annotations(u1* buffer, int limit, |
1704 void ClassFileParser::parse_annotations(u1* buffer, int limit, |
1699 ClassFileParser::AnnotationCollector* coll, |
1705 ClassFileParser::AnnotationCollector* coll, |
1700 TRAPS) { |
1706 TRAPS) { |
1701 // annotations := do(nann:u2) {annotation} |
1707 // annotations := do(nann:u2) {annotation} |
1702 int index = 0; |
1708 int index = 2; |
1703 if ((index += 2) >= limit) return; // read nann |
1709 if (index >= limit) return; // read nann |
1704 int nann = Bytes::get_Java_u2(buffer+index-2); |
1710 int nann = Bytes::get_Java_u2(buffer+index-2); |
1705 enum { // initial annotation layout |
1711 enum { // initial annotation layout |
1706 atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' |
1712 atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' |
1707 count_off = 2, // u2 such as 1 (one value) |
1713 count_off = 2, // u2 such as 1 (one value) |
1708 member_off = 4, // utf8 such as 'value' |
1714 member_off = 4, // utf8 such as 'value' |
1717 s_tag_val = 's', // payload is String |
1723 s_tag_val = 's', // payload is String |
1718 s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' |
1724 s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' |
1719 s_size = 9, |
1725 s_size = 9, |
1720 min_size = 6 // smallest possible size (zero members) |
1726 min_size = 6 // smallest possible size (zero members) |
1721 }; |
1727 }; |
1722 while ((--nann) >= 0 && (index-2 + min_size <= limit)) { |
1728 // Cannot add min_size to index in case of overflow MAX_INT |
|
1729 while ((--nann) >= 0 && (index-2 <= limit - min_size)) { |
1723 int index0 = index; |
1730 int index0 = index; |
1724 index = skip_annotation(buffer, limit, index); |
1731 index = skip_annotation(buffer, limit, index); |
1725 u1* abase = buffer + index0; |
1732 u1* abase = buffer + index0; |
1726 int atype = Bytes::get_Java_u2(abase + atype_off); |
1733 int atype = Bytes::get_Java_u2(abase + atype_off); |
1727 int count = Bytes::get_Java_u2(abase + count_off); |
1734 int count = Bytes::get_Java_u2(abase + count_off); |
2322 generic_signature_index = parse_generic_signature_attribute(CHECK_(nullHandle)); |
2329 generic_signature_index = parse_generic_signature_attribute(CHECK_(nullHandle)); |
2323 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { |
2330 } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) { |
2324 runtime_visible_annotations_length = method_attribute_length; |
2331 runtime_visible_annotations_length = method_attribute_length; |
2325 runtime_visible_annotations = cfs->get_u1_buffer(); |
2332 runtime_visible_annotations = cfs->get_u1_buffer(); |
2326 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
2333 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
|
2334 cfs->guarantee_more(runtime_visible_annotations_length, CHECK_(nullHandle)); |
2327 parse_annotations(runtime_visible_annotations, |
2335 parse_annotations(runtime_visible_annotations, |
2328 runtime_visible_annotations_length, &parsed_annotations, |
2336 runtime_visible_annotations_length, &parsed_annotations, |
2329 CHECK_(nullHandle)); |
2337 CHECK_(nullHandle)); |
2330 cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); |
2338 cfs->skip_u1_fast(runtime_visible_annotations_length); |
2331 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { |
2339 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { |
2332 runtime_invisible_annotations_length = method_attribute_length; |
2340 runtime_invisible_annotations_length = method_attribute_length; |
2333 runtime_invisible_annotations = cfs->get_u1_buffer(); |
2341 runtime_invisible_annotations = cfs->get_u1_buffer(); |
2334 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
2342 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
2335 cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle)); |
2343 cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle)); |
2951 parse_classfile_signature_attribute(CHECK); |
2959 parse_classfile_signature_attribute(CHECK); |
2952 } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { |
2960 } else if (tag == vmSymbols::tag_runtime_visible_annotations()) { |
2953 runtime_visible_annotations_length = attribute_length; |
2961 runtime_visible_annotations_length = attribute_length; |
2954 runtime_visible_annotations = cfs->get_u1_buffer(); |
2962 runtime_visible_annotations = cfs->get_u1_buffer(); |
2955 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
2963 assert(runtime_visible_annotations != NULL, "null visible annotations"); |
|
2964 cfs->guarantee_more(runtime_visible_annotations_length, CHECK); |
2956 parse_annotations(runtime_visible_annotations, |
2965 parse_annotations(runtime_visible_annotations, |
2957 runtime_visible_annotations_length, |
2966 runtime_visible_annotations_length, |
2958 parsed_annotations, |
2967 parsed_annotations, |
2959 CHECK); |
2968 CHECK); |
2960 cfs->skip_u1(runtime_visible_annotations_length, CHECK); |
2969 cfs->skip_u1_fast(runtime_visible_annotations_length); |
2961 } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { |
2970 } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { |
2962 runtime_invisible_annotations_length = attribute_length; |
2971 runtime_invisible_annotations_length = attribute_length; |
2963 runtime_invisible_annotations = cfs->get_u1_buffer(); |
2972 runtime_invisible_annotations = cfs->get_u1_buffer(); |
2964 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
2973 assert(runtime_invisible_annotations != NULL, "null invisible annotations"); |
2965 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); |
2974 cfs->skip_u1(runtime_invisible_annotations_length, CHECK); |