Skip to content

Commit e62234d

Browse files
committed
feat: decode bytes as CESU-8 when converting to char[]
1 parent 683af30 commit e62234d

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

src/main/java/com/code_intelligence/jazzer/mutation/mutator/lang/PrimitiveArrayMutatorFactory.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.lang.reflect.AnnotatedArrayType;
4343
import java.lang.reflect.AnnotatedType;
4444
import java.nio.ByteBuffer;
45+
import java.nio.charset.Charset;
4546
import java.util.Optional;
4647
import java.util.function.BiFunction;
4748
import java.util.function.Function;
@@ -71,6 +72,7 @@ public Optional<SerializingMutator<?>> tryCreate(
7172
public static final class PrimitiveArrayMutator<T> extends SerializingMutator<T> {
7273
private static final int DEFAULT_MIN_LENGTH = 0;
7374
private static final int DEFAULT_MAX_LENGTH = 1000;
75+
private static final Charset FUZZED_DATA_CHARSET = Charset.forName("CESU-8");
7476
private long minRange;
7577
private long maxRange;
7678
private boolean allowNaN;
@@ -253,16 +255,16 @@ private static AnnotatedType convertWithLength(AnnotatedType type, AnnotatedType
253255
}
254256
}
255257

256-
// Randomly maps the byte array from libFuzzer directly onto char[] or converts each byte into a
257-
// 2 byte char. This helps in cases where a String is constructed out of char[] and libFuzzer
258-
// inserts CESU8 encoded bytes into the byte[].
258+
// The strings we pass to native callbacks to trace data flow are CESU-8 encoded.
259+
// As a result, libFuzzer's TORC contains CESU-8 encoded strings.
260+
// Therefore, in 50% of times we decode the byte array as a CESU-8 string.
259261
public char[] postMutateChars(byte[] bytes, PseudoRandom prng) {
260262
if (prng.choice()) {
261263
return (char[]) toPrimitive.apply(bytes);
262264
} else {
263-
char[] chars = new char[bytes.length];
265+
char[] chars = new String(bytes, FUZZED_DATA_CHARSET).toCharArray();
264266
for (int i = 0; i < chars.length; i++) {
265-
chars[i] = (char) bytes[i];
267+
chars[i] = (char) forceInRange(chars[i], minRange, maxRange);
266268
}
267269
return chars;
268270
}

tests/src/test/java/com/example/CharArrayFuzzer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public static void fuzzerTestOneInput(char[] data) {
2222
return;
2323
}
2424
String expression = new String(data);
25-
if (expression.contains("jazzer")) {
26-
throw new RuntimeException("found jazzer");
25+
if (expression.equals("中 Bös3r \uD801\uDC00 C0d3 中")) {
26+
throw new RuntimeException("Found evil code");
2727
}
2828
}
2929
}

0 commit comments

Comments
 (0)