1959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/* 2959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Copyright (C) 2014 The Android Open Source Project 3959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 4959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Licensed under the Apache License, Version 2.0 (the "License"); 5959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * you may not use this file except in compliance with the License. 6959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * You may obtain a copy of the License at 7959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 8959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * http://www.apache.org/licenses/LICENSE-2.0 9959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 10959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Unless required by applicable law or agreed to in writing, software 11959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * distributed under the License is distributed on an "AS IS" BASIS, 12959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * See the License for the specific language governing permissions and 14959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * limitations under the License. 15959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 16959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 17959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepackage dexfuzz.program; 18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Log; 20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.program.mutators.CodeMutator; 21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.BufferedReader; 23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.BufferedWriter; 24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.IOException; 25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/** 27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Responsible for serializing mutations, allowing replay of mutations, and searching 28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * for a minimal set of mutations. 29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic class MutationSerializer { 31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public static String getMutationString(Mutation mutation) { 32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle StringBuilder builder = new StringBuilder(); 33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle builder.append(mutation.mutatorClass.getCanonicalName()).append(" "); 34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle builder.append(mutation.mutatableCodeIdx).append(" "); 35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle builder.append(mutation.getString()); 36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return builder.toString(); 37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public static void writeMutation(BufferedWriter writer, Mutation mutation) throws IOException { 40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Write out the common fields. 41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle writer.write(mutation.mutatorClass.getCanonicalName() + " " 42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle + mutation.mutatableCodeIdx + " "); 43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Use the mutation's own function to write out the rest of the fields. 45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle writer.write(mutation.getString() + "\n"); 46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @SuppressWarnings("unchecked") 49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public static Mutation readMutation(BufferedReader reader) throws IOException { 50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle String line = reader.readLine(); 51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle String[] fields = null; 52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (line != null) { 53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle fields = line.split(" "); 54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } else { 55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Could not read line during mutation loading."); 56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Read the mutator's class name 59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle String mutatorClassName = fields[0]; 60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Get the class for that mutator 62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Class<? extends CodeMutator> mutatorClass = null; 63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle try { 64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutatorClass = (Class<? extends CodeMutator>) Class.forName(mutatorClassName); 65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } catch (ClassNotFoundException e) { 66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Cannot find a mutator class called: " + mutatorClassName); 67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Mutation mutation = null; 70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle try { 71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutation = mutatorClass.newInstance().getNewMutation(); 72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } catch (InstantiationException e) { 73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Unable to instantiate " + mutatorClassName 74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle + " using default constructor."); 75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } catch (IllegalAccessException e) { 76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Unable to access methods in " + mutatorClassName + "."); 77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (mutation == null) { 80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Unable to get Mutation for Mutator: " + mutatorClassName); 81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Populate the common fields of the mutation. 84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutation.mutatorClass = mutatorClass; 85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // The Program must set this later, using the mutatable_code_idx 86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // into its list of MutatableCodes. 87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutation.mutatableCode = null; 88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutation.mutatableCodeIdx = Integer.parseInt(fields[1]); 89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Use the mutation's own method to read the rest of the fields. 91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutation.parseString(fields); 92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return mutation; 94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle} 96