Skip to content

Commit fe4b3a9

Browse files
committed
Parse java arrays in annotations properly
Previously the value from the arrays was being parsed correctly but into an object which was then immediately thrown away, so the value was never really used.
1 parent ec79bdd commit fe4b3a9

File tree

6 files changed

+46
-18
lines changed

6 files changed

+46
-18
lines changed

jbmc/src/java_bytecode/java_bytecode_parser.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class java_bytecode_parsert:public parsert
125125
void rRuntimeAnnotation_attribute(annotationst &);
126126
void rRuntimeAnnotation(annotationt &);
127127
void relement_value_pairs(annotationt::element_value_pairst &);
128-
void relement_value_pair(annotationt::element_value_pairt &);
128+
exprt get_relement_value();
129129
void rmethod_attribute(methodt &method);
130130
void rfield_attribute(fieldt &);
131131
void rcode_attribute(methodt &method);
@@ -1507,16 +1507,17 @@ void java_bytecode_parsert::relement_value_pairs(
15071507
{
15081508
u2 element_name_index=read_u2();
15091509
element_value_pair.element_name=pool_entry(element_name_index).s;
1510-
1511-
relement_value_pair(element_value_pair);
1510+
element_value_pair.value = get_relement_value();
15121511
}
15131512
}
15141513

15151514
/// Corresponds to the element_value structure
15161515
/// Described in Java 8 specification 4.7.16.1
15171516
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.16.1
1518-
void java_bytecode_parsert::relement_value_pair(
1519-
annotationt::element_value_pairt &element_value_pair)
1517+
/// \returns An exprt that represents the particular value of annotations field.
1518+
/// This is usually one of: a byte, number of some sort, string, character,
1519+
/// enum, Class type, array or another annotation.
1520+
exprt java_bytecode_parsert::get_relement_value()
15201521
{
15211522
u1 tag=read_u1();
15221523

@@ -1527,50 +1528,46 @@ void java_bytecode_parsert::relement_value_pair(
15271528
UNUSED_u2(type_name_index);
15281529
UNUSED_u2(const_name_index);
15291530
// todo: enum
1531+
return exprt();
15301532
}
1531-
break;
15321533

15331534
case 'c':
15341535
{
15351536
u2 class_info_index = read_u2();
1536-
element_value_pair.value = symbol_exprt(pool_entry(class_info_index).s);
1537+
return symbol_exprt(pool_entry(class_info_index).s);
15371538
}
1538-
break;
15391539

15401540
case '@':
15411541
{
1542+
// TODO: return this wrapped in an exprt
15421543
// another annotation, recursively
15431544
annotationt annotation;
15441545
rRuntimeAnnotation(annotation);
1546+
return exprt();
15451547
}
1546-
break;
15471548

15481549
case '[':
15491550
{
1551+
array_exprt values;
15501552
u2 num_values=read_u2();
15511553
for(std::size_t i=0; i<num_values; i++)
15521554
{
1553-
annotationt::element_value_pairt element_value;
1554-
relement_value_pair(element_value); // recursive call
1555+
values.operands().push_back(get_relement_value());
15551556
}
1557+
return values;
15561558
}
1557-
break;
15581559

15591560
case 's':
15601561
{
15611562
u2 const_value_index=read_u2();
1562-
element_value_pair.value=string_constantt(
1563-
pool_entry(const_value_index).s);
1563+
return string_constantt(pool_entry(const_value_index).s);
15641564
}
1565-
break;
15661565

15671566
default:
15681567
{
15691568
u2 const_value_index=read_u2();
1570-
element_value_pair.value=constant(const_value_index);
1569+
return constant(const_value_index);
15711570
}
1572-
1573-
break;
15741571
}
15751572
}
15761573

Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public @interface AnnotationWithStringArray {
2+
String[] value() default {};
3+
}
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@AnnotationWithStringArray({"Dave", "Another Dave"})
2+
public class ClassWithArrayAnnotation {
3+
}

jbmc/unit/java_bytecode/java_bytecode_parser/parse_java_annotations.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,30 @@ SCENARIO(
9191
REQUIRE(java_type == void_type());
9292
}
9393
}
94+
WHEN("Parsing an annotation with an array field.")
95+
{
96+
const symbol_tablet &new_symbol_table = load_java_class(
97+
"ClassWithArrayAnnotation", "./java_bytecode/java_bytecode_parser");
98+
99+
THEN("The annotation should store an array of type string.")
100+
{
101+
const symbolt &class_symbol =
102+
*new_symbol_table.lookup("java::ClassWithArrayAnnotation");
103+
const std::vector<java_annotationt> &java_annotations =
104+
to_annotated_type(class_symbol.type).get_annotations();
105+
java_bytecode_parse_treet::annotationst annotations;
106+
convert_java_annotations(java_annotations, annotations);
107+
REQUIRE(annotations.size() == 1);
108+
const auto &annotation = annotations.front();
109+
const auto &element_value_pair = annotation.element_value_pairs.front();
110+
const auto &array = to_array_expr(element_value_pair.value);
111+
112+
REQUIRE(array.operands().size() == 2);
113+
const auto &dave = array.op0().get(ID_value);
114+
const auto &another_dave = array.op1().get(ID_value);
115+
REQUIRE(id2string(dave) == "Dave");
116+
REQUIRE(id2string(another_dave) == "Another Dave");
117+
}
118+
}
94119
}
95120
}

0 commit comments

Comments
 (0)