Skip to content

Commit b8c05f4

Browse files
committed
feat: add support for proto maps with enum values
1 parent b510b50 commit b8c05f4

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

src/main/java/com/code_intelligence/jazzer/mutation/mutator/proto/BuilderMutatorFactory.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,18 +178,15 @@ private ExtendedMutatorFactory withDescriptorDependentMutatorFactoryIfNeeded(
178178
Stream.concat(LangMutators.newFactories(), CollectionMutators.newFactories()),
179179
Stream.of(enumFactory)));
180180
} else if (field.getJavaType() == JavaType.MESSAGE) {
181-
Descriptor messageDescriptor;
182181
if (field.isMapField()) {
183182
// Map fields are represented as messages, but we mutate them as actual Java Maps. In case
184-
// the values of the proto map are themselves messages, we need to mutate their type.
183+
// the values of the proto map are themselves messages or enums, we need to mutate their
184+
// type.
185185
FieldDescriptor valueField = field.getMessageType().getFields().get(1);
186-
if (valueField.getJavaType() != JavaType.MESSAGE) {
187-
return originalFactory;
188-
}
189-
messageDescriptor = valueField.getMessageType();
190-
} else {
191-
messageDescriptor = field.getMessageType();
186+
return withDescriptorDependentMutatorFactoryIfNeeded(
187+
originalFactory, valueField, annotations);
192188
}
189+
Descriptor messageDescriptor = field.getMessageType();
193190
return ChainedMutatorFactory.of(
194191
originalFactory.getCache(),
195192
Stream.of(

src/test/java/com/code_intelligence/jazzer/mutation/mutator/StressTest.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.code_intelligence.jazzer.protobuf.Proto3.EnumField3.TestEnum;
6060
import com.code_intelligence.jazzer.protobuf.Proto3.EnumFieldRepeated3;
6161
import com.code_intelligence.jazzer.protobuf.Proto3.EnumFieldRepeated3.TestEnumRepeated;
62+
import com.code_intelligence.jazzer.protobuf.Proto3.EnumMapField3;
6263
import com.code_intelligence.jazzer.protobuf.Proto3.FloatField3;
6364
import com.code_intelligence.jazzer.protobuf.Proto3.IntegralField3;
6465
import com.code_intelligence.jazzer.protobuf.Proto3.MapField3;
@@ -1010,6 +1011,12 @@ public static Stream<Arguments> protoStressTestCases() {
10101011
false,
10111012
distinctElementsRatio(0.45),
10121013
distinctElementsRatio(0.45)),
1014+
arguments(
1015+
new TypeHolder<@NotNull EnumMapField3>() {}.annotatedType(),
1016+
"{Builder.Map<String, {Builder.Enum<TestEnum>} -> Message>} -> Message",
1017+
false,
1018+
distinctElementsRatio(0.45),
1019+
distinctElementsRatio(0.45)),
10131020
arguments(
10141021
new TypeHolder<@NotNull DoubleField3>() {}.annotatedType(),
10151022
"{Builder.Double} -> Message",
@@ -1050,17 +1057,19 @@ public static Stream<Arguments> protoStressTestCases() {
10501057
+ " Builder via List<Integer>, Builder via List<Integer>, Builder via List<Long>,"
10511058
+ " Builder via List<Long>, Builder via List<Float>, Builder via List<Double>,"
10521059
+ " Builder via List<String>, Builder via List<Enum<Enum>>, WithoutInit(Builder via"
1053-
+ " List<(cycle) -> Message>), Builder.Map<Integer, Integer>,"
1060+
+ " List<(cycle) -> Message>), Builder.Map<Integer, Integer>, Builder.Map<Integer,"
1061+
+ " Enum<Enum>>, WithoutInit(Builder.Map<Integer, (cycle) -> Message>),"
10541062
+ " Builder.Nullable<FixedValue(OnlyLabel)>, Builder.Nullable<{<empty>} ->"
10551063
+ " Message>, Builder.Nullable<Integer> | Builder.Nullable<Long> |"
10561064
+ " Builder.Nullable<Integer>} -> Message>)} -> Message>), Builder via"
10571065
+ " List<Boolean>, Builder via List<Integer>, Builder via List<Integer>, Builder"
10581066
+ " via List<Long>, Builder via List<Long>, Builder via List<Float>, Builder via"
10591067
+ " List<Double>, Builder via List<String>, Builder via List<Enum<Enum>>,"
10601068
+ " WithoutInit(Builder via List<(cycle) -> Message>), Builder.Map<Integer,"
1061-
+ " Integer>, Builder.Nullable<FixedValue(OnlyLabel)>, Builder.Nullable<(cycle) ->"
1062-
+ " Message>, Builder.Nullable<Integer> | Builder.Nullable<Long> |"
1063-
+ " Builder.Nullable<Integer>} -> Message",
1069+
+ " Integer>, Builder.Map<Integer, Enum<Enum>>, WithoutInit(Builder.Map<Integer,"
1070+
+ " (cycle) -> Message>), Builder.Nullable<FixedValue(OnlyLabel)>,"
1071+
+ " Builder.Nullable<(cycle) -> Message>, Builder.Nullable<Integer> |"
1072+
+ " Builder.Nullable<Long> | Builder.Nullable<Integer>} -> Message",
10641073
false,
10651074
manyDistinctElements(),
10661075
manyDistinctElements()),
@@ -1083,17 +1092,19 @@ public static Stream<Arguments> protoStressTestCases() {
10831092
+ " Builder via List<Integer>, Builder via List<Integer>, Builder via List<Long>,"
10841093
+ " Builder via List<Long>, Builder via List<Float>, Builder via List<Double>,"
10851094
+ " Builder via List<String>, Builder via List<Enum<Enum>>, WithoutInit(Builder via"
1086-
+ " List<(cycle) -> Message>), Builder.Map<Integer, Integer>,"
1095+
+ " List<(cycle) -> Message>), Builder.Map<Integer, Integer>, Builder.Map<Integer,"
1096+
+ " Enum<Enum>>, WithoutInit(Builder.Map<Integer, (cycle) -> Message>),"
10871097
+ " Builder.Nullable<FixedValue(OnlyLabel)>, Builder.Nullable<{<empty>} ->"
10881098
+ " Message>, Builder.Nullable<Integer> | Builder.Nullable<Long> |"
10891099
+ " Builder.Nullable<Integer>} -> Message>)} -> Message>), Builder via"
10901100
+ " List<Boolean>, Builder via List<Integer>, Builder via List<Integer>, Builder"
10911101
+ " via List<Long>, Builder via List<Long>, Builder via List<Float>, Builder via"
10921102
+ " List<Double>, Builder via List<String>, Builder via List<Enum<Enum>>,"
10931103
+ " WithoutInit(Builder via List<(cycle) -> Message>), Builder.Map<Integer,"
1094-
+ " Integer>, Builder.Nullable<FixedValue(OnlyLabel)>, Builder.Nullable<(cycle) ->"
1095-
+ " Message>, Builder.Nullable<Integer> | Builder.Nullable<Long> |"
1096-
+ " Builder.Nullable<Integer>} -> Message",
1104+
+ " Integer>, Builder.Map<Integer, Enum<Enum>>, WithoutInit(Builder.Map<Integer,"
1105+
+ " (cycle) -> Message>), Builder.Nullable<FixedValue(OnlyLabel)>,"
1106+
+ " Builder.Nullable<(cycle) -> Message>, Builder.Nullable<Integer> |"
1107+
+ " Builder.Nullable<Long> | Builder.Nullable<Integer>} -> Message",
10971108
false,
10981109
manyDistinctElements(),
10991110
manyDistinctElements()),

src/test/java/com/code_intelligence/jazzer/mutation/mutator/proto/proto2.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ message TestProtobuf {
132132
}
133133

134134
map<int32, int32> map_field = 25;
135+
map<int32, Enum> enum_map = 26;
136+
map<int32, TestSubProtobuf> message_map = 27;
135137

136138
// Special cases
137139
enum EnumOneLabel {

src/test/java/com/code_intelligence/jazzer/mutation/mutator/proto/proto3.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ message MessageMapField3 {
117117
map<string, MapField3> some_field = 1;
118118
}
119119

120+
message EnumMapField3 {
121+
map<string, EnumField3> some_field = 1;
122+
}
123+
120124
message FloatField3 {
121125
float some_field = 1;
122126
}

tests/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ java_fuzz_target_test(
616616

617617
java_fuzz_target_test(
618618
name = "MutatorComplexProtoFuzzer",
619+
timeout = "long",
619620
srcs = ["src/test/java/com/example/MutatorComplexProtoFuzzer.java"],
620621
allowed_findings = ["com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium"],
621622
fuzzer_args = [
@@ -624,7 +625,7 @@ java_fuzz_target_test(
624625
# Limit runs to catch regressions in mutator efficiency and speed up test runs.
625626
# Especially on Windows this test needs way more iterations than on other platforms.
626627
"-runs=3000000",
627-
"-seed=123",
628+
"-seed=1",
628629
],
629630
target_class = "com.example.MutatorComplexProtoFuzzer",
630631
verify_crash_reproducer = False,

0 commit comments

Comments
 (0)