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.rawdex; 18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.IOException; 20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic class EncodedValue implements RawDexObject { 22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public byte valueArg; 23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public byte valueType; 24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public byte[] value; 25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public EncodedArray encodedArray; 26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public EncodedAnnotation encodedAnnotation; 27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private static final byte VALUE_BYTE = 0x00; 29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private static final byte VALUE_ARRAY = 0x1c; 30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private static final byte VALUE_ANNOTATION = 0x1d; 31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private static final byte VALUE_NULL = 0x1e; 32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private static final byte VALUE_BOOLEAN = 0x1f; 33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void read(DexRandomAccessFile file) throws IOException { 36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle int valueArgAndType = file.readUnsignedByte(); 37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Get lower 5 bits. 39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle valueType = (byte) (valueArgAndType & 0x1f); 40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Get upper 3 bits. 41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle valueArg = (byte) ((valueArgAndType & 0xe0) >> 5); 42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle int size = 0; 44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle switch (valueType) { 46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle case VALUE_BYTE: 47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle size = 1; 48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle break; 49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle case VALUE_ARRAY: 50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle (encodedArray = new EncodedArray()).read(file); 51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle size = 0; // So we don't read into value. 52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle break; 53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle case VALUE_ANNOTATION: 54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle (encodedAnnotation = new EncodedAnnotation()).read(file); 55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle size = 0; // So we don't read into value. 56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle break; 57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle case VALUE_NULL: 58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle case VALUE_BOOLEAN: 59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // No value 60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle size = 0; 61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle break; 62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle default: 63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // All others encode value_arg as (size - 1), so... 64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle size = valueArg + 1; 65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle break; 66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (size != 0) { 69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle value = new byte[size]; 70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle for (int i = 0; i < size; i++) { 71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle value[i] = file.readByte(); 72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void write(DexRandomAccessFile file) throws IOException { 78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle int valueArgAndType = ((valueType) | (valueArg << 5)); 79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeByte(valueArgAndType); 80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (encodedArray != null) { 82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle encodedArray.write(file); 83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } else if (encodedAnnotation != null) { 84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle encodedAnnotation.write(file); 85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } else if (value != null) { 86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.write(value); 87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void incrementIndex(IndexUpdateKind kind, int insertedIdx) { 92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (encodedArray != null) { 93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle encodedArray.incrementIndex(kind, insertedIdx); 94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } else if (encodedAnnotation != null) { 95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle encodedAnnotation.incrementIndex(kind, insertedIdx); 96959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 97959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 98959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle} 99