1 // Copyright 2021 Code Intelligence GmbH 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package com.code_intelligence.jazzer.api; 16 17 import java.io.*; 18 import java.util.ArrayList; 19 import java.util.Base64; 20 import java.util.Iterator; 21 import java.util.List; 22 23 /** 24 * Replays recorded FuzzedDataProvider invocations that were executed while fuzzing. 25 * Note: This class is only meant to be used by Jazzer's generated reproducers. 26 */ 27 final public class CannedFuzzedDataProvider implements FuzzedDataProvider { 28 private final Iterator<Object> nextReply; 29 CannedFuzzedDataProvider(String can)30 public CannedFuzzedDataProvider(String can) { 31 byte[] rawIn = Base64.getDecoder().decode(can); 32 ArrayList<Object> recordedReplies; 33 try (ByteArrayInputStream byteStream = new ByteArrayInputStream(rawIn)) { 34 try (ObjectInputStream objectStream = new ObjectInputStream(byteStream)) { 35 recordedReplies = (ArrayList<Object>) objectStream.readObject(); 36 } 37 } catch (IOException | ClassNotFoundException e) { 38 throw new RuntimeException(e); 39 } 40 nextReply = recordedReplies.iterator(); 41 } 42 create(List<Object> objects)43 public static CannedFuzzedDataProvider create(List<Object> objects) { 44 try { 45 try (ByteArrayOutputStream bout = new ByteArrayOutputStream()) { 46 try (ObjectOutputStream out = new ObjectOutputStream(bout)) { 47 out.writeObject(new ArrayList<>(objects)); 48 String base64 = Base64.getEncoder().encodeToString(bout.toByteArray()); 49 return new CannedFuzzedDataProvider(base64); 50 } 51 } 52 } catch (IOException e) { 53 throw new IllegalStateException(e); 54 } 55 } 56 57 @Override consumeBoolean()58 public boolean consumeBoolean() { 59 return (boolean) nextReply.next(); 60 } 61 62 @Override consumeBooleans(int maxLength)63 public boolean[] consumeBooleans(int maxLength) { 64 return (boolean[]) nextReply.next(); 65 } 66 67 @Override consumeByte()68 public byte consumeByte() { 69 return (byte) nextReply.next(); 70 } 71 72 @Override consumeByte(byte min, byte max)73 public byte consumeByte(byte min, byte max) { 74 return (byte) nextReply.next(); 75 } 76 77 @Override consumeShort()78 public short consumeShort() { 79 return (short) nextReply.next(); 80 } 81 82 @Override consumeShort(short min, short max)83 public short consumeShort(short min, short max) { 84 return (short) nextReply.next(); 85 } 86 87 @Override consumeShorts(int maxLength)88 public short[] consumeShorts(int maxLength) { 89 return (short[]) nextReply.next(); 90 } 91 92 @Override consumeInt()93 public int consumeInt() { 94 return (int) nextReply.next(); 95 } 96 97 @Override consumeInt(int min, int max)98 public int consumeInt(int min, int max) { 99 return (int) nextReply.next(); 100 } 101 102 @Override consumeInts(int maxLength)103 public int[] consumeInts(int maxLength) { 104 return (int[]) nextReply.next(); 105 } 106 107 @Override consumeLong()108 public long consumeLong() { 109 return (long) nextReply.next(); 110 } 111 112 @Override consumeLong(long min, long max)113 public long consumeLong(long min, long max) { 114 return (long) nextReply.next(); 115 } 116 117 @Override consumeLongs(int maxLength)118 public long[] consumeLongs(int maxLength) { 119 return (long[]) nextReply.next(); 120 } 121 122 @Override consumeFloat()123 public float consumeFloat() { 124 return (float) nextReply.next(); 125 } 126 127 @Override consumeRegularFloat()128 public float consumeRegularFloat() { 129 return (float) nextReply.next(); 130 } 131 132 @Override consumeRegularFloat(float min, float max)133 public float consumeRegularFloat(float min, float max) { 134 return (float) nextReply.next(); 135 } 136 137 @Override consumeProbabilityFloat()138 public float consumeProbabilityFloat() { 139 return (float) nextReply.next(); 140 } 141 142 @Override consumeDouble()143 public double consumeDouble() { 144 return (double) nextReply.next(); 145 } 146 147 @Override consumeRegularDouble(double min, double max)148 public double consumeRegularDouble(double min, double max) { 149 return (double) nextReply.next(); 150 } 151 152 @Override consumeRegularDouble()153 public double consumeRegularDouble() { 154 return (double) nextReply.next(); 155 } 156 157 @Override consumeProbabilityDouble()158 public double consumeProbabilityDouble() { 159 return (double) nextReply.next(); 160 } 161 162 @Override consumeChar()163 public char consumeChar() { 164 return (char) nextReply.next(); 165 } 166 167 @Override consumeChar(char min, char max)168 public char consumeChar(char min, char max) { 169 return (char) nextReply.next(); 170 } 171 172 @Override consumeCharNoSurrogates()173 public char consumeCharNoSurrogates() { 174 return (char) nextReply.next(); 175 } 176 177 @Override consumeAsciiString(int maxLength)178 public String consumeAsciiString(int maxLength) { 179 return (String) nextReply.next(); 180 } 181 182 @Override consumeString(int maxLength)183 public String consumeString(int maxLength) { 184 return (String) nextReply.next(); 185 } 186 187 @Override consumeRemainingAsAsciiString()188 public String consumeRemainingAsAsciiString() { 189 return (String) nextReply.next(); 190 } 191 192 @Override consumeRemainingAsString()193 public String consumeRemainingAsString() { 194 return (String) nextReply.next(); 195 } 196 197 @Override consumeBytes(int maxLength)198 public byte[] consumeBytes(int maxLength) { 199 return (byte[]) nextReply.next(); 200 } 201 202 @Override consumeRemainingAsBytes()203 public byte[] consumeRemainingAsBytes() { 204 return (byte[]) nextReply.next(); 205 } 206 207 @Override remainingBytes()208 public int remainingBytes() { 209 return (int) nextReply.next(); 210 } 211 } 212