// 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 nextReply; public CannedFuzzedDataProvider(String can) { byte[] rawIn = Base64.getDecoder().decode(can); ArrayList recordedReplies; try (ByteArrayInputStream byteStream = new ByteArrayInputStream(rawIn)) { try (ObjectInputStream objectStream = new ObjectInputStream(byteStream)) { recordedReplies = (ArrayList) objectStream.readObject(); } } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } nextReply = recordedReplies.iterator(); } public static CannedFuzzedDataProvider create(List 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(); } }