1be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver/* 2be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Copyright 2012, Google Inc. 3be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * All rights reserved. 4be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 5be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Redistribution and use in source and binary forms, with or without 6be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * modification, are permitted provided that the following conditions are 7be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * met: 8be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 9be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Redistributions of source code must retain the above copyright 10be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * notice, this list of conditions and the following disclaimer. 11be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Redistributions in binary form must reproduce the above 12be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * copyright notice, this list of conditions and the following disclaimer 13be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * in the documentation and/or other materials provided with the 14be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * distribution. 15be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Neither the name of Google Inc. nor the names of its 16be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * contributors may be used to endorse or promote products derived from 17be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * this software without specific prior written permission. 18be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 19be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver */ 31be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 32be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverpackage org.jf.dexlib2.dexbacked.value; 33be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 34f4662586da3c902c3a0ed21a174b814e248c7fb8Ben Gruverimport org.jf.dexlib2.ValueType; 35f4662586da3c902c3a0ed21a174b814e248c7fb8Ben Gruverimport org.jf.dexlib2.dexbacked.DexReader; 36be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.value.EncodedValue; 377c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.dexlib2.immutable.value.*; 387c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.dexlib2.util.Preconditions; 397c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.util.ExceptionWithContext; 40be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 4125d385a441b95d56987c81f00f19297d799e1b31Ben Gruverimport javax.annotation.Nonnull; 4225d385a441b95d56987c81f00f19297d799e1b31Ben Gruver 437c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverpublic abstract class DexBackedEncodedValue { 4425d385a441b95d56987c81f00f19297d799e1b31Ben Gruver @Nonnull 4525d385a441b95d56987c81f00f19297d799e1b31Ben Gruver public static EncodedValue readFrom(@Nonnull DexReader reader) { 467c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int startOffset = reader.getOffset(); 47be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 487c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver try { 497c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int b = reader.readUbyte(); 507c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueType = b & 0x1f; 517c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueArg = b >>> 5; 52be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 537c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver switch (valueType) { 547c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BYTE: 557c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 567c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableByteEncodedValue((byte)reader.readByte()); 577c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.SHORT: 587c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 597c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableShortEncodedValue((short)reader.readSizedInt(valueArg + 1)); 607c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.CHAR: 617c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 627c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableCharEncodedValue((char)reader.readSizedSmallUint(valueArg + 1)); 637c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.INT: 647c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 657c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableIntEncodedValue(reader.readSizedInt(valueArg + 1)); 667c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.LONG: 677c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 7); 687c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableLongEncodedValue(reader.readSizedLong(valueArg + 1)); 697c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FLOAT: 707c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 717c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableFloatEncodedValue(Float.intBitsToFloat( 72a88239d92d47b45f0e2f9637afeacabcb9e4f3aeBen Gruver reader.readSizedRightExtendedInt(valueArg + 1))); 737c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.DOUBLE: 747c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 7); 757c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableDoubleEncodedValue(Double.longBitsToDouble( 76a88239d92d47b45f0e2f9637afeacabcb9e4f3aeBen Gruver reader.readSizedRightExtendedLong(valueArg + 1))); 777c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.STRING: 787c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 7922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedStringEncodedValue(reader, valueArg); 807c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.TYPE: 817c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 823c3a3c4af82abff185c0699d536dec5002b4406aBen Gruver return new DexBackedTypeEncodedValue(reader, valueArg); 837c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FIELD: 847c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 8522c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedFieldEncodedValue(reader, valueArg); 867c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.METHOD: 877c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 8822c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedMethodEncodedValue(reader, valueArg); 897c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ENUM: 907c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 9122c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedEnumEncodedValue(reader, valueArg); 927c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ARRAY: 937c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 947c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new DexBackedArrayEncodedValue(reader); 957c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ANNOTATION: 967c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 977c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new DexBackedAnnotationEncodedValue(reader); 987c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.NULL: 9922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver Preconditions.checkValueArg(valueArg, 0); 1007c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return ImmutableNullEncodedValue.INSTANCE; 1017c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BOOLEAN: 1027c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 103bddef6af3c39732ba0329c4a8e233f3858226f39Ben Gruver return ImmutableBooleanEncodedValue.forBoolean(valueArg == 1); 1047c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver default: 1057c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType); 1067c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 1077c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } catch (Exception ex) { 1087c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw ExceptionWithContext.withContext(ex, "Error while reading encoded value at offset 0x%x", startOffset); 1097c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 110be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 111be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 11225d385a441b95d56987c81f00f19297d799e1b31Ben Gruver public static void skipFrom(@Nonnull DexReader reader) { 1137c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int startOffset = reader.getOffset(); 1147c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver 1157c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver try { 1167c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int b = reader.readUbyte(); 1177c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueType = b & 0x1f; 1187c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver 1197c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver switch (valueType) { 1207c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BYTE: 1217c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver reader.skipByte(); 1227c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1237c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.SHORT: 1247c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.CHAR: 1257c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.INT: 1267c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.LONG: 1277c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FLOAT: 1287c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.DOUBLE: 1297c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.STRING: 1307c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.TYPE: 1317c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FIELD: 1327c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.METHOD: 1337c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ENUM: 1347c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueArg = b >>> 5; 13568f69b899ff18bf6ced6249d48dd7f059a51255fBen Gruver reader.moveRelative(valueArg+1); 1367c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1377c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ARRAY: 1387c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver DexBackedArrayEncodedValue.skipFrom(reader); 1397c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1407c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ANNOTATION: 1417c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver DexBackedAnnotationEncodedValue.skipFrom(reader); 1427c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1437c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.NULL: 1447c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BOOLEAN: 1457c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1467c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver default: 1477c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType); 1487c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 1497c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } catch (Exception ex) { 1507c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw ExceptionWithContext.withContext(ex, "Error while skipping encoded value at offset 0x%x", 1517c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver startOffset); 1527c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 153be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 154be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver} 155