From 39d2c38685d4091114bdc143eef6e60d3d26a009 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 21 Oct 2012 14:29:19 -0700 Subject: [PATCH] Add tests for the various "sized" types in DexReader --- .../org/jf/dexlib2/dexbacked/DexReader.java | 32 +- .../jf/dexlib2/dexbacked/DexReaderTest.java | 437 ++++++++++++++++++ 2 files changed, 453 insertions(+), 16 deletions(-) create mode 100644 dexlib2/src/test/java/org/jf/dexlib2/dexbacked/DexReaderTest.java diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexReader.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexReader.java index a8e46ab7..e77213ff 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexReader.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexReader.java @@ -271,7 +271,7 @@ public class DexReader { throw new ExceptionWithContext( "Encountered valid sized uint that is out of range at offset 0x%x", offset); } - result = (b & 0xff) << 24; + result = b << 24; // fall-through case 3: result |= (buf[o+2] & 0xff) << 16; @@ -331,7 +331,7 @@ public class DexReader { result = (buf[o] & 0xff) | ((buf[o+1] & 0xff) << 8) | ((buf[o+2] & 0xff) << 16) | - ((buf[o+3] & 0xff) << 24) | + ((buf[o+3] & 0xffL) << 24) | ((buf[o+4] & 0xffL) << 32) | ((buf[o+5] & 0xffL) << 40) | ((buf[o+6] & 0xffL) << 48) | @@ -340,7 +340,7 @@ public class DexReader { case 7: result = ((buf[o] & 0xff)) << 8 | ((buf[o+1] & 0xff) << 16) | - ((buf[o+2] & 0xff) << 24) | + ((buf[o+2] & 0xffL) << 24) | ((buf[o+3] & 0xffL) << 32) | ((buf[o+4] & 0xffL) << 40) | ((buf[o+5] & 0xffL) << 48) | @@ -348,14 +348,14 @@ public class DexReader { break; case 6: result = ((buf[o] & 0xff)) << 16 | - ((buf[o+1] & 0xff) << 24) | + ((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] & 0xff)) << 24 | + result = ((buf[o] & 0xffL)) << 24 | ((buf[o+1] & 0xffL) << 32) | ((buf[o+2] & 0xffL) << 40) | ((buf[o+3] & 0xffL) << 48) | @@ -397,7 +397,7 @@ public class DexReader { result = (buf[o] & 0xff) | ((buf[o+1] & 0xff) << 8) | ((buf[o+2] & 0xff) << 16) | - ((buf[o+3] & 0xff) << 24) | + ((buf[o+3] & 0xffL) << 24) | ((buf[o+4] & 0xffL) << 32) | ((buf[o+5] & 0xffL) << 40) | ((buf[o+6] & 0xffL) << 48) | @@ -407,7 +407,7 @@ public class DexReader { result = (buf[o] & 0xff) | ((buf[o+1] & 0xff) << 8) | ((buf[o+2] & 0xff) << 16) | - ((buf[o+3] & 0xff) << 24) | + ((buf[o+3] & 0xffL) << 24) | ((buf[o+4] & 0xffL) << 32) | ((buf[o+5] & 0xffL) << 40) | ((long)(buf[o+6]) << 48); @@ -416,7 +416,7 @@ public class DexReader { result = (buf[o] & 0xff) | ((buf[o+1] & 0xff) << 8) | ((buf[o+2] & 0xff) << 16) | - ((buf[o+3] & 0xff) << 24) | + ((buf[o+3] & 0xffL) << 24) | ((buf[o+4] & 0xffL) << 32) | ((long)(buf[o+5]) << 40); break; @@ -424,26 +424,26 @@ public class DexReader { result = (buf[o] & 0xff) | ((buf[o+1] & 0xff) << 8) | ((buf[o+2] & 0xff) << 16) | - ((buf[o+3] & 0xff) << 24) | + ((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) | - (buf[o+3] << 24); + (((long)buf[o+3]) << 24); break; case 3: - result = (buf[o] & 0xff) << 8 | - ((buf[o+1] & 0xff) << 16) | - (buf[o+2] << 24); + result = (buf[o] & 0xff) | + ((buf[o+1] & 0xff) << 8) | + (buf[o+2] << 16); break; case 2: - result = (buf[o] & 0xff) << 16 | - (buf[o+1] << 24); + result = (buf[o] & 0xff) | + (buf[o+1] << 8); break; case 1: - result = buf[o] << 24; + result = buf[o]; break; default: throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset); diff --git a/dexlib2/src/test/java/org/jf/dexlib2/dexbacked/DexReaderTest.java b/dexlib2/src/test/java/org/jf/dexlib2/dexbacked/DexReaderTest.java new file mode 100644 index 00000000..2423a77a --- /dev/null +++ b/dexlib2/src/test/java/org/jf/dexlib2/dexbacked/DexReaderTest.java @@ -0,0 +1,437 @@ +/* + * 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 junit.framework.Assert; +import org.jf.util.ExceptionWithContext; +import org.junit.Test; + +public class DexReaderTest { + @Test + public void testSizedInt() { + performSizedIntTest(0, new byte[]{0x00}); + performSizedIntTest(0, new byte[]{0x00, 0x00}); + performSizedIntTest(0, new byte[]{0x00, 0x00, 0x00}); + performSizedIntTest(0, new byte[]{0x00, 0x00, 0x00, 0x00}); + performSizedIntTest(1, new byte[]{0x01}); + performSizedIntTest(1, new byte[]{0x01, 0x00, 0x00, 0x00}); + performSizedIntTest(0x40, new byte[]{0x40}); + performSizedIntTest(0x7f, new byte[]{0x7f}); + performSizedIntTest(0xffffff80, new byte[]{(byte)0x80}); + performSizedIntTest(-1, new byte[]{(byte)0xff}); + + performSizedIntTest(0x100, new byte[]{0x00, 0x01}); + performSizedIntTest(0x110, new byte[]{0x10, 0x01}); + performSizedIntTest(0x7f01, new byte[]{0x01, 0x7f}); + performSizedIntTest(0xffff8001, new byte[]{0x01, (byte)0x80}); + performSizedIntTest(0xffffff10, new byte[]{0x10, (byte)0xff}); + + performSizedIntTest(0x11001, new byte[]{0x01, 0x10, 0x01}); + performSizedIntTest(0x7f0110, new byte[]{0x10, 0x01, 0x7f}); + performSizedIntTest(0xff801001, new byte[]{0x01, 0x10, (byte)0x80}); + performSizedIntTest(0xffff0110, new byte[]{0x10, 0x01, (byte)0xff}); + + performSizedIntTest(0x1003002, new byte[]{0x02, 0x30, 0x00, 0x01}); + performSizedIntTest(0x7f110230, new byte[]{0x30, 0x02, 0x11, 0x7f}); + performSizedIntTest(0x80112233, new byte[]{0x33, 0x22, 0x11, (byte)0x80}); + performSizedIntTest(-1, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}); + } + + private void performSizedIntTest(int expectedValue, byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + Assert.assertEquals(expectedValue, reader.readSizedInt(buf.length)); + } + + @Test + public void testSizedIntFailure() { + // wrong size + performSizedIntFailureTest(new byte[]{}); + performSizedIntFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedIntFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedIntFailureTest(new byte[]{0x12, 0x34, 0x56, 0x12, 0x34, 0x56, 0x78}); + } + + private void performSizedIntFailureTest(byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + try { + reader.readSizedInt(buf.length); + Assert.fail(); + } catch (ExceptionWithContext ex) { + // expected + } + } + + @Test + public void testSizedSmallUint() { + performSizedSmallUintTest(0, new byte[]{0x00}); + performSizedSmallUintTest(0, new byte[]{0x00, 0x00}); + performSizedSmallUintTest(0, new byte[]{0x00, 0x00, 0x00}); + performSizedSmallUintTest(0, new byte[]{0x00, 0x00, 0x00, 0x00}); + performSizedSmallUintTest(1, new byte[]{0x01}); + performSizedSmallUintTest(1, new byte[]{0x01, 0x00, 0x00, 0x00}); + performSizedSmallUintTest(0x40, new byte[]{0x40}); + performSizedSmallUintTest(0x7f, new byte[]{0x7f}); + performSizedSmallUintTest(0x80, new byte[]{(byte)0x80}); + performSizedSmallUintTest(0xff, new byte[]{(byte)0xff}); + + performSizedSmallUintTest(0x100, new byte[]{0x00, 0x01}); + performSizedSmallUintTest(0x110, new byte[]{0x10, 0x01}); + performSizedSmallUintTest(0x7f01, new byte[]{0x01, 0x7f}); + performSizedSmallUintTest(0x8001, new byte[]{0x01, (byte)0x80}); + performSizedSmallUintTest(0xff10, new byte[]{0x10, (byte)0xff}); + + performSizedSmallUintTest(0x11001, new byte[]{0x01, 0x10, 0x01}); + performSizedSmallUintTest(0x7f0110, new byte[]{0x10, 0x01, 0x7f}); + performSizedSmallUintTest(0x801001, new byte[]{0x01, 0x10, (byte)0x80}); + performSizedSmallUintTest(0xff0110, new byte[]{0x10, 0x01, (byte)0xff}); + + performSizedSmallUintTest(0x1003002, new byte[]{0x02, 0x30, 0x00, 0x01}); + performSizedSmallUintTest(0x7f110230, new byte[]{0x30, 0x02, 0x11, 0x7f}); + performSizedSmallUintTest(Integer.MAX_VALUE, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, 0x7f}); + } + + private void performSizedSmallUintTest(int expectedValue, byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + Assert.assertEquals(expectedValue, reader.readSizedSmallUint(buf.length)); + } + + @Test + public void testSizedSmallUintFailure() { + // wrong size + performSizedSmallUintFailureTest(new byte[]{}); + performSizedSmallUintFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedSmallUintFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedSmallUintFailureTest(new byte[]{0x12, 0x34, 0x56, 0x12, 0x34, 0x56, 0x78}); + + // MSB set + performSizedSmallUintFailureTest(new byte[]{0x00, 0x00, 0x00, (byte)0x80}); + performSizedSmallUintFailureTest(new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}); + } + + private void performSizedSmallUintFailureTest(byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + try { + reader.readSizedSmallUint(buf.length); + Assert.fail(); + } catch (ExceptionWithContext ex) { + // expected + } + } + + @Test + public void testSizedRightExtendedInt() { + performSizedRightExtendedIntTest(0, new byte[]{0x00}); + performSizedRightExtendedIntTest(0, new byte[]{0x00, 0x00}); + performSizedRightExtendedIntTest(0, new byte[]{0x00, 0x00, 0x00}); + performSizedRightExtendedIntTest(0, new byte[]{0x00, 0x00, 0x00, 0x00}); + + performSizedRightExtendedIntTest(0x01000000, new byte[]{0x01}); + performSizedRightExtendedIntTest(0x7f000000, new byte[]{0x7f}); + performSizedRightExtendedIntTest(0x80000000, new byte[]{(byte) 0x80}); + performSizedRightExtendedIntTest(0xf0000000, new byte[]{(byte) 0xf0}); + performSizedRightExtendedIntTest(0xff000000, new byte[]{(byte) 0xff}); + + performSizedRightExtendedIntTest(0x010000, new byte[]{0x01, 0x00}); + performSizedRightExtendedIntTest(0x01100000, new byte[]{0x10, 0x01}); + performSizedRightExtendedIntTest(0x7f100000, new byte[]{0x10, 0x7f}); + performSizedRightExtendedIntTest(0x80100000, new byte[]{0x10, (byte) 0x80}); + performSizedRightExtendedIntTest(0xf0100000, new byte[]{0x10, (byte) 0xf0}); + performSizedRightExtendedIntTest(0xff100000, new byte[]{0x10, (byte) 0xff}); + performSizedRightExtendedIntTest(0xff000000, new byte[]{0x00, (byte) 0xff}); + + performSizedRightExtendedIntTest(0x0100, new byte[]{0x01, 0x00, 0x00}); + performSizedRightExtendedIntTest(0x01101000, new byte[]{0x10, 0x10, 0x01}); + performSizedRightExtendedIntTest(0x7f101000, new byte[]{0x10, 0x10, 0x7f}); + performSizedRightExtendedIntTest(0x80101000, new byte[]{0x10, 0x10, (byte) 0x80}); + performSizedRightExtendedIntTest(0xf0101000, new byte[]{0x10, 0x10, (byte) 0xf0}); + performSizedRightExtendedIntTest(0xff101000, new byte[]{0x10, 0x10, (byte) 0xff}); + performSizedRightExtendedIntTest(0xff000000, new byte[]{0x00, 0x00, (byte) 0xff}); + + performSizedRightExtendedIntTest(0x01, new byte[]{0x01, 0x00, 0x00, 0x00}); + performSizedRightExtendedIntTest(0x80, new byte[]{(byte) 0x80, 0x00, 0x00, 0x00}); + performSizedRightExtendedIntTest(0xff, new byte[]{(byte) 0xff, 0x00, 0x00, 0x00}); + performSizedRightExtendedIntTest(0x01101010, new byte[]{0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedIntTest(0x7f101010, new byte[]{0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedIntTest(0x80101010, new byte[]{0x10, 0x10, 0x10, (byte) 0x80}); + performSizedRightExtendedIntTest(0xf0101010, new byte[]{0x10, 0x10, 0x10, (byte) 0xf0}); + performSizedRightExtendedIntTest(0xff101010, new byte[]{0x10, 0x10, 0x10, (byte) 0xff}); + performSizedRightExtendedIntTest(0xff000000, new byte[]{0x00, 0x00, 0x00, (byte) 0xff}); + } + + private void performSizedRightExtendedIntTest(int expectedValue, byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + Assert.assertEquals(expectedValue, reader.readSizedRightExtendedInt(buf.length)); + } + + @Test + public void testSizedRightExtendedIntFailure() { + // wrong size + performSizedRightExtendedIntFailureTest(new byte[]{}); + performSizedRightExtendedIntFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedIntFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedIntFailureTest(new byte[]{0x12, 0x34, 0x56, 0x12, 0x34, 0x56, 0x78}); + } + + private void performSizedRightExtendedIntFailureTest(byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + try { + reader.readSizedRightExtendedInt(buf.length); + Assert.fail(); + } catch (ExceptionWithContext ex) { + // expected + } + } + + @Test + public void testSizedRightExtendedLong() { + performSizedRightExtendedLongTest(0, new byte[]{0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + + performSizedRightExtendedLongTest(0x0100000000000000L, new byte[]{0x01}); + performSizedRightExtendedLongTest(0x7f00000000000000L, new byte[]{0x7f}); + performSizedRightExtendedLongTest(0x8000000000000000L, new byte[]{(byte)0x80}); + performSizedRightExtendedLongTest(0xf000000000000000L, new byte[]{(byte)0xf0}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{(byte)0xff}); + + performSizedRightExtendedLongTest(0x01000000000000L, new byte[]{0x01, 0x00}); + performSizedRightExtendedLongTest(0x0110000000000000L, new byte[]{0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10000000000000L, new byte[]{0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010000000000000L, new byte[]{0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010000000000000L, new byte[]{0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10000000000000L, new byte[]{0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fff000000000000L, new byte[]{(byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x010000000000L, new byte[]{0x01, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110100000000000L, new byte[]{0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10100000000000L, new byte[]{0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010100000000000L, new byte[]{0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010100000000000L, new byte[]{0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10100000000000L, new byte[]{0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fffff0000000000L, new byte[]{(byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x0100000000L, new byte[]{0x01, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110101000000000L, new byte[]{0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10101000000000L, new byte[]{0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010101000000000L, new byte[]{0x10, 0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010101000000000L, new byte[]{0x10, 0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10101000000000L, new byte[]{0x10, 0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fffffff00000000L, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x01000000L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110101010000000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10101010000000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010101010000000L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010101010000000L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10101010000000L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fffffffff000000L, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x010000L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110101010100000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10101010100000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010101010100000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010101010100000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10101010100000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fffffffffff0000L, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x0100L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110101010101000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10101010101000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010101010101000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010101010101000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10101010101000L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(0x7fffffffffffff00L, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedRightExtendedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongTest(0x0110101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedRightExtendedLongTest(0x7f10101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedRightExtendedLongTest(0x8010101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedRightExtendedLongTest(0xf010101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedRightExtendedLongTest(0xff10101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedRightExtendedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedRightExtendedLongTest(Long.MAX_VALUE, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + performSizedRightExtendedLongTest(Long.MIN_VALUE, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80}); + performSizedRightExtendedLongTest(-1, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}); + } + + private void performSizedRightExtendedLongTest(long expectedValue, byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + Assert.assertEquals(expectedValue, reader.readSizedRightExtendedLong(buf.length)); + } + + @Test + public void testSizedRightExtendedLongFailure() { + // wrong size + performSizedRightExtendedLongFailureTest(new byte[]{}); + performSizedRightExtendedLongFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedRightExtendedLongFailureTest(new byte[]{0x12, 0x34, 0x56, 0x12, 0x34, 0x56, 0x78, (byte)0x89, (byte)0x90, 0x01}); + } + + private void performSizedRightExtendedLongFailureTest(byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + try { + reader.readSizedRightExtendedLong(buf.length); + Assert.fail(); + } catch (ExceptionWithContext ex) { + // expected + } + } + + @Test + public void testSizedLong() { + performSizedLongTest(0, new byte[]{0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + + performSizedLongTest(0x01L, new byte[]{0x01}); + performSizedLongTest(0x7fL, new byte[]{0x7f}); + performSizedLongTest(0xffffffffffffff80L, new byte[]{(byte)0x80}); + performSizedLongTest(0xfffffffffffffff0L, new byte[]{(byte)0xf0}); + performSizedLongTest(0xffffffffffffffffL, new byte[]{(byte)0xff}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00}); + performSizedLongTest(0x0110L, new byte[]{0x10, 0x01}); + performSizedLongTest(0x7f10L, new byte[]{0x10, 0x7f}); + performSizedLongTest(0xffffffffffff8010L, new byte[]{0x10, (byte)0x80}); + performSizedLongTest(0xfffffffffffff010L, new byte[]{0x10, (byte)0xf0}); + performSizedLongTest(0xffffffffffffff10L, new byte[]{0x10, (byte)0xff}); + performSizedLongTest(0xffffffffffffff00L, new byte[]{0x00, (byte)0xff}); + performSizedLongTest(0x7fffL, new byte[]{(byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00}); + performSizedLongTest(0x011010L, new byte[]{0x10, 0x10, 0x01}); + performSizedLongTest(0x7f1010L, new byte[]{0x10, 0x10, 0x7f}); + performSizedLongTest(0xffffffffff801010L, new byte[]{0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xfffffffffff01010L, new byte[]{0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xffffffffffff1010L, new byte[]{0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xffffffffffff0000L, new byte[]{0x00, 0x00, (byte)0xff}); + performSizedLongTest(0x7fffffL, new byte[]{(byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00, 0x00}); + performSizedLongTest(0x01101010L, new byte[]{0x10, 0x10, 0x10, 0x01}); + performSizedLongTest(0x7f101010L, new byte[]{0x10, 0x10, 0x10, 0x7f}); + performSizedLongTest(0xffffffff80101010L, new byte[]{0x10, 0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xfffffffff0101010l, new byte[]{0x10, 0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xffffffffff101010L, new byte[]{0x10, 0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xffffffffff000000L, new byte[]{0x00, 0x00, 0x00, (byte)0xff}); + performSizedLongTest(0x7fffffffL, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0x0110101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedLongTest(0x7f10101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedLongTest(0xffffff8010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xfffffff010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xffffffff10101010L, new byte[]{0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xffffffff00000000L, new byte[]{0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedLongTest(0x7fffffffffL, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0x011010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedLongTest(0x7f1010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedLongTest(0xffff801010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xfffff01010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xffffff1010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xffffff0000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedLongTest(0x7fffffffffffL, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0x01101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedLongTest(0x7f101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedLongTest(0xff80101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xfff0101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xffff101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xffff000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedLongTest(0x7fffffffffffffL, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + + performSizedLongTest(0x01L, new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongTest(0x0110101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x01}); + performSizedLongTest(0x7f10101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7f}); + performSizedLongTest(0x8010101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0x80}); + performSizedLongTest(0xf010101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xf0}); + performSizedLongTest(0xff10101010101010L, new byte[]{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, (byte)0xff}); + performSizedLongTest(0xff00000000000000L, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff}); + performSizedLongTest(Long.MAX_VALUE, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x7f}); + performSizedLongTest(Long.MIN_VALUE, new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80}); + performSizedLongTest(-1, new byte[]{(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}); + } + + private void performSizedLongTest(long expectedValue, byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + Assert.assertEquals(expectedValue, reader.readSizedLong(buf.length)); + } + + @Test + public void testSizedLongFailure() { + // wrong size + performSizedLongFailureTest(new byte[]{}); + performSizedLongFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongFailureTest(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + performSizedLongFailureTest(new byte[]{0x12, 0x34, 0x56, 0x12, 0x34, 0x56, 0x78, (byte)0x89, (byte)0x90, 0x01}); + } + + private void performSizedLongFailureTest(byte[] buf) { + DexBuffer dexBuf = new DexBuffer(buf); + DexReader reader = dexBuf.readerAt(0); + try { + reader.readSizedLong(buf.length); + Assert.fail(); + } catch (ExceptionWithContext ex) { + // expected + } + } +}