Skip to content

Commit f31e023

Browse files
committed
fix: instrumention of nested records, and records with annotated fields
Using ClassWriter without ClassReader in asm, seems to produce corrupted bytecode for nested records and records with annotated fields. Prior to this fix, a segfault was triggered for nested records that use Jazzer annotations when Jazzer was trying to access data on record components, when trying to create a record mutator. In addition, for non-nested records with annotated fields as for example: record Address(byte @WithLength(max=10) [] data) {} no suitable mutator could be found.
1 parent f8668e2 commit f31e023

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/main/java/com/code_intelligence/jazzer/instrumentor/TraceDataFlowInstrumentor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ internal class TraceDataFlowInstrumentor(
5252
}
5353
}
5454

55-
val writer = ClassWriter(ClassWriter.COMPUTE_MAXS)
55+
val writer = ClassWriter(reader, ClassWriter.COMPUTE_MAXS)
5656
node.accept(writer)
5757
return writer.toByteArray()
5858
}

tests/BUILD.bazel

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,35 @@ java_fuzz_target_test(
10771077
],
10781078
)
10791079

1080+
java_fuzz_target_test(
1081+
name = "NestedRecordFuzzer",
1082+
timeout = "short",
1083+
srcs = [
1084+
"src/test/java/com/example/NestedRecordFuzzer.java",
1085+
],
1086+
fuzzer_args = [
1087+
"-print_final_stats=1",
1088+
"-runs=10000",
1089+
],
1090+
javacopts = [
1091+
"--release",
1092+
"17",
1093+
],
1094+
tags = [
1095+
"no-jdk8",
1096+
],
1097+
target_class = "com.example.NestedRecordFuzzer",
1098+
runtime_deps = [
1099+
"@maven//:org_junit_jupiter_junit_jupiter_engine",
1100+
],
1101+
deps = [
1102+
"//deploy:jazzer-junit",
1103+
"//deploy:jazzer-project",
1104+
"@maven//:org_junit_jupiter_junit_jupiter_api",
1105+
"@maven//:org_junit_jupiter_junit_jupiter_params",
1106+
],
1107+
)
1108+
10801109
java_fuzz_target_test(
10811110
name = "BigDecimalFuzzer",
10821111
srcs = [
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2024 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example;
18+
19+
import com.code_intelligence.jazzer.junit.FuzzTest;
20+
import com.code_intelligence.jazzer.mutation.annotation.NotNull;
21+
import com.code_intelligence.jazzer.mutation.annotation.WithLength;
22+
23+
/**
24+
* This regression test checks if we instrument fuzz test classes with nested records correctly, and
25+
* can start a fuzzing run at all without getting segfaults.
26+
*/
27+
public class NestedRecordFuzzer {
28+
record Address(@NotNull String street, byte @NotNull @WithLength(min = 3, max = 4) [] data) {}
29+
30+
@FuzzTest
31+
public void test(Address address) {
32+
if (address != null) {
33+
byte[] data = address.data();
34+
if (data.length < 3 || data.length > 4) {
35+
throw new IllegalStateException("Data length out of bounds: " + data.length);
36+
}
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)