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.driver; 16 17 import com.code_intelligence.jazzer.api.CannedFuzzedDataProvider; 18 import com.code_intelligence.jazzer.api.FuzzedDataProvider; 19 import com.code_intelligence.jazzer.driver.RecordingFuzzedDataProvider; 20 import java.io.IOException; 21 import java.util.Arrays; 22 import java.util.stream.Collectors; 23 import java.util.stream.IntStream; 24 import java.util.stream.LongStream; 25 import org.junit.Assert; 26 import org.junit.Test; 27 28 public class RecordingFuzzedDataProviderTest { 29 @Test testRecordingFuzzedDataProvider()30 public void testRecordingFuzzedDataProvider() throws IOException { 31 FuzzedDataProvider mockData = new MockFuzzedDataProvider(); 32 String referenceResult = sampleFuzzTarget(mockData); 33 34 FuzzedDataProvider recordingMockData = 35 RecordingFuzzedDataProvider.makeFuzzedDataProviderProxy(mockData); 36 Assert.assertEquals(referenceResult, sampleFuzzTarget(recordingMockData)); 37 38 String cannedMockDataString = 39 RecordingFuzzedDataProvider.serializeFuzzedDataProviderProxy(recordingMockData); 40 FuzzedDataProvider cannedMockData = new CannedFuzzedDataProvider(cannedMockDataString); 41 Assert.assertEquals(referenceResult, sampleFuzzTarget(cannedMockData)); 42 } 43 sampleFuzzTarget(FuzzedDataProvider data)44 private String sampleFuzzTarget(FuzzedDataProvider data) { 45 StringBuilder result = new StringBuilder(); 46 result.append(data.consumeString(10)); 47 int[] ints = data.consumeInts(5); 48 result.append(Arrays.stream(ints).mapToObj(Integer::toString).collect(Collectors.joining(","))); 49 result.append(data.pickValue(ints)); 50 result.append(data.consumeString(20)); 51 result.append(data.pickValues(Arrays.stream(ints).boxed().collect(Collectors.toSet()), 5) 52 .stream() 53 .map(Integer::toHexString) 54 .collect(Collectors.joining(","))); 55 result.append(data.remainingBytes()); 56 return result.toString(); 57 } 58 59 private static final class MockFuzzedDataProvider implements FuzzedDataProvider { 60 @Override consumeBoolean()61 public boolean consumeBoolean() { 62 return true; 63 } 64 65 @Override consumeBooleans(int maxLength)66 public boolean[] consumeBooleans(int maxLength) { 67 return new boolean[] {false, true}; 68 } 69 70 @Override consumeByte()71 public byte consumeByte() { 72 return 2; 73 } 74 75 @Override consumeByte(byte min, byte max)76 public byte consumeByte(byte min, byte max) { 77 return max; 78 } 79 80 @Override consumeShort()81 public short consumeShort() { 82 return 2; 83 } 84 85 @Override consumeShort(short min, short max)86 public short consumeShort(short min, short max) { 87 return min; 88 } 89 90 @Override consumeShorts(int maxLength)91 public short[] consumeShorts(int maxLength) { 92 return new short[] {2, 4, 7}; 93 } 94 95 @Override consumeInt()96 public int consumeInt() { 97 return 5; 98 } 99 100 @Override consumeInt(int min, int max)101 public int consumeInt(int min, int max) { 102 return max; 103 } 104 105 @Override consumeInts(int maxLength)106 public int[] consumeInts(int maxLength) { 107 return IntStream.range(0, maxLength).toArray(); 108 } 109 110 @Override consumeLong()111 public long consumeLong() { 112 return 42; 113 } 114 115 @Override consumeLong(long min, long max)116 public long consumeLong(long min, long max) { 117 return min; 118 } 119 120 @Override consumeLongs(int maxLength)121 public long[] consumeLongs(int maxLength) { 122 return LongStream.range(0, maxLength).toArray(); 123 } 124 125 @Override consumeFloat()126 public float consumeFloat() { 127 return Float.NaN; 128 } 129 130 @Override consumeRegularFloat()131 public float consumeRegularFloat() { 132 return 0.3f; 133 } 134 135 @Override consumeRegularFloat(float min, float max)136 public float consumeRegularFloat(float min, float max) { 137 return min; 138 } 139 140 @Override consumeProbabilityFloat()141 public float consumeProbabilityFloat() { 142 return 0.2f; 143 } 144 145 @Override consumeDouble()146 public double consumeDouble() { 147 return Double.NaN; 148 } 149 150 @Override consumeRegularDouble(double min, double max)151 public double consumeRegularDouble(double min, double max) { 152 return max; 153 } 154 155 @Override consumeRegularDouble()156 public double consumeRegularDouble() { 157 return Math.PI; 158 } 159 160 @Override consumeProbabilityDouble()161 public double consumeProbabilityDouble() { 162 return 0.5; 163 } 164 165 @Override consumeChar()166 public char consumeChar() { 167 return 'C'; 168 } 169 170 @Override consumeChar(char min, char max)171 public char consumeChar(char min, char max) { 172 return min; 173 } 174 175 @Override consumeCharNoSurrogates()176 public char consumeCharNoSurrogates() { 177 return 'C'; 178 } 179 180 @Override consumeAsciiString(int maxLength)181 public String consumeAsciiString(int maxLength) { 182 return "foobar"; 183 } 184 185 @Override consumeString(int maxLength)186 public String consumeString(int maxLength) { 187 return "fooۊ"; 188 } 189 190 @Override consumeRemainingAsAsciiString()191 public String consumeRemainingAsAsciiString() { 192 return "foobar"; 193 } 194 195 @Override consumeRemainingAsString()196 public String consumeRemainingAsString() { 197 return "foobar"; 198 } 199 200 @Override consumeBytes(int maxLength)201 public byte[] consumeBytes(int maxLength) { 202 return new byte[maxLength]; 203 } 204 205 @Override consumeRemainingAsBytes()206 public byte[] consumeRemainingAsBytes() { 207 return new byte[] {1}; 208 } 209 210 @Override remainingBytes()211 public int remainingBytes() { 212 return 1; 213 } 214 } 215 } 216