Merge branch 'master' into issue-1498

This commit is contained in:
Marvin Killing
2017-06-09 22:56:04 +02:00
committed by GitHub
39 changed files with 376 additions and 59 deletions

View File

@ -19,6 +19,7 @@ package brut.androlib;
import brut.androlib.meta.MetaInfo;
import brut.androlib.meta.UsesFramework;
import brut.androlib.res.AndrolibResources;
import brut.androlib.res.data.ResConfigFlags;
import brut.androlib.res.data.ResPackage;
import brut.androlib.res.data.ResTable;
import brut.androlib.res.data.ResUnknownFiles;
@ -279,7 +280,22 @@ public class Androlib {
mAndRes.setSharedLibrary(meta.sharedLibrary);
if (meta.sdkInfo != null && meta.sdkInfo.get("minSdkVersion") != null) {
mMinSdkVersion = Integer.parseInt(meta.sdkInfo.get("minSdkVersion"));
String minSdkVersion = meta.sdkInfo.get("minSdkVersion");
// Preview builds use short letter for API versions
switch (minSdkVersion) {
case "M":
mMinSdkVersion = ResConfigFlags.SDK_MNC;
break;
case "N":
mMinSdkVersion = ResConfigFlags.SDK_NOUGAT;
break;
case "O":
mMinSdkVersion = ResConfigFlags.SDK_O;
break;
default:
mMinSdkVersion = Integer.parseInt(meta.sdkInfo.get("minSdkVersion"));
}
}
if (outFile == null) {

View File

@ -507,6 +507,9 @@ public class ResConfigFlags {
public final static byte SDK_LOLLIPOP = 21;
public final static byte SDK_LOLLIPOP_MR1 = 22;
public final static byte SDK_MNC = 23;
public final static byte SDK_NOUGAT = 24;
public final static byte SDK_NOUGAT_MR1 = 25;
public final static byte SDK_O = 26;
public final static byte ORIENTATION_ANY = 0;
public final static byte ORIENTATION_PORT = 1;

View File

@ -90,7 +90,8 @@ public class ResValueFactory {
if (key == ResAttr.BAG_KEY_ATTR_TYPE) {
return ResAttr.factory(parentVal, items, this, mPackage);
}
if (key == ResArrayValue.BAG_KEY_ARRAY_START) {
// Android O Preview added an unknown enum for ResTable_map. This is hardcoded as 0 for now.
if (key == ResArrayValue.BAG_KEY_ARRAY_START || key == 0) {
return new ResArrayValue(parentVal, items);
}
if (key >= ResPluralsValue.BAG_KEY_PLURALS_START && key <= ResPluralsValue.BAG_KEY_PLURALS_END) {

View File

@ -20,6 +20,8 @@ import brut.androlib.AndrolibException;
import brut.androlib.err.CantFind9PatchChunk;
import brut.util.ExtDataInput;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.*;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
@ -39,8 +41,24 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
BufferedImage im = ImageIO.read(new ByteArrayInputStream(data));
int w = im.getWidth(), h = im.getHeight();
BufferedImage im2 = new BufferedImage(w+2, h+2, BufferedImage.TYPE_INT_ARGB);
im2.createGraphics().drawImage(im, 1, 1, w, h, null);
BufferedImage im2 = new BufferedImage(w + 2, h + 2, BufferedImage.TYPE_INT_ARGB);
if (im.getType() == BufferedImage.TYPE_CUSTOM) {
//TODO: Ensure this is gray + alpha case?
Raster srcRaster = im.getRaster();
WritableRaster dstRaster = im2.getRaster();
int[] gray = null, alpha = null;
for (int y = 0; y < im.getHeight(); y++) {
gray = srcRaster.getSamples(0, y, w, 1, 0, gray);
alpha = srcRaster.getSamples(0, y, w, 1, 1, alpha);
dstRaster.setSamples(1, y + 1, w, 1, 0, gray);
dstRaster.setSamples(1, y + 1, w, 1, 1, gray);
dstRaster.setSamples(1, y + 1, w, 1, 2, gray);
dstRaster.setSamples(1, y + 1, w, 1, 3, alpha);
}
} else {
im2.createGraphics().drawImage(im, 1, 1, w, h, null);
}
NinePatch np = getNinePatch(data);
drawHLine(im2, h + 1, np.padLeft + 1, w - np.padRight);
@ -56,6 +74,34 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
drawVLine(im2, 0, yDivs[i] + 1, yDivs[i + 1]);
}
// Some images additionally use Optical Bounds
// https://developer.android.com/about/versions/android-4.3.html#OpticalBounds
try {
OpticalInset oi = getOpticalInset(data);
for (int i = 0; i < oi.layoutBoundsLeft; i++) {
int x = 1 + i;
im2.setRGB(x, h + 1, OI_COLOR);
}
for (int i = 0; i < oi.layoutBoundsRight; i++) {
int x = w - i;
im2.setRGB(x, h + 1, OI_COLOR);
}
for (int i = 0; i < oi.layoutBoundsTop; i++) {
int y = 1 + i;
im2.setRGB(w + 1, y, OI_COLOR);
}
for (int i = 0; i < oi.layoutBoundsBottom; i++) {
int y = h - i;
im2.setRGB(w + 1, y, OI_COLOR);
}
} catch (CantFind9PatchChunk t) {
// This chunk might not exist
}
ImageIO.write(im2, "png", out);
} catch (IOException ex) {
throw new AndrolibException(ex);
@ -70,11 +116,18 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
private NinePatch getNinePatch(byte[] data) throws AndrolibException,
IOException {
ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data));
find9patchChunk(di);
find9patchChunk(di, NP_CHUNK_TYPE);
return NinePatch.decode(di);
}
private void find9patchChunk(DataInput di) throws AndrolibException,
private OpticalInset getOpticalInset(byte[] data) throws AndrolibException,
IOException {
ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data));
find9patchChunk(di, OI_CHUNK_TYPE);
return OpticalInset.decode(di);
}
private void find9patchChunk(DataInput di, int magic) throws AndrolibException,
IOException {
di.skipBytes(8);
while (true) {
@ -84,7 +137,7 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
} catch (IOException ex) {
throw new CantFind9PatchChunk("Cant find nine patch chunk", ex);
}
if (di.readInt() == NP_CHUNK_TYPE) {
if (di.readInt() == magic) {
return;
}
di.skipBytes(size + 4);
@ -104,7 +157,9 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
}
private static final int NP_CHUNK_TYPE = 0x6e705463; // npTc
private static final int OI_CHUNK_TYPE = 0x6e704c62; // npLb
private static final int NP_COLOR = 0xff000000;
private static final int OI_COLOR = 0xffff0000;
private static class NinePatch {
public final int padLeft, padRight, padTop, padBottom;
@ -121,16 +176,16 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
}
public static NinePatch decode(ExtDataInput di) throws IOException {
di.skipBytes(1);
di.skipBytes(1); // wasDeserialized
byte numXDivs = di.readByte();
byte numYDivs = di.readByte();
di.skipBytes(1);
di.skipBytes(8);
di.skipBytes(1); // numColors
di.skipBytes(8); // xDivs/yDivs offset
int padLeft = di.readInt();
int padRight = di.readInt();
int padTop = di.readInt();
int padBottom = di.readInt();
di.skipBytes(4);
di.skipBytes(4); // colorsOffset
int[] xDivs = di.readIntArray(numXDivs);
int[] yDivs = di.readIntArray(numYDivs);
@ -138,4 +193,25 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
yDivs);
}
}
private static class OpticalInset {
public final int layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom;
public OpticalInset(int layoutBoundsLeft, int layoutBoundsTop,
int layoutBoundsRight, int layoutBoundsBottom) {
this.layoutBoundsLeft = layoutBoundsLeft;
this.layoutBoundsTop = layoutBoundsTop;
this.layoutBoundsRight = layoutBoundsRight;
this.layoutBoundsBottom = layoutBoundsBottom;
}
public static OpticalInset decode(ExtDataInput di) throws IOException {
int layoutBoundsLeft = Integer.reverseBytes(di.readInt());
int layoutBoundsTop = Integer.reverseBytes(di.readInt());
int layoutBoundsRight = Integer.reverseBytes(di.readInt());
int layoutBoundsBottom = Integer.reverseBytes(di.readInt());
return new OpticalInset(layoutBoundsLeft, layoutBoundsTop,
layoutBoundsRight, layoutBoundsBottom);
}
}
}

View File

@ -131,8 +131,14 @@ public class StringBlock {
if (style == null) {
return ResXmlEncoders.escapeXmlChars(raw);
}
// If the returned style is further in string, than string length. Lets skip it.
if (style[1] > raw.length()) {
return ResXmlEncoders.escapeXmlChars(raw);
}
StringBuilder html = new StringBuilder(raw.length() + 32);
int[] opened = new int[style.length / 3];
boolean[] unclosed = new boolean[style.length / 3];
int offset = 0, depth = 0;
while (true) {
int i = -1, j;
@ -149,6 +155,9 @@ public class StringBlock {
int last = opened[j];
int end = style[last + 2];
if (end >= start) {
if (style[last + 1] == -1 && end != -1) {
unclosed[j] = true;
}
break;
}
if (offset <= end) {
@ -160,6 +169,11 @@ public class StringBlock {
depth = j + 1;
if (offset < start) {
html.append(ResXmlEncoders.escapeXmlChars(raw.substring(offset, start)));
if (j >= 0 && unclosed.length >= j && unclosed[j]) {
if (unclosed.length > (j + 1) && unclosed[j + 1] || unclosed.length == 1) {
outputStyleTag(getString(style[opened[j]]), html, true);
}
}
offset = start;
}
if (i == -1) {

View File

@ -246,6 +246,8 @@ public final class ResXmlPatcher {
throws IOException, SAXException, ParserConfigurationException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setFeature(FEATURE_DISABLE_DOCTYPE_DECL, true);
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
return docBuilder.parse(file);
}
@ -264,10 +266,10 @@ public final class ResXmlPatcher {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.STANDALONE,"yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
}
private static final String FEATURE_DISABLE_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
}

View File

@ -21,7 +21,6 @@ import brut.common.BrutException;
import brut.util.OS;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import org.junit.*;
import static org.junit.Assert.*;
@ -29,10 +28,10 @@ import static org.junit.Assert.*;
public class AndResGuardTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/issue1170/", sTmpDir);
TestUtils.copyResourceDir(AndResGuardTest.class, "brut/apktool/issue1170/", sTmpDir);
}
@AfterClass
@ -62,6 +61,4 @@ public class AndResGuardTest {
private static ExtFile sTmpDir;
private static ExtFile sTestOrigDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeTest.class.getName());
}
}

View File

@ -33,7 +33,7 @@ import static org.junit.Assert.assertTrue;
public class BuildAndDecodeJarTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
sTestOrigDir = new ExtFile(sTmpDir, "testjar-orig");
@ -66,4 +66,4 @@ public class BuildAndDecodeJarTest {
private static ExtFile sTestNewDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}
}

View File

@ -44,7 +44,7 @@ import javax.imageio.ImageIO;
public class BuildAndDecodeTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
@ -253,6 +253,11 @@ public class BuildAndDecodeTest {
compareValuesFiles("values-ast/strings.xml");
}
@Test
public void androidOStringTest() throws BrutException, IOException {
compareValuesFiles("values-ast/strings.xml");
}
@Test
public void twoLetterNotHandledAsBcpTest() throws BrutException, IOException {
checkFolderExists("res/values-fr");
@ -345,6 +350,89 @@ public class BuildAndDecodeTest {
assertEquals(controlImage.getRGB(30, 30), testImage.getRGB(30, 30));
}
@Test
public void issue1508Test() throws BrutException, IOException {
char slash = File.separatorChar;
String location = slash + "res" + slash + "drawable-xhdpi" + slash;
File control = new File((sTestOrigDir + location), "btn_zoom_up_normal.9.png");
File test = new File((sTestNewDir + location), "btn_zoom_up_normal.9.png");
BufferedImage controlImage = ImageIO.read(control);
BufferedImage testImage = ImageIO.read(test);
// 0, 0 = clear
assertEquals(controlImage.getRGB(0, 0), testImage.getRGB(0, 0));
// 30, 0 = black line
assertEquals(controlImage.getRGB(0, 30), testImage.getRGB(0, 30));
// 30, 30 = greyish button
assertEquals(controlImage.getRGB(30, 30), testImage.getRGB(30, 30));
}
@Test
public void issue1511Test() throws BrutException, IOException {
char slash = File.separatorChar;
String location = slash + "res" + slash + "drawable-xxhdpi" + slash;
File control = new File((sTestOrigDir + location), "textfield_activated_holo_dark.9.png");
File test = new File((sTestNewDir + location), "textfield_activated_holo_dark.9.png");
BufferedImage controlImage = ImageIO.read(control);
BufferedImage testImage = ImageIO.read(test);
// Check entire image as we cannot mess this up
final int w = controlImage.getWidth(),
h = controlImage.getHeight();
final int[] controlImageGrid = controlImage.getRGB(0, 0, w, h, null, 0, w);
final int[] testImageGrid = testImage.getRGB(0, 0, w, h, null, 0, w);
for (int i = 0; i < controlImageGrid.length; i++) {
assertEquals("Image lost Optical Bounds at i = " + i, controlImageGrid[i], testImageGrid[i]);
}
}
@Test
public void robust9patchTest() throws BrutException, IOException {
String[] ninePatches = {"ic_notification_overlay.9.png", "status_background.9.png",
"search_bg_transparent.9.png", "screenshot_panel.9.png", "recents_lower_gradient.9.png"};
char slash = File.separatorChar;
String location = slash + "res" + slash + "drawable-xxhdpi" + slash;
for (String ninePatch : ninePatches) {
File control = new File((sTestOrigDir + location), ninePatch);
File test = new File((sTestNewDir + location), ninePatch);
BufferedImage controlImage = ImageIO.read(control);
BufferedImage testImage = ImageIO.read(test);
int w = controlImage.getWidth(), h = controlImage.getHeight();
// Check the entire horizontal line
for (int i = 1; i < w; i++) {
if (isTransparent(controlImage.getRGB(i, 0))) {
assertTrue(isTransparent(testImage.getRGB(i, 0)));
} else {
assertEquals("Image lost npTc chunk on image " + ninePatch + " at (x, y) (" + i + "," + 0 + ")",
controlImage.getRGB(i, 0), testImage.getRGB(i, 0));
}
}
// Check the entire vertical line
for (int i = 1; i < h; i++) {
if (isTransparent(controlImage.getRGB(0, i))) {
assertTrue(isTransparent(testImage.getRGB(0, i)));
} else {
assertEquals("Image lost npTc chunk on image " + ninePatch + " at (x, y) (" + 0 + "," + i + ")",
controlImage.getRGB(0, i), testImage.getRGB(0, i));
}
}
}
}
@Test
public void drawableXxhdpiTest() throws BrutException, IOException {
compareResFolder("drawable-xxhdpi");
@ -465,6 +553,10 @@ public class BuildAndDecodeTest {
assertTrue(f.isDirectory());
}
private boolean isTransparent(int pixel) {
return pixel >> 24 == 0x00;
}
private void compareXmlFiles(String path, ElementQualifier qualifier) throws BrutException {
DetailedDiff diff;
try {

View File

@ -37,7 +37,7 @@ import static org.junit.Assert.assertTrue;
public class DebugTagRetainedTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
sTestOrigDir = new ExtFile(sTmpDir, "issue1235-orig");

View File

@ -18,12 +18,12 @@ import static org.junit.Assert.assertEquals;
public class DefaultBaksmaliVariableTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
sTmpDir = new ExtFile(OS.createTempDirectory());
sTestOrigDir = new ExtFile(sTmpDir, "testjar-orig");
sTestNewDir = new ExtFile(sTmpDir, "testjar-new");
LOGGER.info("Unpacking testjar...");
TestUtils.copyResourceDir(BuildAndDecodeJarTest.class, "brut/apktool/issue1481/", sTestOrigDir);
TestUtils.copyResourceDir(DefaultBaksmaliVariableTest.class, "brut/apktool/issue1481/", sTestOrigDir);
LOGGER.info("Building issue1481.jar...");
File testJar = new File(sTmpDir, "issue1481.jar");
@ -99,5 +99,5 @@ public class DefaultBaksmaliVariableTest {
private static ExtFile sTestOrigDir;
private static ExtFile sTestNewDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
private final static Logger LOGGER = Logger.getLogger(DefaultBaksmaliVariableTest.class.getName());
}

View File

@ -27,7 +27,6 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import static org.junit.Assert.assertTrue;
@ -37,10 +36,10 @@ import static org.junit.Assert.assertTrue;
public class DoubleExtensionUnknownFileTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/issue1244/", sTmpDir);
TestUtils.copyResourceDir(DoubleExtensionUnknownFileTest.class, "brut/apktool/issue1244/", sTmpDir);
}
@AfterClass
@ -67,6 +66,4 @@ public class DoubleExtensionUnknownFileTest {
}
private static ExtFile sTmpDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}

View File

@ -0,0 +1,76 @@
/**
* Copyright 2014 Ryszard Wiśniewski <brut.alll@gmail.com>
* Copyright 2016 Connor Tumbleson <connor.tumbleson@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package brut.androlib;
import brut.directory.ExtFile;
import brut.common.BrutException;
import brut.util.OS;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
/**
* @author Connor Tumbleson <connor.tumbleson@gmail.com>
*/
public class ExternalEntityTest {
@BeforeClass
public static void beforeClass() throws Exception {
sOrigDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(ExternalEntityTest.class, "brut/apktool/doctype/", sOrigDir);
LOGGER.info("Building doctype.apk...");
File testApk = new File(sOrigDir, "doctype.apk");
new Androlib().build(sOrigDir, testApk);
LOGGER.info("Decoding doctype.apk...");
ApkDecoder apkDecoder = new ApkDecoder(testApk);
apkDecoder.setOutDir(new File(sOrigDir + File.separator + "output"));
apkDecoder.decode();
}
@AfterClass
public static void afterClass() throws BrutException {
OS.rmdir(sOrigDir);
}
@Test
public void doctypeTest() throws BrutException, IOException {
String expected = TestUtils.replaceNewlines("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<manifest android:versionCode=\"1\" android:versionName=\"1.0\" hardwareAccelerated=\"true\" package=\"com.ibotpeaches.doctype\" platformBuildVersionCode=\"23\" platformBuildVersionName=\"6.0-2438415\"\n" +
" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n" +
" <supports-screens android:anyDensity=\"true\" android:smallScreens=\"true\" android:normalScreens=\"true\" android:largeScreens=\"true\" android:resizeable=\"true\" android:xlargeScreens=\"true\" />\n" +
"</manifest>");
byte[] encoded = Files.readAllBytes(Paths.get(sOrigDir + File.separator + "output" + File.separator + "AndroidManifest.xml"));
String obtained = TestUtils.replaceNewlines(new String(encoded));
assertEquals(expected, obtained);
}
private static ExtFile sOrigDir;
private final static Logger LOGGER = Logger.getLogger(ExternalEntityTest.class.getName());
}

View File

@ -22,7 +22,6 @@ import brut.util.OS;
import java.io.*;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import org.custommonkey.xmlunit.*;
import org.junit.*;
@ -32,7 +31,7 @@ import org.xml.sax.SAXException;
public class LargeIntsInManifestTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/issue767/", sTmpDir);
@ -94,6 +93,4 @@ public class LargeIntsInManifestTest {
private static ExtFile sTmpDir;
private static ExtFile sTestOrigDir;
private static ExtFile sTestNewDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeTest.class.getName());
}

View File

@ -35,10 +35,10 @@ import static org.junit.Assert.assertEquals;
public class MissingVersionManifestTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/issue1264/", sTmpDir);
TestUtils.copyResourceDir(MissingVersionManifestTest.class, "brut/apktool/issue1264/", sTmpDir);
}
@AfterClass
@ -61,6 +61,4 @@ public class MissingVersionManifestTest {
}
private static ExtFile sTmpDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}

View File

@ -17,7 +17,6 @@ package brut.androlib;
import brut.androlib.res.xml.ResXmlEncoders;
import org.junit.Test;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
@ -54,6 +53,4 @@ public class PositionalEnumerationTest {
private String enumerateArguments(String value) {
return ResXmlEncoders.enumerateNonPositionalSubstitutionsIfRequired(value);
}
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}

View File

@ -84,4 +84,4 @@ public class ProviderAttributeTest {
}
private static ExtFile sTmpDir;
}
}

View File

@ -25,7 +25,6 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
@ -35,10 +34,10 @@ import static org.junit.Assert.assertEquals;
public class ReferenceVersionCodeTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/issue1234/", sTmpDir);
TestUtils.copyResourceDir(ReferenceVersionCodeTest.class, "brut/apktool/issue1234/", sTmpDir);
}
@AfterClass
@ -61,6 +60,4 @@ public class ReferenceVersionCodeTest {
}
private static ExtFile sTmpDir;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}

View File

@ -25,7 +25,6 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
@ -36,10 +35,10 @@ import static org.junit.Assert.assertNotSame;
public class UnknownCompressionTest {
@BeforeClass
public static void beforeClass() throws Exception, BrutException {
public static void beforeClass() throws Exception {
TestUtils.cleanFrameworkFile();
sTmpDir = new ExtFile(OS.createTempDirectory());
TestUtils.copyResourceDir(LargeIntsInManifestTest.class, "brut/apktool/unknown_compression/", sTmpDir);
TestUtils.copyResourceDir(UnknownCompressionTest.class, "brut/apktool/unknown_compression/", sTmpDir);
String apk = "deflated_unknowns.apk";
ApkOptions apkOptions = new ApkOptions();
@ -90,6 +89,4 @@ public class UnknownCompressionTest {
private static ExtFile sOriginalFile;
private static ExtFile sBuiltFile;
private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName());
}

View File

@ -25,7 +25,6 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import static org.junit.Assert.assertTrue;
@ -66,6 +65,4 @@ public class VectorDrawableTest {
private static ExtFile sTmpDir;
private static ExtFile sTestOrigDir;
private final static Logger LOGGER = Logger.getLogger(VectorDrawableTest.class.getName());
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE manifest [<!ENTITY e1 SYSTEM 'http://ibotpeaches.com?z=APKTOOLXXE;'>]>
<manifest hardwareAccelerated="true" package="com.ibotpeaches.doctype" platformBuildVersionCode="24" platformBuildVersionName="6.0-2456767" xmlns:android="http://schemas.android.com/apk/res/android">
&e1;
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true"/>
</manifest>

View File

@ -0,0 +1,12 @@
version: 2.0.0
apkFileName: doctype.apk
isFrameworkApk: false
usesFramework:
ids:
- 1
packageInfo:
forced-package-id: '127'
versionInfo:
versionCode: '1'
versionName: '1.0'
compressionType: false

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="test1">"Forgot your username or password?\nVisit google.com/accounts/recovery."</string>
<string name="test2">Forgot your username or password?\n.Visit google.com/accounts/recovery</string>
<string name="test3"> (string8) "Forgot your username or password?\nVisit google.com/accounts/recovery."</string>
<string name="test4">Forgot your username or password?\nVisit google.com/accounts/recovery.</string>
<string name="test5">Forgot your username or password?
Visit google.com/accounts/recovery.</string>
</resources>

View File

@ -31,4 +31,14 @@ bar"</string>
<string name="test_string29" formatted="false">category=temp%temp%foo</string>
<string name="test_string30">res/foo/</string>
<string name="test_string31">res/foo</string>
<string name="test_string32">[<font size="17">TEST STRING</font>]</string>
<string name="test_string33"><font size="17">[TEST STRING]</font></string>
<string name="test_string34">[<font size="17">TEST STRING]</font></string>
<string name="test_string35"><font size="17">[TEST STRING</font>]</string>
<string name="test_string36"><font size="17">TEST STRING</font></string>
<string name="test_string37">[<font size="17">Ţåþ ţö ţýþé þåššŵöŕð one two three]</font></string>
<string name="test_string38">[<font size="17">Ţåþ ţö ţýþé þåššŵöŕð one two three</font>]</string>
<string name="test_string39"><font size="17">[Ţåþ ţö ţýþé þåššŵöŕð one two three</font>]</string>
<string name="test_string40">[<font size="17">]Ţåþ ţö ţýþé þåššŵöŕð one two three</font></string>
<string name="test_string41"><font size="17">[Ţåþ ţö ţýþé þåššŵöŕð one two three]</font></string>
</resources>