Skip to content

Commit 728528d

Browse files
committed
fix: use getCanonicalName() for array codegen in autofuzz reproducers
1 parent ffa1bab commit 728528d

4 files changed

Lines changed: 92 additions & 3 deletions

File tree

src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ Object consume(FuzzedDataProvider data, Type genericType, AutofuzzCodegenVisitor
496496
} else {
497497
if (visitor != null) {
498498
visitor.pushGroup(
499-
String.format("new %s[]{", type.getComponentType().getName()), ", ", "}");
499+
String.format("new %s[]{", type.getComponentType().getCanonicalName()), ", ", "}");
500500
}
501501
int remainingBytesBeforeFirstElementCreation = data.remainingBytes();
502502
Object firstElement = consume(data, type.getComponentType(), visitor);
@@ -593,7 +593,7 @@ Object consume(FuzzedDataProvider data, Type genericType, AutofuzzCodegenVisitor
593593
} else if (type.isEnum()) {
594594
Enum<?> enumValue = (Enum<?>) data.pickValue(type.getEnumConstants());
595595
if (visitor != null) {
596-
visitor.pushElement(String.format("%s.%s", type.getName(), enumValue.name()));
596+
visitor.pushElement(String.format("%s.%s", type.getCanonicalName(), enumValue.name()));
597597
}
598598
return enumValue;
599599
} else if (type == Class.class) {

src/test/java/com/code_intelligence/jazzer/autofuzz/MetaTest.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,45 @@ public void testConsume() throws NoSuchMethodException {
125125
23, // remaining bytes
126126
"foo\nbar"));
127127

128+
// Test for multi-dimensional array codegen
129+
// (https://github.com/CodeIntelligenceTesting/jazzer/issues/1026)
130+
consumeTestCase(
131+
int[][].class,
132+
new int[][] {{1, 2}, {3}},
133+
"new int[][]{new int[]{1, 2}, new int[]{3}}",
134+
Arrays.asList(
135+
(byte) 1, // do not return null for the outer array
136+
100, // remainingBytes before first element creation
137+
(byte) 1, // do not return null for first int[]
138+
50, // remainingBytes for consumeArrayLength inside first consumeInts
139+
new int[] {1, 2}, // consumeInts returns first int[]
140+
40, // remainingBytes after first element creation
141+
// sizeOfElementEstimate = 100 - 40 = 60
142+
// consumeArrayLength(data, 60) = remainingBytes / 2 / 60
143+
// need this to return 2: 240 / 2 / 60 = 2
144+
240, // remainingBytes for outer consumeArrayLength
145+
(byte) 1, // do not return null for second int[]
146+
50, // remainingBytes for consumeArrayLength inside second consumeInts
147+
new int[] {3})); // consumeInts returns second int[]
148+
149+
// Test that inner class arrays use getCanonicalName() (dot-separated) not getTypeName() which
150+
// would produce '$'-separated names that are not valid Java source.
151+
consumeTestCase(
152+
TestEnum[].class,
153+
new TestEnum[] {TestEnum.BAR},
154+
"new com.code_intelligence.jazzer.autofuzz.MetaTest.TestEnum[]{"
155+
+ "com.code_intelligence.jazzer.autofuzz.MetaTest.TestEnum.BAR}",
156+
Arrays.asList(
157+
(byte) 1, // do not return null for the array
158+
100, // remainingBytes before first element creation
159+
(byte) 1, // do not return null for the enum value
160+
1, // pickValue index (BAR)
161+
90, // remainingBytes after first element creation
162+
// sizeOfElementEstimate = 100 - 90 = 10
163+
// consumeArrayLength(data, 10) = remainingBytes / 2 / 10
164+
// need this to return 1: 20 / 2 / 10 = 1
165+
20)); // remainingBytes for outer consumeArrayLength
166+
128167
byte[] testInputStreamBytes = new byte[] {(byte) 1, (byte) 2, (byte) 3};
129168
consumeTestCase(
130169
new ByteArrayInputStream(testInputStreamBytes),
@@ -136,7 +175,7 @@ public void testConsume() throws NoSuchMethodException {
136175

137176
consumeTestCase(
138177
TestEnum.BAR,
139-
String.format("%s.%s", TestEnum.class.getName(), TestEnum.BAR.name()),
178+
String.format("%s.%s", TestEnum.class.getCanonicalName(), TestEnum.BAR.name()),
140179
Arrays.asList(
141180
(byte) 1, // do not return null for the enum value
142181
1 /* second value */));

tests/BUILD.bazel

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,23 @@ java_fuzz_target_test(
555555
],
556556
)
557557

558+
java_library(
559+
name = "autofuzz_multi_dim_array_target",
560+
srcs = ["src/test/java/com/example/AutofuzzMultiDimArrayTarget.java"],
561+
)
562+
563+
# Regression test for https://github.com/CodeIntelligenceTesting/jazzer/issues/1026.
564+
java_fuzz_target_test(
565+
name = "AutofuzzMultiDimArrayFuzzer",
566+
allowed_findings = ["java.lang.RuntimeException"],
567+
fuzzer_args = [
568+
"--autofuzz=com.example.AutofuzzMultiDimArrayTarget::new",
569+
],
570+
runtime_deps = [
571+
":autofuzz_multi_dim_array_target",
572+
],
573+
)
574+
558575
java_fuzz_target_test(
559576
name = "SilencedFuzzer",
560577
timeout = "short",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
// Regression test for https://github.com/CodeIntelligenceTesting/jazzer/issues/1026.
20+
// It also uses a static inner class array parameter to verify that the reproducer codegen uses
21+
// getCanonicalName() (dot-separated) rather than getName()/getTypeName() (which use '$'
22+
// for inner classes and are not valid Java source).
23+
public class AutofuzzMultiDimArrayTarget {
24+
public static class Item {
25+
public Item(int value) {}
26+
}
27+
28+
public AutofuzzMultiDimArrayTarget(int[][] grid, Item[] items) {
29+
if (grid != null && grid.length > 3 && items != null && items.length > 3) {
30+
throw new RuntimeException();
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)