oss-fuzz/projects/spring-data-keyvalue/KeyValueTemplateFuzzer.java

158 lines
4.9 KiB
Java

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import lombok.Data;
import lombok.AllArgsConstructor;
import org.springframework.data.keyvalue.core.KeyValueTemplate;
import org.springframework.data.keyvalue.annotation.KeySpace;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.map.MapKeyValueAdapter;
import org.springframework.data.annotation.Id;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.annotation.Persistent;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.expression.spel.SpelParseException;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.keyvalue.core.UncategorizedKeyValueException;
public class KeyValueTemplateFuzzer {
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
String foo_id = data.consumeString(1000);
String bar_id = data.consumeString(1000);
String aliased_id = data.consumeString(1000);
String subclass_id = data.consumeString(1000);
String foo_input = data.consumeString(1000);
Foo foo = new Foo(foo_input);
Bar bar = new Bar(data.consumeString(1000));
ClassWithTypeAlias aliased = new ClassWithTypeAlias(data.consumeString(1000));
SubclassOfAliasedType subclass_of_aliased = new SubclassOfAliasedType(data.consumeString(1000));
KeyValueQuery<String> STRING_QUERY = new KeyValueQuery<>("foo == '" + foo_input + "'");
KeyValueTemplate operations = new KeyValueTemplate(new MapKeyValueAdapter());
try{
operations.insert(foo_id, foo);
operations.insert(bar_id, bar);
operations.insert(aliased_id, aliased);
operations.insert(subclass_id, subclass_of_aliased);
}
catch (DuplicateKeyException e){}
operations.update(foo_id, bar);
operations.findById(foo_id, Foo.class);
operations.findById(bar_id, Bar.class);
operations.findById(foo_id, Bar.class);
operations.findById(aliased_id, ClassWithTypeAlias.class);
try {
operations.find(new KeyValueQuery<>(data.consumeString(1000)), Foo.class);
}
//catching the Spel* exceptions because they are not the focus and essentially block the fuzzer
catch (DataRetrievalFailureException | SpelParseException | SpelEvaluationException | UncategorizedKeyValueException e){}
try {
operations.find(new KeyValueQuery<>(STRING_QUERY), Foo.class);
operations.find(new KeyValueQuery<>(STRING_QUERY), ClassWithTypeAlias.class);
operations.find(new KeyValueQuery<>(STRING_QUERY), SubclassOfAliasedType.class);
}
catch (DataRetrievalFailureException | UncategorizedKeyValueException e){}
operations.findAll(foo.getClass());
operations.findAll(aliased.getClass());
operations.findAll(subclass_of_aliased.getClass());
operations.delete(data.consumeString(1000), Foo.class);
operations.delete(foo_id, Foo.class);
}
@Data
@AllArgsConstructor
static class Foo {
String foo;
}
@Data
@AllArgsConstructor
static class Bar {
String bar;
}
@Data
static class ClassWithStringId implements Serializable {
private static final long serialVersionUID = -7481030649267602830L;
@Id String id;
String value;
}
@ExplicitKeySpace(name = "aliased")
@Data
static class ClassWithTypeAlias implements Serializable {
private static final long serialVersionUID = -5921943364908784571L;
@Id String id;
String name;
ClassWithTypeAlias(String name) {
this.name = name;
}
}
static class SubclassOfAliasedType extends ClassWithTypeAlias {
private static final long serialVersionUID = -468809596668871479L;
SubclassOfAliasedType(String name) {
super(name);
}
}
@KeySpace
@Persistent
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@interface ExplicitKeySpace {
@AliasFor(annotation = KeySpace.class, value = "value")
String name() default "";
}
}