• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.util;
33 
34 import org.jf.dexlib2.Format;
35 import org.jf.dexlib2.Opcode;
36 import org.jf.dexlib2.ReferenceType;
37 import org.jf.dexlib2.VerificationError;
38 import org.jf.dexlib2.iface.reference.*;
39 
40 public class Preconditions {
checkFormat(Opcode opcode, Format expectedFormat)41     public static void checkFormat(Opcode opcode, Format expectedFormat) {
42         if (opcode.format != expectedFormat) {
43             throw new IllegalArgumentException(
44                     String.format("Invalid opcode %s for %s", opcode.name, expectedFormat.name()));
45         }
46     }
47 
checkNibbleRegister(int register)48     public static int checkNibbleRegister(int register) {
49         if ((register & 0xFFFFFFF0) != 0) {
50             throw new IllegalArgumentException(
51                     String.format("Invalid register: v%d. Must be between v0 and v15, inclusive.", register));
52         }
53         return register;
54     }
55 
checkByteRegister(int register)56     public static int checkByteRegister(int register) {
57         if ((register & 0xFFFFFF00) != 0) {
58             throw new IllegalArgumentException(
59                     String.format("Invalid register: v%d. Must be between v0 and v255, inclusive.", register));
60         }
61         return register;
62     }
63 
checkShortRegister(int register)64     public static int checkShortRegister(int register) {
65         if ((register & 0xFFFF0000) != 0) {
66             throw new IllegalArgumentException(
67                     String.format("Invalid register: v%d. Must be between v0 and v65535, inclusive.", register));
68         }
69         return register;
70     }
71 
checkNibbleLiteral(int literal)72     public static int checkNibbleLiteral(int literal) {
73         if (literal < -8 || literal > 7) {
74             throw new IllegalArgumentException(
75                     String.format("Invalid literal value: %d. Must be between -8 and 7, inclusive.", literal));
76         }
77         return literal;
78     }
79 
checkByteLiteral(int literal)80     public static int checkByteLiteral(int literal) {
81         if (literal < -128 || literal > 127) {
82             throw new IllegalArgumentException(
83                     String.format("Invalid literal value: %d. Must be between -128 and 127, inclusive.", literal));
84         }
85         return literal;
86     }
87 
checkShortLiteral(int literal)88     public static int checkShortLiteral(int literal) {
89         if (literal < -32768 || literal > 32767) {
90             throw new IllegalArgumentException(
91                     String.format("Invalid literal value: %d. Must be between -32768 and 32767, inclusive.", literal));
92         }
93         return literal;
94     }
95 
checkIntegerHatLiteral(int literal)96     public static int checkIntegerHatLiteral(int literal) {
97         if ((literal & 0xFFFF) != 0) {
98             throw new IllegalArgumentException(
99                     String.format("Invalid literal value: %d. Low 16 bits must be zeroed out.", literal));
100         }
101         return literal;
102     }
103 
checkLongHatLiteral(long literal)104     public static long checkLongHatLiteral(long literal) {
105         if ((literal & 0xFFFFFFFFFFFFL) != 0) {
106             throw new IllegalArgumentException(
107                     String.format("Invalid literal value: %d. Low 48 bits must be zeroed out.", literal));
108         }
109         return literal;
110     }
111 
checkByteCodeOffset(int offset)112     public static int checkByteCodeOffset(int offset) {
113         if (offset < -128 || offset > 127) {
114             throw new IllegalArgumentException(
115                     String.format("Invalid code offset: %d. Must be between -128 and 127, inclusive.", offset));
116         }
117         return offset;
118     }
119 
checkShortCodeOffset(int offset)120     public static int checkShortCodeOffset(int offset) {
121         if (offset < -32768 || offset > 32767) {
122             throw new IllegalArgumentException(
123                     String.format("Invalid code offset: %d. Must be between -32768 and 32767, inclusive.", offset));
124         }
125         return offset;
126     }
127 
check35cAnd45ccRegisterCount(int registerCount)128     public static int check35cAnd45ccRegisterCount(int registerCount) {
129         if (registerCount < 0 || registerCount > 5) {
130             throw new IllegalArgumentException(
131                     String.format("Invalid register count: %d. Must be between 0 and 5, inclusive.", registerCount));
132         }
133         return registerCount;
134     }
135 
checkRegisterRangeCount(int registerCount)136     public static int checkRegisterRangeCount(int registerCount) {
137         if ((registerCount & 0xFFFFFF00) != 0) {
138             throw new IllegalArgumentException(
139                     String.format("Invalid register count: %d. Must be between 0 and 255, inclusive.", registerCount));
140         }
141         return registerCount;
142     }
143 
checkValueArg(int valueArg, int maxValue)144     public static void checkValueArg(int valueArg, int maxValue) {
145         if (valueArg > maxValue) {
146             if (maxValue == 0) {
147                 throw new IllegalArgumentException(
148                         String.format("Invalid value_arg value %d for an encoded_value. Expecting 0",
149                                 valueArg));
150             }
151             throw new IllegalArgumentException(
152                     String.format("Invalid value_arg value %d for an encoded_value. Expecting 0..%d, inclusive",
153                             valueArg, maxValue));
154         }
155     }
156 
checkFieldOffset(int fieldOffset)157     public static int checkFieldOffset(int fieldOffset) {
158         if (fieldOffset < 0 || fieldOffset > 65535) {
159             throw new IllegalArgumentException(
160                     String.format("Invalid field offset: 0x%x. Must be between 0x0000 and 0xFFFF inclusive",
161                             fieldOffset));
162         }
163         return fieldOffset;
164     }
165 
checkVtableIndex(int vtableIndex)166     public static int checkVtableIndex(int vtableIndex) {
167         if (vtableIndex < 0 || vtableIndex > 65535) {
168             throw new IllegalArgumentException(
169                     String.format("Invalid vtable index: %d. Must be between 0 and 65535, inclusive", vtableIndex));
170         }
171         return vtableIndex;
172     }
173 
checkInlineIndex(int inlineIndex)174     public static int checkInlineIndex(int inlineIndex) {
175         if (inlineIndex < 0 || inlineIndex > 65535) {
176             throw new IllegalArgumentException(
177                     String.format("Invalid inline index: %d. Must be between 0 and 65535, inclusive", inlineIndex));
178         }
179         return inlineIndex;
180     }
181 
checkVerificationError(int verificationError)182     public static int checkVerificationError(int verificationError) {
183         if (!VerificationError.isValidVerificationError(verificationError)) {
184             throw new IllegalArgumentException(
185                     String.format("Invalid verification error value: %d. Must be between 1 and 9, inclusive",
186                             verificationError));
187         }
188         return verificationError;
189     }
190 
checkReference(int referenceType, T reference)191     public static <T extends Reference> T checkReference(int referenceType, T reference) {
192         switch (referenceType) {
193             case ReferenceType.STRING:
194                 if (!(reference instanceof StringReference)) {
195                     throw new IllegalArgumentException("Invalid reference type, expecting a string reference");
196                 }
197                 break;
198             case ReferenceType.TYPE:
199                 if (!(reference instanceof TypeReference)) {
200                     throw new IllegalArgumentException("Invalid reference type, expecting a type reference");
201                 }
202                 break;
203             case ReferenceType.FIELD:
204                 if (!(reference instanceof FieldReference)) {
205                     throw new IllegalArgumentException("Invalid reference type, expecting a field reference");
206                 }
207                 break;
208             case ReferenceType.METHOD:
209                 if (!(reference instanceof MethodReference)) {
210                     throw new IllegalArgumentException("Invalid reference type, expecting a method reference");
211                 }
212                 break;
213             default:
214                 throw new IllegalArgumentException(String.format("Not a valid reference type: %d", referenceType));
215         }
216         return reference;
217     }
218 }
219