mirror of https://github.com/google/oss-fuzz.git
jackson-databind: Improve fuzzers (#8807)
1. Add more target APIs 2. Group target types together 3. Add more settings Signed-off-by: AdamKorcz <adam@adalogics.com> Signed-off-by: AdamKorcz <adam@adalogics.com>
This commit is contained in:
parent
dc3a4df805
commit
f7cd9410c9
|
@ -20,20 +20,37 @@ import java.util.*;
|
|||
import java.util.regex.Pattern;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.EOFException;
|
||||
import java.lang.IllegalArgumentException;
|
||||
import java.net.URI;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.TreeNode;
|
||||
import com.fasterxml.jackson.core.filter.TokenFilter;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import java.lang.ClassCastException;
|
||||
|
||||
// For NoCheckSubTypeValidator
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.cfg.MapperConfig;
|
||||
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
|
||||
|
||||
public class AdaLObjectReader3Fuzzer {
|
||||
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
|
||||
|
@ -47,6 +64,55 @@ public class AdaLObjectReader3Fuzzer {
|
|||
ObjectReader r, r2, r3;
|
||||
JsonParser jp;
|
||||
|
||||
MapperFeature[] mapperfeatures = new MapperFeature[]{MapperFeature.AUTO_DETECT_CREATORS,
|
||||
MapperFeature.AUTO_DETECT_FIELDS,
|
||||
MapperFeature.AUTO_DETECT_GETTERS,
|
||||
MapperFeature.AUTO_DETECT_IS_GETTERS,
|
||||
MapperFeature.AUTO_DETECT_SETTERS,
|
||||
MapperFeature.REQUIRE_SETTERS_FOR_GETTERS,
|
||||
MapperFeature.USE_GETTERS_AS_SETTERS,
|
||||
MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES,
|
||||
MapperFeature.INFER_PROPERTY_MUTATORS,
|
||||
MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS,
|
||||
MapperFeature.ALLOW_VOID_VALUED_PROPERTIES,
|
||||
MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS,
|
||||
MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS,
|
||||
MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,
|
||||
MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES,
|
||||
MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING,
|
||||
MapperFeature.USE_STD_BEAN_NAMING,
|
||||
MapperFeature.ALLOW_COERCION_OF_SCALARS,
|
||||
MapperFeature.DEFAULT_VIEW_INCLUSION,
|
||||
MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS,
|
||||
MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE,
|
||||
MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL,
|
||||
MapperFeature.USE_STATIC_TYPING,
|
||||
MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES};
|
||||
|
||||
SerializationFeature[] serializationfeatures = new SerializationFeature[]{SerializationFeature.INDENT_OUTPUT,
|
||||
SerializationFeature.CLOSE_CLOSEABLE,
|
||||
SerializationFeature.WRAP_ROOT_VALUE,
|
||||
SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,
|
||||
SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,
|
||||
SerializationFeature.WRITE_ENUMS_USING_TO_STRING,
|
||||
SerializationFeature.WRITE_ENUMS_USING_INDEX,
|
||||
SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,
|
||||
SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,
|
||||
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,
|
||||
SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID,
|
||||
SerializationFeature.FAIL_ON_EMPTY_BEANS,
|
||||
SerializationFeature.WRAP_EXCEPTIONS,
|
||||
SerializationFeature.FLUSH_AFTER_WRITE_VALUE,
|
||||
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
|
||||
SerializationFeature.WRITE_NULL_MAP_VALUES,
|
||||
SerializationFeature.WRITE_EMPTY_JSON_ARRAYS,
|
||||
SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,
|
||||
SerializationFeature.EAGER_SERIALIZER_FETCH};
|
||||
|
||||
DeserializationFeature[] deserializationfeatures = new DeserializationFeature[]{DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,
|
||||
DeserializationFeature.USE_BIG_INTEGER_FOR_INTS,
|
||||
DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY,
|
||||
|
@ -73,9 +139,59 @@ public class AdaLObjectReader3Fuzzer {
|
|||
DeserializationFeature.FAIL_ON_TRAILING_TOKENS,
|
||||
DeserializationFeature.EAGER_DESERIALIZER_FETCH};
|
||||
|
||||
ObjectMapper.DefaultTyping[] typings = new ObjectMapper.DefaultTyping[]{ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT,
|
||||
ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE,
|
||||
ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS,
|
||||
ObjectMapper.DefaultTyping.NON_FINAL,
|
||||
ObjectMapper.DefaultTyping.EVERYTHING};
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
// Maybe create a mapper with different typing settings. Let the fuzzer decide
|
||||
doThis = data.consumeBoolean();
|
||||
if (doThis) {
|
||||
JsonMapper.Builder b = JsonMapper.builder();
|
||||
|
||||
for (int i = 0; i < typings.length; i++) {
|
||||
if (data.consumeBoolean()) {
|
||||
b.activateDefaultTyping(NoCheckSubTypeValidator.instance, typings[i]);
|
||||
}
|
||||
}
|
||||
mapper = b.build();
|
||||
}
|
||||
|
||||
for (int i = 0; i < mapperfeatures.length; i++) {
|
||||
if (data.consumeBoolean()) {
|
||||
mapper.enable(mapperfeatures[i]);
|
||||
} else {
|
||||
mapper.disable(mapperfeatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < serializationfeatures.length; i++) {
|
||||
if (data.consumeBoolean()) {
|
||||
mapper.enable(serializationfeatures[i]);
|
||||
} else {
|
||||
mapper.disable(serializationfeatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int idx = data.consumeInt(0, classes.length - 1);
|
||||
r = mapper.readerFor(classes[idx]);
|
||||
r = mapper.readerFor(classes[idx]); // To initialize-
|
||||
switch (data.consumeInt(0, 4)) {
|
||||
case 0:
|
||||
r = mapper.readerFor(classes[idx]);
|
||||
case 1:
|
||||
r = mapper.readerForMapOf(classes[idx]);
|
||||
case 2:
|
||||
r = mapper.readerForListOf(classes[idx]);
|
||||
case 3:
|
||||
r = mapper.readerForArrayOf(classes[idx]);
|
||||
case 4:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
r = r.forType(mapper.constructType(classes[fuzzInt1]));
|
||||
}
|
||||
|
||||
// set reader settings
|
||||
for (int i = 0; i < deserializationfeatures.length; i++) {
|
||||
|
@ -87,102 +203,214 @@ public class AdaLObjectReader3Fuzzer {
|
|||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < data.consumeInt(); i++) {
|
||||
// Select a method and call it
|
||||
int callType = data.consumeInt();
|
||||
switch (callType%19) {
|
||||
// Select a method and call it
|
||||
int callType = data.consumeInt();
|
||||
switch (callType%7) {
|
||||
case 0:
|
||||
// readValue
|
||||
switch (data.consumeInt(0, 12)){
|
||||
case 0:
|
||||
r.readValue(data.consumeString(100000));
|
||||
case 1:
|
||||
r.readValue(data.consumeBytes(100000));
|
||||
r.readValue(new MockFuzzDataInput(data.consumeString(100000)));
|
||||
case 2:
|
||||
r.readTree(data.consumeString(100000));
|
||||
r.readValue(data.consumeBytes(100000));
|
||||
case 3:
|
||||
r.readTree(data.consumeBytes(100000));
|
||||
case 4:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeBytes(100000));
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readValue(jp);
|
||||
doThis = data.consumeBoolean();
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 4:
|
||||
jp = _createParser(data, mapper, r);
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
r.readValue(jp, mapper.constructType(classes[fuzzInt1]));
|
||||
case 5:
|
||||
stringR = new StringReader(new String(data.consumeBytes(100000)));
|
||||
r.readValue(stringR);
|
||||
jp = _createParser(data, mapper, r);
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
r.readValue(jp, classes[fuzzInt1]);
|
||||
case 6:
|
||||
stringR = new StringReader(new String(data.consumeBytes(100000)));
|
||||
r.readValues(stringR);
|
||||
r.readValue(stringR);
|
||||
case 7:
|
||||
r.readValues(data.consumeRemainingAsString());
|
||||
case 8:
|
||||
r.readValue(data.consumeBytes(100000));
|
||||
case 9:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeBytes(100000));
|
||||
o = r.readValues(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 10:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeBytes(100000));
|
||||
o = r.readTree(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 11:
|
||||
stringR = new StringReader(new String(data.consumeBytes(100000)));
|
||||
r.readTree(stringR);
|
||||
case 12:
|
||||
fileData = data.consumeBytes(100000);
|
||||
fileData = data.consumeRemainingAsBytes();
|
||||
out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
r.readValue(new File("fuzzFile"));
|
||||
case 8:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
r.readValue(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 9:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
r.readValue(data.consumeBytes(100000), classes[idx]);
|
||||
case 10:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
r.readValue(data.consumeString(100000), classes[idx]);
|
||||
case 11:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeBytes(1000000), data.consumeInt(), data.consumeInt(), classes[fuzzInt1]);
|
||||
case 12:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeBytes(1000000), mapper.constructType(classes[fuzzInt1]));
|
||||
case 13:
|
||||
fileData = data.consumeBytes(100000);
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeString(1000000), mapper.constructType(classes[fuzzInt1]));
|
||||
}
|
||||
case 1:
|
||||
// readTree
|
||||
switch (data.consumeInt(0, 6)){
|
||||
case 0:
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readTree(jp);
|
||||
if (data.consumeBoolean()) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 1:
|
||||
r.readTree(data.consumeString(100000));
|
||||
case 2:
|
||||
r.readTree(data.consumeBytes(100000));
|
||||
case 3:
|
||||
stringR = new StringReader(new String(data.consumeRemainingAsBytes()));
|
||||
r.readTree(stringR);
|
||||
case 4:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
r.readTree(data.consumeRemainingAsBytes(), fuzzInt1, fuzzInt2);
|
||||
case 5:
|
||||
mapper.readTree(data.consumeBytes(1000000));
|
||||
case 6:
|
||||
mapper.readTree(data.consumeString(1000000));
|
||||
case 7:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
switch (data.consumeInt(0,1)) {
|
||||
case 0:
|
||||
r.readValue(data.consumeRemainingAsBytes(), classes[fuzzInt1]);
|
||||
case 1:
|
||||
r.readValue(data.consumeRemainingAsString(), classes[fuzzInt1]);
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
// readValues
|
||||
switch (data.consumeInt(0, 7)){
|
||||
case 0:
|
||||
stringR = new StringReader(new String(data.consumeRemainingAsBytes()));
|
||||
r.readValues(stringR);
|
||||
case 1:
|
||||
r.readValues(data.consumeRemainingAsString());
|
||||
case 2:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readValues(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 3:
|
||||
fileData = data.consumeRemainingAsBytes();
|
||||
out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
r.readValues(new File("fuzzFile"));
|
||||
case 14:
|
||||
fileData = data.consumeBytes(100000);
|
||||
out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
jp = r.createParser(new File("fuzzFile"));
|
||||
o = r.readTree(jp);
|
||||
case 15:
|
||||
case 4:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
r.readValue(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 16:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
r.readValues(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 17:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
r.readTree(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 18:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
jp = r.createParser(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
r.readValues(data.consumeBytes(1000000), fuzzInt1, fuzzInt2);
|
||||
case 5:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
jp = _createParser(data, mapper, r);
|
||||
mapper.readValues(jp, mapper.constructType(classes[fuzzInt1]));
|
||||
case 6:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
jp = _createParser(data, mapper, r);
|
||||
mapper.readValues(jp, classes[fuzzInt1]);
|
||||
case 7:
|
||||
r.readValues(new MockFuzzDataInput(data.consumeString(1000000)));
|
||||
}
|
||||
|
||||
// target with();
|
||||
if (data.consumeBoolean()) {
|
||||
JsonFactory jf = new JsonFactory();
|
||||
r2 = r.with(jf);
|
||||
case 3:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
fuzzInt2 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.addMixIn(classes[fuzzInt1], classes[fuzzInt2]);
|
||||
case 4:
|
||||
JsonNode tree = mapper.readTree(data.consumeString(1000000));
|
||||
JsonNode node = tree.at(data.consumeString(1000000));
|
||||
doThis = data.consumeBoolean();
|
||||
if (doThis) {
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.treeToValue(node, classes[fuzzInt1]);
|
||||
}
|
||||
doThis = data.consumeBoolean();
|
||||
if (doThis) {
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.treeToValue(node, mapper.constructType(classes[fuzzInt1]));
|
||||
}
|
||||
doThis = data.consumeBoolean();
|
||||
if (doThis) {
|
||||
r.readValue(node);
|
||||
}
|
||||
doThis = data.consumeBoolean();
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
if (doThis) {
|
||||
r.readValue(node, classes[fuzzInt1]);
|
||||
}
|
||||
case 5:
|
||||
switch (data.consumeInt(0, 1)){
|
||||
case 0:
|
||||
mapper.readTree(new ByteArrayInputStream(data.consumeBytes(100000)));
|
||||
case 1:
|
||||
ObjectNode src = (ObjectNode) mapper.readTree(data.consumeString(100000));
|
||||
TreeNode tn = src;
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.treeToValue(tn, classes[fuzzInt1]);
|
||||
case 2:
|
||||
r.readTree(new MockFuzzDataInput(data.consumeString(100000)));
|
||||
}
|
||||
case 6:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.canSerialize(classes[fuzzInt1]);
|
||||
}
|
||||
} catch (IOException | IllegalArgumentException e) { }
|
||||
|
||||
// target with();
|
||||
if (data.consumeBoolean()) {
|
||||
JsonFactory jf = new JsonFactory();
|
||||
r2 = r.with(jf);
|
||||
}
|
||||
} catch (IOException | IllegalArgumentException | ClassCastException e) { }
|
||||
|
||||
try {
|
||||
Files.delete(Paths.get("fuzzFile"));
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public static JsonParser _createParser(FuzzedDataProvider data, ObjectMapper mapper, ObjectReader r) throws IOException {
|
||||
int fuzzInt1, fuzzInt2;
|
||||
byte[] fileData;
|
||||
switch (data.consumeInt(0, 6)) {
|
||||
case 0:
|
||||
return r.createParser(data.consumeBytes(100000));
|
||||
case 1:
|
||||
fileData = data.consumeBytes(100000);
|
||||
FileOutputStream out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
return r.createParser(new File("fuzzFile"));
|
||||
case 2:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
return r.createParser(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 3:
|
||||
mapper.createParser(data.consumeBytes(100000));
|
||||
case 4:
|
||||
return mapper.createParser(data.consumeString(1000000));
|
||||
case 5:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
return mapper.createParser(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
}
|
||||
return r.createParser(data.consumeBytes(100000));
|
||||
}
|
||||
|
||||
public static Class[] classes = { DummyClass.class, Integer.class, String.class, Byte.class, List.class, Map.class,
|
||||
TreeMap.class, BitSet.class, TimeZone.class, Date.class, Calendar.class, Locale.class, Long.class };
|
||||
|
||||
|
@ -215,4 +443,127 @@ public class AdaLObjectReader3Fuzzer {
|
|||
public Long _long;
|
||||
public Double _double;
|
||||
}
|
||||
|
||||
|
||||
// Test util classes
|
||||
public static final class NoCheckSubTypeValidator
|
||||
extends PolymorphicTypeValidator.Base
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final NoCheckSubTypeValidator instance = new NoCheckSubTypeValidator();
|
||||
|
||||
@Override
|
||||
public Validity validateBaseType(MapperConfig<?> config, JavaType baseType) {
|
||||
return Validity.INDETERMINATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validity validateSubClassName(MapperConfig<?> config,
|
||||
JavaType baseType, String subClassName) {
|
||||
return Validity.ALLOWED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validity validateSubType(MapperConfig<?> config, JavaType baseType,
|
||||
JavaType subType) {
|
||||
return Validity.ALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MockFuzzDataInput implements DataInput
|
||||
{
|
||||
private final InputStream _input;
|
||||
|
||||
public MockFuzzDataInput(byte[] data) {
|
||||
_input = new ByteArrayInputStream(data);
|
||||
}
|
||||
|
||||
public MockFuzzDataInput(String utf8Data) throws IOException {
|
||||
_input = new ByteArrayInputStream(utf8Data.getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
public MockFuzzDataInput(InputStream in) {
|
||||
_input = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFully(byte[] b, int off, int len) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skipBytes(int n) throws IOException {
|
||||
return (int) _input.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() throws IOException {
|
||||
int ch = _input.read();
|
||||
if (ch < 0) {
|
||||
throw new EOFException("End-of-input for readByte()");
|
||||
}
|
||||
return (byte) ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedByte() throws IOException {
|
||||
return readByte() & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUnsignedShort() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char readChar() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readUTF() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,18 @@ public class ObjectReader2Fuzzer {
|
|||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
int idx = data.consumeInt(0, classes.length - 1);
|
||||
r = mapper.readerFor(classes[idx]);
|
||||
r = mapper.readerFor(classes[idx]); // To initialize
|
||||
switch (data.consumeInt(0, 3)) {
|
||||
case 0:
|
||||
r = mapper.readerFor(classes[idx]);
|
||||
case 1:
|
||||
r = mapper.readerForMapOf(classes[idx]);
|
||||
case 2:
|
||||
r = mapper.readerForListOf(classes[idx]);
|
||||
case 3:
|
||||
r = mapper.readerForArrayOf(classes[idx]);
|
||||
|
||||
}
|
||||
|
||||
// set reader settings
|
||||
for (int i = 0; i < deserializationfeatures.length; i++) {
|
||||
|
@ -88,7 +99,7 @@ public class ObjectReader2Fuzzer {
|
|||
try {
|
||||
// Select a method and call it
|
||||
int callType = data.consumeInt();
|
||||
switch (callType%19) {
|
||||
switch (callType%23) {
|
||||
case 0:
|
||||
r.readValue(data.consumeRemainingAsString());
|
||||
case 1:
|
||||
|
@ -99,7 +110,7 @@ public class ObjectReader2Fuzzer {
|
|||
r.readTree(data.consumeRemainingAsBytes());
|
||||
case 4:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeRemainingAsBytes());
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readValue(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
|
@ -116,14 +127,14 @@ public class ObjectReader2Fuzzer {
|
|||
r.readValue(data.consumeRemainingAsBytes());
|
||||
case 9:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeRemainingAsBytes());
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readValues(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
}
|
||||
case 10:
|
||||
doThis = data.consumeBoolean();
|
||||
jp = r.createParser(data.consumeRemainingAsBytes());
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readTree(jp);
|
||||
if (doThis) {
|
||||
r3 = r.withValueToUpdate(o);
|
||||
|
@ -144,11 +155,7 @@ public class ObjectReader2Fuzzer {
|
|||
out.close();
|
||||
r.readValues(new File("fuzzFile"));
|
||||
case 14:
|
||||
fileData = data.consumeRemainingAsBytes();
|
||||
out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
jp = r.createParser(new File("fuzzFile"));
|
||||
jp = _createParser(data, mapper, r);
|
||||
o = r.readTree(jp);
|
||||
case 15:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
|
@ -163,9 +170,24 @@ public class ObjectReader2Fuzzer {
|
|||
fuzzInt2 = data.consumeInt();
|
||||
r.readTree(data.consumeRemainingAsBytes(), fuzzInt1, fuzzInt2);
|
||||
case 18:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
jp = r.createParser(data.consumeRemainingAsBytes(), fuzzInt1, fuzzInt2);
|
||||
jp = _createParser(data, mapper, r);
|
||||
case 19:
|
||||
int idx2 = data.consumeInt(0, classes.length - 1);
|
||||
switch (data.consumeInt()%4) {
|
||||
case 0:
|
||||
r.readValue(data.consumeRemainingAsBytes(), classes[idx]);
|
||||
case 1:
|
||||
r.readValue(data.consumeRemainingAsString(), classes[idx]);
|
||||
}
|
||||
case 20:
|
||||
fuzzInt1 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeBytes(1000000), data.consumeInt(), data.consumeInt(), classes[fuzzInt1]);
|
||||
case 21:
|
||||
int idx3 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeBytes(1000000), mapper.constructType(classes[idx]));
|
||||
case 22:
|
||||
int idx4 = data.consumeInt(0, classes.length - 1);
|
||||
mapper.readValue(data.consumeString(1000000), mapper.constructType(classes[idx]));
|
||||
}
|
||||
|
||||
// target with();
|
||||
|
@ -180,6 +202,34 @@ public class ObjectReader2Fuzzer {
|
|||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
public static JsonParser _createParser(FuzzedDataProvider data, ObjectMapper mapper, ObjectReader r) throws IOException {
|
||||
int fuzzInt1, fuzzInt2;
|
||||
byte[] fileData;
|
||||
switch (data.consumeInt(0, 5)) {
|
||||
case 0:
|
||||
return r.createParser(data.consumeBytes(100000));
|
||||
case 1:
|
||||
fileData = data.consumeBytes(100000);
|
||||
FileOutputStream out = new FileOutputStream("fuzzFile");
|
||||
out.write(fileData);
|
||||
out.close();
|
||||
return r.createParser(new File("fuzzFile"));
|
||||
case 2:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
return r.createParser(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
case 3:
|
||||
mapper.createParser(data.consumeBytes(100000));
|
||||
case 4:
|
||||
return mapper.createParser(data.consumeString(1000000));
|
||||
case 5:
|
||||
fuzzInt1 = data.consumeInt();
|
||||
fuzzInt2 = data.consumeInt();
|
||||
return mapper.createParser(data.consumeBytes(100000), fuzzInt1, fuzzInt2);
|
||||
}
|
||||
return r.createParser(data.consumeBytes(100000));
|
||||
}
|
||||
|
||||
public static Class[] classes = { DummyClass.class, Integer.class, String.class, Byte.class, List.class, Map.class,
|
||||
TreeMap.class, BitSet.class, TimeZone.class, Date.class, Calendar.class, Locale.class, Long.class, File.class,
|
||||
Charset.class, URI.class };
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
|
@ -63,6 +65,55 @@ public class ObjectReaderRandomClassFuzzer {
|
|||
return;
|
||||
}
|
||||
|
||||
MapperFeature[] mapperfeatures = new MapperFeature[]{MapperFeature.AUTO_DETECT_CREATORS,
|
||||
MapperFeature.AUTO_DETECT_FIELDS,
|
||||
MapperFeature.AUTO_DETECT_GETTERS,
|
||||
MapperFeature.AUTO_DETECT_IS_GETTERS,
|
||||
MapperFeature.AUTO_DETECT_SETTERS,
|
||||
MapperFeature.REQUIRE_SETTERS_FOR_GETTERS,
|
||||
MapperFeature.USE_GETTERS_AS_SETTERS,
|
||||
MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES,
|
||||
MapperFeature.INFER_PROPERTY_MUTATORS,
|
||||
MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS,
|
||||
MapperFeature.ALLOW_VOID_VALUED_PROPERTIES,
|
||||
MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS,
|
||||
MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS,
|
||||
MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,
|
||||
MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES,
|
||||
MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES,
|
||||
MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING,
|
||||
MapperFeature.USE_STD_BEAN_NAMING,
|
||||
MapperFeature.ALLOW_COERCION_OF_SCALARS,
|
||||
MapperFeature.DEFAULT_VIEW_INCLUSION,
|
||||
MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS,
|
||||
MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE,
|
||||
MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL,
|
||||
MapperFeature.USE_STATIC_TYPING,
|
||||
MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES};
|
||||
|
||||
SerializationFeature[] serializationfeatures = new SerializationFeature[]{SerializationFeature.INDENT_OUTPUT,
|
||||
SerializationFeature.CLOSE_CLOSEABLE,
|
||||
SerializationFeature.WRAP_ROOT_VALUE,
|
||||
SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,
|
||||
SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,
|
||||
SerializationFeature.WRITE_ENUMS_USING_TO_STRING,
|
||||
SerializationFeature.WRITE_ENUMS_USING_INDEX,
|
||||
SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED,
|
||||
SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,
|
||||
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,
|
||||
SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID,
|
||||
SerializationFeature.FAIL_ON_EMPTY_BEANS,
|
||||
SerializationFeature.WRAP_EXCEPTIONS,
|
||||
SerializationFeature.FLUSH_AFTER_WRITE_VALUE,
|
||||
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
|
||||
SerializationFeature.WRITE_NULL_MAP_VALUES,
|
||||
SerializationFeature.WRITE_EMPTY_JSON_ARRAYS,
|
||||
SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,
|
||||
SerializationFeature.EAGER_SERIALIZER_FETCH};
|
||||
|
||||
DeserializationFeature[] deserializationfeatures = new DeserializationFeature[]{DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,
|
||||
DeserializationFeature.USE_BIG_INTEGER_FOR_INTS,
|
||||
DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY,
|
||||
|
@ -105,6 +156,22 @@ public class ObjectReaderRandomClassFuzzer {
|
|||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
for (int i = 0; i < mapperfeatures.length; i++) {
|
||||
if (data.consumeBoolean()) {
|
||||
mapper.enable(mapperfeatures[i]);
|
||||
} else {
|
||||
mapper.disable(mapperfeatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < serializationfeatures.length; i++) {
|
||||
if (data.consumeBoolean()) {
|
||||
mapper.enable(serializationfeatures[i]);
|
||||
} else {
|
||||
mapper.disable(serializationfeatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
///////////////////////////
|
||||
// Create a random class //
|
||||
|
|
|
@ -63,6 +63,10 @@ for fuzzer in $(find $SRC -name '*Fuzzer.java'); do
|
|||
if [ "$fuzzer_basename" != "ObjectReaderRandomClassFuzzer" ]; then
|
||||
cp $SRC/$fuzzer_basename\$DummyClass.class $OUT/
|
||||
fi
|
||||
if [ "$fuzzer_basename" == "AdaLObjectReader3Fuzzer" ]; then
|
||||
cp $SRC/$fuzzer_basename\$NoCheckSubTypeValidator.class $OUT/
|
||||
cp $SRC/$fuzzer_basename\$MockFuzzDataInput.class $OUT/
|
||||
fi
|
||||
|
||||
# Create an execution wrapper that executes Jazzer with the correct arguments.
|
||||
echo "#!/bin/sh
|
||||
|
|
Loading…
Reference in New Issue