mirror of
https://github.com/revanced/smali.git
synced 2025-05-03 08:04:28 +02:00
Refactor DexBuffer and DexReader to make them easier to test
This commit is contained in:
parent
fd26bc6062
commit
7301fbe30e
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
|
import org.jf.util.ExceptionWithContext;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class BaseDexBuffer {
|
||||||
|
@Nonnull /* package private */ final byte[] buf;
|
||||||
|
|
||||||
|
public BaseDexBuffer(@Nonnull byte[] buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSmallUint(int offset) {
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
int result = (buf[offset] & 0xff) |
|
||||||
|
((buf[offset+1] & 0xff) << 8) |
|
||||||
|
((buf[offset+2] & 0xff) << 16) |
|
||||||
|
((buf[offset+3]) << 24);
|
||||||
|
if (result < 0) {
|
||||||
|
throw new ExceptionWithContext("Encountered small uint that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readOptionalUint(int offset) {
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
int result = (buf[offset] & 0xff) |
|
||||||
|
((buf[offset+1] & 0xff) << 8) |
|
||||||
|
((buf[offset+2] & 0xff) << 16) |
|
||||||
|
((buf[offset+3]) << 24);
|
||||||
|
if (result < -1) {
|
||||||
|
throw new ExceptionWithContext("Encountered optional uint that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUshort(int offset) {
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
return (buf[offset] & 0xff) |
|
||||||
|
((buf[offset+1] & 0xff) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUbyte(int offset) {
|
||||||
|
return buf[offset] & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong(int offset) {
|
||||||
|
// TODO: use | or +?
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
return (buf[offset] & 0xff) |
|
||||||
|
((buf[offset+1] & 0xff) << 8) |
|
||||||
|
((buf[offset+2] & 0xff) << 16) |
|
||||||
|
((buf[offset+3] & 0xffL) << 24) |
|
||||||
|
((buf[offset+4] & 0xffL) << 32) |
|
||||||
|
((buf[offset+5] & 0xffL) << 40) |
|
||||||
|
((buf[offset+6] & 0xffL) << 48) |
|
||||||
|
(((long)buf[offset+7]) << 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt(int offset) {
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
return (buf[offset] & 0xff) |
|
||||||
|
((buf[offset+1] & 0xff) << 8) |
|
||||||
|
((buf[offset+2] & 0xff) << 16) |
|
||||||
|
(buf[offset+3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readShort(int offset) {
|
||||||
|
byte[] buf = this.buf;
|
||||||
|
return (buf[offset] & 0xff) |
|
||||||
|
(buf[offset+1] << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readByte(int offset) {
|
||||||
|
return buf[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public BaseDexReader readerAt(int offset) {
|
||||||
|
return new BaseDexReader<BaseDexBuffer>(this, offset);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,460 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
|
import org.jf.util.ExceptionWithContext;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class BaseDexReader<T extends BaseDexBuffer> {
|
||||||
|
@Nonnull public final T dexBuf;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
public BaseDexReader(@Nonnull T dexBuf, int offset) {
|
||||||
|
this.dexBuf = dexBuf;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset() { return offset; }
|
||||||
|
public void setOffset(int offset) { this.offset = offset; }
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public int readSleb128() {
|
||||||
|
int end = offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result <= 0x7f) {
|
||||||
|
result = (result << 25) >> 25;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 18) >> 18;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 14;
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 11) >> 11;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 21;
|
||||||
|
if (currentByteValue <= 0x7f) {
|
||||||
|
result = (result << 4) >> 4;
|
||||||
|
} else {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result |= currentByteValue << 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSmallUleb128() {
|
||||||
|
int end = offset;
|
||||||
|
int currentByteValue;
|
||||||
|
int result;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
result = buf[end++] & 0xff;
|
||||||
|
if (result > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 14;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++] & 0xff;
|
||||||
|
result |= (currentByteValue & 0x7f) << 21;
|
||||||
|
if (currentByteValue > 0x7f) {
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
|
||||||
|
// MSB shouldn't be set on last byte
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||||
|
// we assume most significant bit of the result will not be set, so that it can fit into
|
||||||
|
// a signed integer without wrapping
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result |= currentByteValue << 28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipUleb128() {
|
||||||
|
int end = offset;
|
||||||
|
byte currentByteValue;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) { // if the MSB is set
|
||||||
|
currentByteValue = buf[end++];
|
||||||
|
if (currentByteValue < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||||
|
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||||
|
// we assume most significant bit of the result will not be set, so that it can fit into
|
||||||
|
// a signed integer without wrapping
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSmallUint() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readSmallUint(o);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readOptionalUint() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readOptionalUint(o);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekUshort() {
|
||||||
|
return dexBuf.readUshort(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUshort() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readUshort(offset);
|
||||||
|
offset = o + 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int peekUbyte() {
|
||||||
|
return dexBuf.readUbyte(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readUbyte() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readUbyte(offset);
|
||||||
|
offset = o + 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong() {
|
||||||
|
int o = offset;
|
||||||
|
long result = dexBuf.readLong(offset);
|
||||||
|
offset = o + 8;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readInt(offset);
|
||||||
|
offset = o + 4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readShort() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readShort(offset);
|
||||||
|
offset = o + 2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readByte() {
|
||||||
|
int o = offset;
|
||||||
|
int result = dexBuf.readByte(offset);
|
||||||
|
offset = o + 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipByte() { offset++; }
|
||||||
|
public void moveRelative(int i) { offset += i; }
|
||||||
|
|
||||||
|
public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
|
||||||
|
public int readUshort(int offset) { return dexBuf.readUshort(offset); }
|
||||||
|
public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
|
||||||
|
public long readLong(int offset) { return dexBuf.readLong(offset); }
|
||||||
|
public int readInt(int offset) { return dexBuf.readInt(offset); }
|
||||||
|
public int readShort(int offset) { return dexBuf.readShort(offset); }
|
||||||
|
public int readByte(int offset) { return dexBuf.readByte(offset); }
|
||||||
|
|
||||||
|
public int readSizedInt(int bytes) {
|
||||||
|
int o = offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(buf[o+3] << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2]) << 16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1]) << 8);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSizedSmallUint(int bytes) {
|
||||||
|
int o = offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
int b = buf[o+3];
|
||||||
|
if (b < 0) {
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Encountered valid sized uint that is out of range at offset 0x%x", offset);
|
||||||
|
}
|
||||||
|
result = b << 24;
|
||||||
|
// fall-through
|
||||||
|
case 3:
|
||||||
|
result |= (buf[o+2] & 0xff) << 16;
|
||||||
|
// fall-through
|
||||||
|
case 2:
|
||||||
|
result |= (buf[o+1] & 0xff) << 8;
|
||||||
|
// fall-through
|
||||||
|
case 1:
|
||||||
|
result |= (buf[o] & 0xff);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readSizedRightExtendedInt(int bytes) {
|
||||||
|
int o = offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(buf[o+3] << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) << 8 |
|
||||||
|
((buf[o+1] & 0xff) << 16) |
|
||||||
|
(buf[o+2] << 24);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) << 16 |
|
||||||
|
(buf[o+1] << 24);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o] << 24;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readSizedRightExtendedLong(int bytes) {
|
||||||
|
int o = offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
long result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 8:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((buf[o+6] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+7]) << 56);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = ((buf[o] & 0xff)) << 8 |
|
||||||
|
((buf[o+1] & 0xff) << 16) |
|
||||||
|
((buf[o+2] & 0xffL) << 24) |
|
||||||
|
((buf[o+3] & 0xffL) << 32) |
|
||||||
|
((buf[o+4] & 0xffL) << 40) |
|
||||||
|
((buf[o+5] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+6]) << 56);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result = ((buf[o] & 0xff)) << 16 |
|
||||||
|
((buf[o+1] & 0xffL) << 24) |
|
||||||
|
((buf[o+2] & 0xffL) << 32) |
|
||||||
|
((buf[o+3] & 0xffL) << 40) |
|
||||||
|
((buf[o+4] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+5]) << 56);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = ((buf[o] & 0xffL)) << 24 |
|
||||||
|
((buf[o+1] & 0xffL) << 32) |
|
||||||
|
((buf[o+2] & 0xffL) << 40) |
|
||||||
|
((buf[o+3] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+4]) << 56);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = ((buf[o] & 0xffL)) << 32 |
|
||||||
|
((buf[o+1] & 0xffL) << 40) |
|
||||||
|
((buf[o+2] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+3]) << 56);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = ((buf[o] & 0xffL)) << 40 |
|
||||||
|
((buf[o+1] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+2]) << 56);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = ((buf[o] & 0xffL)) << 48 |
|
||||||
|
(((long)buf[o+1]) << 56);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = ((long)buf[o]) << 56;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext(
|
||||||
|
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
offset = o + bytes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readSizedLong(int bytes) {
|
||||||
|
int o = offset;
|
||||||
|
byte[] buf = dexBuf.buf;
|
||||||
|
|
||||||
|
long result;
|
||||||
|
switch (bytes) {
|
||||||
|
case 8:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((buf[o+6] & 0xffL) << 48) |
|
||||||
|
(((long)buf[o+7]) << 56);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((buf[o+5] & 0xffL) << 40) |
|
||||||
|
((long)(buf[o+6]) << 48);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((buf[o+4] & 0xffL) << 32) |
|
||||||
|
((long)(buf[o+5]) << 40);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
((buf[o+3] & 0xffL) << 24) |
|
||||||
|
((long)(buf[o+4]) << 32);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
((buf[o+2] & 0xff) << 16) |
|
||||||
|
(((long)buf[o+3]) << 24);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
((buf[o+1] & 0xff) << 8) |
|
||||||
|
(buf[o+2] << 16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = (buf[o] & 0xff) |
|
||||||
|
(buf[o+1] << 8);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = buf[o];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = o + bytes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -31,12 +31,10 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
|
||||||
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
||||||
import org.jf.dexlib2.iface.DexFile;
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class DexBackedDexFile implements DexFile {
|
public class DexBackedDexFile implements DexFile {
|
||||||
@ -65,110 +63,4 @@ public class DexBackedDexFile implements DexFile {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChecksum() {
|
|
||||||
return dexBuf.getChecksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getSignature() {
|
|
||||||
return dexBuf.getSignature();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DexBackedMapItem> getMap() {
|
|
||||||
final int mapOffset = dexBuf.getMapOffset();
|
|
||||||
final int sectionCount = dexBuf.readSmallUint(mapOffset);
|
|
||||||
|
|
||||||
return new FixedSizeList<DexBackedMapItem>() {
|
|
||||||
@Override
|
|
||||||
public DexBackedMapItem readItem(int index) {
|
|
||||||
int mapItemOffset = mapOffset + 4 + index * DexBuffer.MAP_ITEM_SIZE;
|
|
||||||
return new DexBackedMapItem(dexBuf, mapItemOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return sectionCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getStrings() {
|
|
||||||
final int stringCount = dexBuf.getStringCount();
|
|
||||||
|
|
||||||
return new FixedSizeSet<String>() {
|
|
||||||
@Override
|
|
||||||
public String readItem(int index) {
|
|
||||||
return dexBuf.getString(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return stringCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getTypes() {
|
|
||||||
final int typeCount = dexBuf.getTypeCount();
|
|
||||||
|
|
||||||
return new FixedSizeSet<String>() {
|
|
||||||
@Override
|
|
||||||
public String readItem(int index) {
|
|
||||||
return dexBuf.getType(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return typeCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getProtos() {
|
|
||||||
final int protoCount = dexBuf.getProtoCount();
|
|
||||||
|
|
||||||
return new FixedSizeSet<String>() {
|
|
||||||
@Override
|
|
||||||
public String readItem(int index) {
|
|
||||||
return dexBuf.getProto(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return protoCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getFields() {
|
|
||||||
final int fieldCount = dexBuf.getFieldCount();
|
|
||||||
|
|
||||||
return new FixedSizeSet<String>() {
|
|
||||||
@Override
|
|
||||||
public String readItem(int index) {
|
|
||||||
return dexBuf.getField(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return fieldCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getMethods() {
|
|
||||||
final int methodCount = dexBuf.getMethodCount();
|
|
||||||
|
|
||||||
return new FixedSizeSet<String>() {
|
|
||||||
@Override
|
|
||||||
public String readItem(int index) {
|
|
||||||
return dexBuf.getMethod(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return methodCount;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, Google Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of Google Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
|
||||||
|
|
||||||
import org.jf.dexlib2.writer.DexItemType;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public class DexBackedMapItem {
|
|
||||||
@Nonnull public final DexBuffer dexBuf;
|
|
||||||
private final int mapItemOffset;
|
|
||||||
|
|
||||||
private static final int TYPE_OFFSET = 0;
|
|
||||||
private static final int SIZE_OFFSET = 4;
|
|
||||||
private static final int OFFSET_OFFSET = 8;
|
|
||||||
|
|
||||||
DexBackedMapItem(@Nonnull DexBuffer dexBuf,
|
|
||||||
int mapItemOffset) {
|
|
||||||
this.dexBuf = dexBuf;
|
|
||||||
this.mapItemOffset = mapItemOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() {
|
|
||||||
return dexBuf.readUshort(mapItemOffset + TYPE_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return DexItemType.getItemTypeName(getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumItems() {
|
|
||||||
return dexBuf.readSmallUint(mapItemOffset + SIZE_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOffset() {
|
|
||||||
return dexBuf.readSmallUint(mapItemOffset + OFFSET_OFFSET);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012, Google Inc.
|
* Copyright 2013, Google Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
import org.jf.dexlib2.ReferenceType;
|
|
||||||
import org.jf.util.ExceptionWithContext;
|
import org.jf.util.ExceptionWithContext;
|
||||||
import org.jf.util.Utf8Utils;
|
import org.jf.util.Utf8Utils;
|
||||||
|
|
||||||
@ -39,21 +38,19 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class DexBuffer {
|
public class DexBuffer extends BaseDexBuffer {
|
||||||
// TODO: consider using a direct ByteBuffer instead
|
public final int stringCount;
|
||||||
@Nonnull /* package private */ final byte[] buf;
|
public final int stringStartOffset;
|
||||||
private final int stringCount;
|
public final int typeCount;
|
||||||
private final int stringStartOffset;
|
public final int typeStartOffset;
|
||||||
private final int typeCount;
|
public final int protoCount;
|
||||||
private final int typeStartOffset;
|
public final int protoStartOffset;
|
||||||
private final int protoCount;
|
public final int fieldCount;
|
||||||
private final int protoStartOffset;
|
public final int fieldStartOffset;
|
||||||
private final int fieldCount;
|
public final int methodCount;
|
||||||
private final int fieldStartOffset;
|
public final int methodStartOffset;
|
||||||
private final int methodCount;
|
public final int classCount;
|
||||||
private final int methodStartOffset;
|
public final int classStartOffset;
|
||||||
private final int classCount;
|
|
||||||
private final int classStartOffset;
|
|
||||||
|
|
||||||
@Nonnull private final String[] stringCache;
|
@Nonnull private final String[] stringCache;
|
||||||
|
|
||||||
@ -105,43 +102,25 @@ public class DexBuffer {
|
|||||||
public static final int TYPE_LIST_SIZE_OFFSET = 0;
|
public static final int TYPE_LIST_SIZE_OFFSET = 0;
|
||||||
public static final int TYPE_LIST_LIST_OFFSET = 4;
|
public static final int TYPE_LIST_LIST_OFFSET = 4;
|
||||||
|
|
||||||
protected DexBuffer(@Nonnull byte[] buf, boolean bare) {
|
|
||||||
this.buf = buf;
|
|
||||||
|
|
||||||
if (!bare) {
|
|
||||||
verifyMagic();
|
|
||||||
verifyEndian();
|
|
||||||
stringCount = readSmallUint(STRING_COUNT_OFFSET);
|
|
||||||
stringStartOffset = readSmallUint(STRING_START_OFFSET);
|
|
||||||
typeCount = readSmallUint(TYPE_COUNT_OFFSET);
|
|
||||||
typeStartOffset = readSmallUint(TYPE_START_OFFSET);
|
|
||||||
protoCount = readSmallUint(PROTO_COUNT_OFFSET);
|
|
||||||
protoStartOffset = readSmallUint(PROTO_START_OFFSET);
|
|
||||||
fieldCount = readSmallUint(FIELD_COUNT_OFFSET);
|
|
||||||
fieldStartOffset = readSmallUint(FIELD_START_OFFSET);
|
|
||||||
methodCount = readSmallUint(METHOD_COUNT_OFFSET);
|
|
||||||
methodStartOffset = readSmallUint(METHOD_START_OFFSET);
|
|
||||||
classCount = readSmallUint(CLASS_COUNT_OFFSET);
|
|
||||||
classStartOffset = readSmallUint(CLASS_START_OFFSET);
|
|
||||||
} else {
|
|
||||||
stringCount = 0;
|
|
||||||
stringStartOffset = 0;
|
|
||||||
typeCount = 0;
|
|
||||||
typeStartOffset = 0;
|
|
||||||
protoCount = 0;
|
|
||||||
protoStartOffset = 0;
|
|
||||||
fieldCount = 0;
|
|
||||||
fieldStartOffset = 0;
|
|
||||||
methodCount = 0;
|
|
||||||
methodStartOffset = 0;
|
|
||||||
classCount = 0;
|
|
||||||
classStartOffset = 0;
|
|
||||||
}
|
|
||||||
stringCache = new String[stringCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DexBuffer(@Nonnull byte[] buf) {
|
public DexBuffer(@Nonnull byte[] buf) {
|
||||||
this(buf, false);
|
super(buf);
|
||||||
|
|
||||||
|
verifyMagic();
|
||||||
|
verifyEndian();
|
||||||
|
stringCount = readSmallUint(STRING_COUNT_OFFSET);
|
||||||
|
stringStartOffset = readSmallUint(STRING_START_OFFSET);
|
||||||
|
typeCount = readSmallUint(TYPE_COUNT_OFFSET);
|
||||||
|
typeStartOffset = readSmallUint(TYPE_START_OFFSET);
|
||||||
|
protoCount = readSmallUint(PROTO_COUNT_OFFSET);
|
||||||
|
protoStartOffset = readSmallUint(PROTO_START_OFFSET);
|
||||||
|
fieldCount = readSmallUint(FIELD_COUNT_OFFSET);
|
||||||
|
fieldStartOffset = readSmallUint(FIELD_START_OFFSET);
|
||||||
|
methodCount = readSmallUint(METHOD_COUNT_OFFSET);
|
||||||
|
methodStartOffset = readSmallUint(METHOD_START_OFFSET);
|
||||||
|
classCount = readSmallUint(CLASS_COUNT_OFFSET);
|
||||||
|
classStartOffset = readSmallUint(CLASS_START_OFFSET);
|
||||||
|
|
||||||
|
stringCache = new String[stringCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyMagic() {
|
private void verifyMagic() {
|
||||||
@ -245,10 +224,6 @@ public class DexBuffer {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStringCount() {
|
|
||||||
return stringCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getOptionalType(int typeIndex) {
|
public String getOptionalType(int typeIndex) {
|
||||||
if (typeIndex == -1) {
|
if (typeIndex == -1) {
|
||||||
@ -272,165 +247,9 @@ public class DexBuffer {
|
|||||||
return getString(stringIndex);
|
return getString(stringIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTypeCount() {
|
@Override
|
||||||
return typeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getProto(int typeIndex) {
|
|
||||||
int protoOffset = getProtoIdItemOffset(typeIndex);
|
|
||||||
int stringIndex = readSmallUint(protoOffset);
|
|
||||||
return getString(stringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProtoCount() {
|
|
||||||
return protoCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getField(int fieldIndex) {
|
|
||||||
int fieldOffset = getFieldIdItemOffset(fieldIndex);
|
|
||||||
String className = getType(readUshort(fieldOffset + FIELD_CLASS_IDX_OFFSET));
|
|
||||||
String fieldType = getType(readUshort(fieldOffset + FIELD_TYPE_IDX_OFFSET));
|
|
||||||
String fieldName = getString(readSmallUint(fieldOffset + FIELD_NAME_IDX_OFFSET));
|
|
||||||
|
|
||||||
StringBuilder sb = localStringBuilder.get();
|
|
||||||
sb.setLength(0);
|
|
||||||
sb.append(className);
|
|
||||||
sb.append("->");
|
|
||||||
sb.append(fieldName);
|
|
||||||
sb.append(":");
|
|
||||||
sb.append(fieldType);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFieldCount() {
|
|
||||||
return fieldCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getMethod(int methodIndex) {
|
|
||||||
int methodOffset = getMethodIdItemOffset(methodIndex);
|
|
||||||
String className = getType(readUshort(methodOffset + METHOD_CLASS_IDX_OFFSET));
|
|
||||||
String methodName = getString(readSmallUint(methodOffset + METHOD_NAME_IDX_OFFSET));
|
|
||||||
|
|
||||||
int protoOffset = getProtoIdItemOffset(readUshort(methodOffset + METHOD_PROTO_IDX_OFFSET));
|
|
||||||
String returnType = getType(readSmallUint(protoOffset + PROTO_RETURN_TYPE_IDX_OFFSET));
|
|
||||||
int parametersOffset = readSmallUint(protoOffset + PROTO_PARAM_LIST_OFF_OFFSET);
|
|
||||||
|
|
||||||
StringBuilder sb = localStringBuilder.get();
|
|
||||||
sb.setLength(0);
|
|
||||||
sb.append(className);
|
|
||||||
sb.append("->");
|
|
||||||
sb.append(methodName);
|
|
||||||
sb.append("(");
|
|
||||||
|
|
||||||
if (parametersOffset > 0) {
|
|
||||||
int parameterCount = readSmallUint(parametersOffset + TYPE_LIST_SIZE_OFFSET);
|
|
||||||
int endOffset = parametersOffset + TYPE_LIST_LIST_OFFSET + parameterCount*2;
|
|
||||||
|
|
||||||
for (int off=parametersOffset+TYPE_LIST_LIST_OFFSET; off<endOffset; off+=2) {
|
|
||||||
int parameterTypeIndex = readUshort(off);
|
|
||||||
sb.append(getType(parameterTypeIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(")");
|
|
||||||
sb.append(returnType);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMethodCount() {
|
|
||||||
return methodCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getReference(int referenceType, int referenceIndex) {
|
|
||||||
switch (referenceType) {
|
|
||||||
case ReferenceType.STRING:
|
|
||||||
return getString(referenceIndex);
|
|
||||||
case ReferenceType.TYPE:
|
|
||||||
return getType(referenceIndex);
|
|
||||||
case ReferenceType.FIELD:
|
|
||||||
return getField(referenceIndex);
|
|
||||||
case ReferenceType.METHOD:
|
|
||||||
return getMethod(referenceIndex);
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid reference type: %d", referenceType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSmallUint(int offset) {
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
int result = (buf[offset] & 0xff) |
|
|
||||||
((buf[offset+1] & 0xff) << 8) |
|
|
||||||
((buf[offset+2] & 0xff) << 16) |
|
|
||||||
((buf[offset+3]) << 24);
|
|
||||||
if (result < 0) {
|
|
||||||
throw new ExceptionWithContext("Encountered small uint that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readOptionalUint(int offset) {
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
int result = (buf[offset] & 0xff) |
|
|
||||||
((buf[offset+1] & 0xff) << 8) |
|
|
||||||
((buf[offset+2] & 0xff) << 16) |
|
|
||||||
((buf[offset+3]) << 24);
|
|
||||||
if (result < -1) {
|
|
||||||
throw new ExceptionWithContext("Encountered optional uint that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUshort(int offset) {
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
return (buf[offset] & 0xff) |
|
|
||||||
((buf[offset+1] & 0xff) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUbyte(int offset) {
|
|
||||||
return buf[offset] & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readLong(int offset) {
|
|
||||||
// TODO: use | or +?
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
return (buf[offset] & 0xff) |
|
|
||||||
((buf[offset+1] & 0xff) << 8) |
|
|
||||||
((buf[offset+2] & 0xff) << 16) |
|
|
||||||
((buf[offset+3] & 0xffL) << 24) |
|
|
||||||
((buf[offset+4] & 0xffL) << 32) |
|
|
||||||
((buf[offset+5] & 0xffL) << 40) |
|
|
||||||
((buf[offset+6] & 0xffL) << 48) |
|
|
||||||
(((long)buf[offset+7]) << 56);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readInt(int offset) {
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
return (buf[offset] & 0xff) |
|
|
||||||
((buf[offset+1] & 0xff) << 8) |
|
|
||||||
((buf[offset+2] & 0xff) << 16) |
|
|
||||||
(buf[offset+3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readShort(int offset) {
|
|
||||||
byte[] buf = this.buf;
|
|
||||||
return (buf[offset] & 0xff) |
|
|
||||||
(buf[offset+1] << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readByte(int offset) {
|
|
||||||
return buf[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public DexReader readerAt(int offset) {
|
public DexReader readerAt(int offset) {
|
||||||
return new DexReader(this, offset);
|
return new DexReader(this, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ThreadLocal<StringBuilder> localStringBuilder = new ThreadLocal<StringBuilder>() {
|
|
||||||
@Override protected StringBuilder initialValue() { return new StringBuilder(256); }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -31,430 +31,10 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
package org.jf.dexlib2.dexbacked;
|
||||||
|
|
||||||
import org.jf.util.ExceptionWithContext;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class DexReader {
|
public class DexReader extends BaseDexReader<DexBuffer> {
|
||||||
@Nonnull public final DexBuffer dexBuf;
|
|
||||||
private int offset;
|
|
||||||
|
|
||||||
public DexReader(@Nonnull DexBuffer dexBuf, int offset) {
|
public DexReader(@Nonnull DexBuffer dexBuf, int offset) {
|
||||||
this.dexBuf = dexBuf;
|
super(dexBuf, offset);
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOffset() { return offset; }
|
|
||||||
public void setOffset(int offset) { this.offset = offset; }
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
public int readSleb128() {
|
|
||||||
int end = offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result <= 0x7f) {
|
|
||||||
result = (result << 25) >> 25;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 18) >> 18;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 14;
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 11) >> 11;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 21;
|
|
||||||
if (currentByteValue <= 0x7f) {
|
|
||||||
result = (result << 4) >> 4;
|
|
||||||
} else {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result |= currentByteValue << 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSmallUleb128() {
|
|
||||||
int end = offset;
|
|
||||||
int currentByteValue;
|
|
||||||
int result;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
result = buf[end++] & 0xff;
|
|
||||||
if (result > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 14;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++] & 0xff;
|
|
||||||
result |= (currentByteValue & 0x7f) << 21;
|
|
||||||
if (currentByteValue > 0x7f) {
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
|
|
||||||
// MSB shouldn't be set on last byte
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
|
||||||
// we assume most significant bit of the result will not be set, so that it can fit into
|
|
||||||
// a signed integer without wrapping
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result |= currentByteValue << 28;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void skipUleb128() {
|
|
||||||
int end = offset;
|
|
||||||
byte currentByteValue;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) { // if the MSB is set
|
|
||||||
currentByteValue = buf[end++];
|
|
||||||
if (currentByteValue < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
|
||||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
|
||||||
// we assume most significant bit of the result will not be set, so that it can fit into
|
|
||||||
// a signed integer without wrapping
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSmallUint() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readSmallUint(o);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readOptionalUint() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readOptionalUint(o);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekUshort() {
|
|
||||||
return dexBuf.readUshort(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUshort() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readUshort(offset);
|
|
||||||
offset = o + 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int peekUbyte() {
|
|
||||||
return dexBuf.readUbyte(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readUbyte() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readUbyte(offset);
|
|
||||||
offset = o + 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readLong() {
|
|
||||||
int o = offset;
|
|
||||||
long result = dexBuf.readLong(offset);
|
|
||||||
offset = o + 8;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readInt() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readInt(offset);
|
|
||||||
offset = o + 4;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readShort() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readShort(offset);
|
|
||||||
offset = o + 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readByte() {
|
|
||||||
int o = offset;
|
|
||||||
int result = dexBuf.readByte(offset);
|
|
||||||
offset = o + 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void skipByte() { offset++; }
|
|
||||||
public void moveRelative(int i) { offset += i; }
|
|
||||||
|
|
||||||
public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
|
|
||||||
public int readUshort(int offset) { return dexBuf.readUshort(offset); }
|
|
||||||
public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
|
|
||||||
public long readLong(int offset) { return dexBuf.readLong(offset); }
|
|
||||||
public int readInt(int offset) { return dexBuf.readInt(offset); }
|
|
||||||
public int readShort(int offset) { return dexBuf.readShort(offset); }
|
|
||||||
public int readByte(int offset) { return dexBuf.readByte(offset); }
|
|
||||||
|
|
||||||
public int readSizedInt(int bytes) {
|
|
||||||
int o = offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(buf[o+3] << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2]) << 16);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1]) << 8);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSizedSmallUint(int bytes) {
|
|
||||||
int o = offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result = 0;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
int b = buf[o+3];
|
|
||||||
if (b < 0) {
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Encountered valid sized uint that is out of range at offset 0x%x", offset);
|
|
||||||
}
|
|
||||||
result = b << 24;
|
|
||||||
// fall-through
|
|
||||||
case 3:
|
|
||||||
result |= (buf[o+2] & 0xff) << 16;
|
|
||||||
// fall-through
|
|
||||||
case 2:
|
|
||||||
result |= (buf[o+1] & 0xff) << 8;
|
|
||||||
// fall-through
|
|
||||||
case 1:
|
|
||||||
result |= (buf[o] & 0xff);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int readSizedRightExtendedInt(int bytes) {
|
|
||||||
int o = offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(buf[o+3] << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) << 8 |
|
|
||||||
((buf[o+1] & 0xff) << 16) |
|
|
||||||
(buf[o+2] << 24);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) << 16 |
|
|
||||||
(buf[o+1] << 24);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o] << 24;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readSizedRightExtendedLong(int bytes) {
|
|
||||||
int o = offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
long result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 8:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((buf[o+6] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+7]) << 56);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result = ((buf[o] & 0xff)) << 8 |
|
|
||||||
((buf[o+1] & 0xff) << 16) |
|
|
||||||
((buf[o+2] & 0xffL) << 24) |
|
|
||||||
((buf[o+3] & 0xffL) << 32) |
|
|
||||||
((buf[o+4] & 0xffL) << 40) |
|
|
||||||
((buf[o+5] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+6]) << 56);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
result = ((buf[o] & 0xff)) << 16 |
|
|
||||||
((buf[o+1] & 0xffL) << 24) |
|
|
||||||
((buf[o+2] & 0xffL) << 32) |
|
|
||||||
((buf[o+3] & 0xffL) << 40) |
|
|
||||||
((buf[o+4] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+5]) << 56);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result = ((buf[o] & 0xffL)) << 24 |
|
|
||||||
((buf[o+1] & 0xffL) << 32) |
|
|
||||||
((buf[o+2] & 0xffL) << 40) |
|
|
||||||
((buf[o+3] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+4]) << 56);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
result = ((buf[o] & 0xffL)) << 32 |
|
|
||||||
((buf[o+1] & 0xffL) << 40) |
|
|
||||||
((buf[o+2] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+3]) << 56);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = ((buf[o] & 0xffL)) << 40 |
|
|
||||||
((buf[o+1] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+2]) << 56);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = ((buf[o] & 0xffL)) << 48 |
|
|
||||||
(((long)buf[o+1]) << 56);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = ((long)buf[o]) << 56;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext(
|
|
||||||
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
offset = o + bytes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readSizedLong(int bytes) {
|
|
||||||
int o = offset;
|
|
||||||
byte[] buf = dexBuf.buf;
|
|
||||||
|
|
||||||
long result;
|
|
||||||
switch (bytes) {
|
|
||||||
case 8:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((buf[o+6] & 0xffL) << 48) |
|
|
||||||
(((long)buf[o+7]) << 56);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((buf[o+5] & 0xffL) << 40) |
|
|
||||||
((long)(buf[o+6]) << 48);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((buf[o+4] & 0xffL) << 32) |
|
|
||||||
((long)(buf[o+5]) << 40);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
((buf[o+3] & 0xffL) << 24) |
|
|
||||||
((long)(buf[o+4]) << 32);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
((buf[o+2] & 0xff) << 16) |
|
|
||||||
(((long)buf[o+3]) << 24);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
((buf[o+1] & 0xff) << 8) |
|
|
||||||
(buf[o+2] << 16);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result = (buf[o] & 0xff) |
|
|
||||||
(buf[o+1] << 8);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
result = buf[o];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = o + bytes;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, Google Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of Google Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.dexlib2.dexbacked;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public class BareDexBuffer extends DexBuffer {
|
|
||||||
public BareDexBuffer(@Nonnull byte[] buf) {
|
|
||||||
super(buf, true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,92 +39,92 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class DexBufferTest {
|
public class BaseDexBufferTest {
|
||||||
@Test
|
@Test
|
||||||
public void testReadSmallUintSuccess() {
|
public void testReadSmallUintSuccess() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge1() {
|
public void testReadSmallUintTooLarge1() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge2() {
|
public void testReadSmallUintTooLarge2() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadSmallUintTooLarge3() {
|
public void testReadSmallUintTooLarge3() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadOptionalUintSuccess() {
|
public void testReadOptionalUintSuccess() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x44332211, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
Assert.assertEquals(0x7fffffff, dexBuf.readSmallUint(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readOptionalUint(0));
|
Assert.assertEquals(-1, dexBuf.readOptionalUint(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge1() {
|
public void testReadOptionalUintTooLarge1() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge2() {
|
public void testReadOptionalUintTooLarge2() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExceptionWithContext.class)
|
@Test(expected=ExceptionWithContext.class)
|
||||||
public void testReadOptionalUintTooLarge3() {
|
public void testReadOptionalUintTooLarge3() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {(byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {(byte)0xfe, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
dexBuf.readSmallUint(0);
|
dexBuf.readSmallUint(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUshort() {
|
public void testReadUshort() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x11, 0x22});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x2211);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x2211);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0);
|
Assert.assertEquals(dexBuf.readUshort(0), 0);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0xffff);
|
Assert.assertEquals(dexBuf.readUshort(0), 0xffff);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x8000);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x8000);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
||||||
Assert.assertEquals(dexBuf.readUshort(0), 0x7fff);
|
Assert.assertEquals(dexBuf.readUshort(0), 0x7fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadUbyte() {
|
public void testReadUbyte() {
|
||||||
byte[] buf = new byte[1];
|
byte[] buf = new byte[1];
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<=0xff; i++) {
|
for (int i=0; i<=0xff; i++) {
|
||||||
buf[0] = (byte)i;
|
buf[0] = (byte)i;
|
||||||
@ -134,24 +134,24 @@ public class DexBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadLong() {
|
public void testReadLong() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77});
|
||||||
Assert.assertEquals(0x7766554433221100L, dexBuf.readLong(0));
|
Assert.assertEquals(0x7766554433221100L, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readLong(0));
|
Assert.assertEquals(0, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(Long.MAX_VALUE, dexBuf.readLong(0));
|
Assert.assertEquals(Long.MAX_VALUE, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80});
|
||||||
Assert.assertEquals(Long.MIN_VALUE, dexBuf.readLong(0));
|
Assert.assertEquals(Long.MIN_VALUE, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(0x80ffffffffffffffL, dexBuf.readLong(0));
|
Assert.assertEquals(0x80ffffffffffffffL, dexBuf.readLong(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readLong(0));
|
Assert.assertEquals(-1, dexBuf.readLong(0));
|
||||||
|
|
||||||
@ -159,50 +159,50 @@ public class DexBufferTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInt() {
|
public void testReadInt() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22, 0x33, 0x44});
|
||||||
Assert.assertEquals(0x44332211, dexBuf.readInt(0));
|
Assert.assertEquals(0x44332211, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, 0x00});
|
||||||
Assert.assertEquals(0, dexBuf.readInt(0));
|
Assert.assertEquals(0, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, 0x7f});
|
||||||
Assert.assertEquals(Integer.MAX_VALUE, dexBuf.readInt(0));
|
Assert.assertEquals(Integer.MAX_VALUE, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00, 0x00, (byte)0x80});
|
||||||
Assert.assertEquals(Integer.MIN_VALUE, dexBuf.readInt(0));
|
Assert.assertEquals(Integer.MIN_VALUE, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(0x80ffffff, dexBuf.readInt(0));
|
Assert.assertEquals(0x80ffffff, dexBuf.readInt(0));
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(-1, dexBuf.readInt(0));
|
Assert.assertEquals(-1, dexBuf.readInt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadShort() {
|
public void testReadShort() {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(new byte[] {0x11, 0x22});
|
BaseDexBuffer dexBuf = new BaseDexBuffer(new byte[] {0x11, 0x22});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0x2211);
|
Assert.assertEquals(dexBuf.readShort(0), 0x2211);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {0x00, 0x00});
|
dexBuf = new BaseDexBuffer(new byte[] {0x00, 0x00});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0);
|
Assert.assertEquals(dexBuf.readShort(0), 0);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0xff});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), -1);
|
Assert.assertEquals(dexBuf.readShort(0), -1);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0x00, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), Short.MIN_VALUE);
|
Assert.assertEquals(dexBuf.readShort(0), Short.MIN_VALUE);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x7f});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0x7fff);
|
Assert.assertEquals(dexBuf.readShort(0), 0x7fff);
|
||||||
|
|
||||||
dexBuf = new BareDexBuffer(new byte[] {(byte)0xff, (byte)0x80});
|
dexBuf = new BaseDexBuffer(new byte[] {(byte)0xff, (byte)0x80});
|
||||||
Assert.assertEquals(dexBuf.readShort(0), 0xffff80ff);
|
Assert.assertEquals(dexBuf.readShort(0), 0xffff80ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadByte() {
|
public void testReadByte() {
|
||||||
byte[] buf = new byte[1];
|
byte[] buf = new byte[1];
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<=0xff; i++) {
|
for (int i=0; i<=0xff; i++) {
|
||||||
buf[0] = (byte)i;
|
buf[0] = (byte)i;
|
||||||
@ -215,7 +215,7 @@ public class DexBufferTest {
|
|||||||
Random r = new Random(1234567890);
|
Random r = new Random(1234567890);
|
||||||
ByteBuffer byteBuf = ByteBuffer.allocateDirect(4).order(ByteOrder.LITTLE_ENDIAN);
|
ByteBuffer byteBuf = ByteBuffer.allocateDirect(4).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
byte[] buf = new byte[4];
|
byte[] buf = new byte[4];
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<10000; i++) {
|
for (int i=0; i<10000; i++) {
|
||||||
int val = r.nextInt();
|
int val = r.nextInt();
|
||||||
@ -249,7 +249,7 @@ public class DexBufferTest {
|
|||||||
Random r = new Random(1234567890);
|
Random r = new Random(1234567890);
|
||||||
ByteBuffer byteBuf = ByteBuffer.allocateDirect(8).order(ByteOrder.LITTLE_ENDIAN);
|
ByteBuffer byteBuf = ByteBuffer.allocateDirect(8).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
byte[] buf = new byte[8];
|
byte[] buf = new byte[8];
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
|
|
||||||
for (int i=0; i<10000; i++) {
|
for (int i=0; i<10000; i++) {
|
||||||
int val = r.nextInt();
|
int val = r.nextInt();
|
@ -35,7 +35,7 @@ import junit.framework.Assert;
|
|||||||
import org.jf.util.ExceptionWithContext;
|
import org.jf.util.ExceptionWithContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class DexFileReaderLeb128Test {
|
public class BaseDexReaderLeb128Test {
|
||||||
@Test
|
@Test
|
||||||
public void testUleb128() {
|
public void testUleb128() {
|
||||||
performTest(0x0, new byte[]{0x0, 0x11}, 1);
|
performTest(0x0, new byte[]{0x0, 0x11}, 1);
|
||||||
@ -246,8 +246,8 @@ public class DexFileReaderLeb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSmallUleb128());
|
Assert.assertEquals(expectedValue, reader.readSmallUleb128());
|
||||||
Assert.assertEquals(expectedLength, reader.getOffset());
|
Assert.assertEquals(expectedLength, reader.getOffset());
|
||||||
|
|
||||||
@ -257,8 +257,8 @@ public class DexFileReaderLeb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performFailureTest(byte[] buf) {
|
private void performFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSmallUleb128();
|
reader.readSmallUleb128();
|
||||||
Assert.fail();
|
Assert.fail();
|
@ -35,7 +35,7 @@ import junit.framework.Assert;
|
|||||||
import org.jf.util.ExceptionWithContext;
|
import org.jf.util.ExceptionWithContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class DexReaderSleb128Test {
|
public class BaseDexReaderSleb128Test {
|
||||||
@Test
|
@Test
|
||||||
public void testSleb128() {
|
public void testSleb128() {
|
||||||
performTest(0x0, new byte[]{0x0, 0x11}, 1);
|
performTest(0x0, new byte[]{0x0, 0x11}, 1);
|
||||||
@ -253,15 +253,15 @@ public class DexReaderSleb128Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
private void performTest(int expectedValue, byte[] buf, int expectedLength) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSleb128());
|
Assert.assertEquals(expectedValue, reader.readSleb128());
|
||||||
Assert.assertEquals(expectedLength, reader.getOffset());
|
Assert.assertEquals(expectedLength, reader.getOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performFailureTest(byte[] buf) {
|
private void performFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSleb128();
|
reader.readSleb128();
|
||||||
Assert.fail();
|
Assert.fail();
|
@ -35,7 +35,7 @@ import junit.framework.Assert;
|
|||||||
import org.jf.util.ExceptionWithContext;
|
import org.jf.util.ExceptionWithContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class DexReaderTest {
|
public class BaseDexReaderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSizedInt() {
|
public void testSizedInt() {
|
||||||
performSizedIntTest(0, new byte[]{0x00});
|
performSizedIntTest(0, new byte[]{0x00});
|
||||||
@ -67,8 +67,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedIntTest(int expectedValue, byte[] buf) {
|
private void performSizedIntTest(int expectedValue, byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedInt(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedInt(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +82,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedIntFailureTest(byte[] buf) {
|
private void performSizedIntFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedInt(buf.length);
|
reader.readSizedInt(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -122,8 +122,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedSmallUintTest(int expectedValue, byte[] buf) {
|
private void performSizedSmallUintTest(int expectedValue, byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedSmallUint(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedSmallUint(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +141,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedSmallUintFailureTest(byte[] buf) {
|
private void performSizedSmallUintFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedSmallUint(buf.length);
|
reader.readSizedSmallUint(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -192,8 +192,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedIntTest(int expectedValue, byte[] buf) {
|
private void performSizedRightExtendedIntTest(int expectedValue, byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedInt(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedInt(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,8 +207,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedIntFailureTest(byte[] buf) {
|
private void performSizedRightExtendedIntFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedRightExtendedInt(buf.length);
|
reader.readSizedRightExtendedInt(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -301,8 +301,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedLongTest(long expectedValue, byte[] buf) {
|
private void performSizedRightExtendedLongTest(long expectedValue, byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedLong(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedRightExtendedLong(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,8 +316,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedRightExtendedLongFailureTest(byte[] buf) {
|
private void performSizedRightExtendedLongFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedRightExtendedLong(buf.length);
|
reader.readSizedRightExtendedLong(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -410,8 +410,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedLongTest(long expectedValue, byte[] buf) {
|
private void performSizedLongTest(long expectedValue, byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
Assert.assertEquals(expectedValue, reader.readSizedLong(buf.length));
|
Assert.assertEquals(expectedValue, reader.readSizedLong(buf.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,8 +425,8 @@ public class DexReaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void performSizedLongFailureTest(byte[] buf) {
|
private void performSizedLongFailureTest(byte[] buf) {
|
||||||
BareDexBuffer dexBuf = new BareDexBuffer(buf);
|
BaseDexBuffer dexBuf = new BaseDexBuffer(buf);
|
||||||
DexReader reader = dexBuf.readerAt(0);
|
BaseDexReader reader = dexBuf.readerAt(0);
|
||||||
try {
|
try {
|
||||||
reader.readSizedLong(buf.length);
|
reader.readSizedLong(buf.length);
|
||||||
Assert.fail();
|
Assert.fail();
|
Loading…
x
Reference in New Issue
Block a user