diff options
Diffstat (limited to 'agent/src/main/java/com/code_intelligence/jazzer/api/CannedFuzzedDataProvider.java')
-rw-r--r-- | agent/src/main/java/com/code_intelligence/jazzer/api/CannedFuzzedDataProvider.java | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/api/CannedFuzzedDataProvider.java b/agent/src/main/java/com/code_intelligence/jazzer/api/CannedFuzzedDataProvider.java new file mode 100644 index 00000000..7209a497 --- /dev/null +++ b/agent/src/main/java/com/code_intelligence/jazzer/api/CannedFuzzedDataProvider.java @@ -0,0 +1,211 @@ +// Copyright 2021 Code Intelligence GmbH +// +// 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. + +package com.code_intelligence.jazzer.api; + +import java.io.*; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Iterator; +import java.util.List; + +/** + * Replays recorded FuzzedDataProvider invocations that were executed while fuzzing. + * Note: This class is only meant to be used by Jazzer's generated reproducers. + */ +final public class CannedFuzzedDataProvider implements FuzzedDataProvider { + private final Iterator<Object> nextReply; + + public CannedFuzzedDataProvider(String can) { + byte[] rawIn = Base64.getDecoder().decode(can); + ArrayList<Object> recordedReplies; + try (ByteArrayInputStream byteStream = new ByteArrayInputStream(rawIn)) { + try (ObjectInputStream objectStream = new ObjectInputStream(byteStream)) { + recordedReplies = (ArrayList<Object>) objectStream.readObject(); + } + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + nextReply = recordedReplies.iterator(); + } + + public static CannedFuzzedDataProvider create(List<Object> objects) { + try { + try (ByteArrayOutputStream bout = new ByteArrayOutputStream()) { + try (ObjectOutputStream out = new ObjectOutputStream(bout)) { + out.writeObject(new ArrayList<>(objects)); + String base64 = Base64.getEncoder().encodeToString(bout.toByteArray()); + return new CannedFuzzedDataProvider(base64); + } + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Override + public boolean consumeBoolean() { + return (boolean) nextReply.next(); + } + + @Override + public boolean[] consumeBooleans(int maxLength) { + return (boolean[]) nextReply.next(); + } + + @Override + public byte consumeByte() { + return (byte) nextReply.next(); + } + + @Override + public byte consumeByte(byte min, byte max) { + return (byte) nextReply.next(); + } + + @Override + public short consumeShort() { + return (short) nextReply.next(); + } + + @Override + public short consumeShort(short min, short max) { + return (short) nextReply.next(); + } + + @Override + public short[] consumeShorts(int maxLength) { + return (short[]) nextReply.next(); + } + + @Override + public int consumeInt() { + return (int) nextReply.next(); + } + + @Override + public int consumeInt(int min, int max) { + return (int) nextReply.next(); + } + + @Override + public int[] consumeInts(int maxLength) { + return (int[]) nextReply.next(); + } + + @Override + public long consumeLong() { + return (long) nextReply.next(); + } + + @Override + public long consumeLong(long min, long max) { + return (long) nextReply.next(); + } + + @Override + public long[] consumeLongs(int maxLength) { + return (long[]) nextReply.next(); + } + + @Override + public float consumeFloat() { + return (float) nextReply.next(); + } + + @Override + public float consumeRegularFloat() { + return (float) nextReply.next(); + } + + @Override + public float consumeRegularFloat(float min, float max) { + return (float) nextReply.next(); + } + + @Override + public float consumeProbabilityFloat() { + return (float) nextReply.next(); + } + + @Override + public double consumeDouble() { + return (double) nextReply.next(); + } + + @Override + public double consumeRegularDouble(double min, double max) { + return (double) nextReply.next(); + } + + @Override + public double consumeRegularDouble() { + return (double) nextReply.next(); + } + + @Override + public double consumeProbabilityDouble() { + return (double) nextReply.next(); + } + + @Override + public char consumeChar() { + return (char) nextReply.next(); + } + + @Override + public char consumeChar(char min, char max) { + return (char) nextReply.next(); + } + + @Override + public char consumeCharNoSurrogates() { + return (char) nextReply.next(); + } + + @Override + public String consumeAsciiString(int maxLength) { + return (String) nextReply.next(); + } + + @Override + public String consumeString(int maxLength) { + return (String) nextReply.next(); + } + + @Override + public String consumeRemainingAsAsciiString() { + return (String) nextReply.next(); + } + + @Override + public String consumeRemainingAsString() { + return (String) nextReply.next(); + } + + @Override + public byte[] consumeBytes(int maxLength) { + return (byte[]) nextReply.next(); + } + + @Override + public byte[] consumeRemainingAsBytes() { + return (byte[]) nextReply.next(); + } + + @Override + public int remainingBytes() { + return (int) nextReply.next(); + } +} |