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