mirror of
https://github.com/revanced/Apktool.git
synced 2024-06-21 20:40:12 +02:00
a117132e39
* Revert "Remove Apktool Dummys. (#3258)"
This reverts commit 0e226928ce
.
* feat: properly add dummys
* refactor: shorten ResTypeSpec
* style: remove extra space
* refactor: extract FlagItem into own class
* refactor: notate which type is null
* fix: only add dummys if enabled
* feat: skip unknown (if enabled)
* feat: introduce "res-mode"
* feat: expose config on res table
* feat: add method to base attr for res skips
* fix: ensure autobuild doesn't choke
* refactor: remove java17 enhanced switch
* refactor: rename methods
* refactor: cleanup res-mode param
* test: introduction of test/sample apk
* refactor: make ResXmlPatcher public for loading XML
* test: assertions for dummy|leave|retain
* fix: prevent using `@null` as a name
* refactor: shorten long param for 'resm'
* refactor: leave for preserve
159 lines
5.6 KiB
Java
159 lines
5.6 KiB
Java
/*
|
|
* Copyright (C) 2010 Ryszard Wiśniewski <brut.alll@gmail.com>
|
|
* Copyright (C) 2010 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
|
|
*
|
|
* https://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.androlib.exceptions.AndrolibException;
|
|
import brut.androlib.res.Framework;
|
|
import brut.androlib.res.xml.ResXmlPatcher;
|
|
import brut.common.BrutException;
|
|
import brut.directory.DirUtil;
|
|
import brut.directory.Directory;
|
|
import brut.directory.FileDirectory;
|
|
import brut.util.OS;
|
|
import org.w3c.dom.Document;
|
|
import org.xml.sax.SAXException;
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
import org.xmlpull.v1.XmlPullParserException;
|
|
import org.xmlpull.v1.XmlPullParserFactory;
|
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import java.io.*;
|
|
import java.net.URL;
|
|
import java.net.URLDecoder;
|
|
import java.nio.file.Files;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
public abstract class TestUtils {
|
|
|
|
public static Map<String, String> parseStringsXml(File file)
|
|
throws BrutException {
|
|
try {
|
|
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
|
|
xpp.setInput(new FileReader(file));
|
|
|
|
int eventType;
|
|
String key = null;
|
|
Map<String, String> map = new HashMap<>();
|
|
while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) {
|
|
switch (eventType) {
|
|
case XmlPullParser.START_TAG:
|
|
if ("string".equals(xpp.getName())) {
|
|
int attrCount = xpp.getAttributeCount();
|
|
for (int i = 0; i < attrCount; i++) {
|
|
if ("name".equals(xpp.getAttributeName(i))) {
|
|
key = xpp.getAttributeValue(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case XmlPullParser.END_TAG:
|
|
if ("string".equals(xpp.getName())) {
|
|
key = null;
|
|
}
|
|
break;
|
|
case XmlPullParser.TEXT:
|
|
if (key != null) {
|
|
map.put(key, xpp.getText());
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return map;
|
|
} catch (IOException | XmlPullParserException ex) {
|
|
throw new BrutException(ex);
|
|
}
|
|
}
|
|
|
|
public static Document getDocumentFromFile(File file) throws BrutException {
|
|
try {
|
|
return ResXmlPatcher.loadDocument(file);
|
|
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
|
throw new BrutException(ex);
|
|
}
|
|
}
|
|
|
|
public static void copyResourceDir(Class<?> class_, String dirPath, File out) throws BrutException {
|
|
if (!out.exists()) {
|
|
out.mkdirs();
|
|
}
|
|
copyResourceDir(class_, dirPath, new FileDirectory(out));
|
|
}
|
|
|
|
public static void copyResourceDir(Class<?> class_, String dirPath, Directory out) throws BrutException {
|
|
if (class_ == null) {
|
|
class_ = Class.class;
|
|
}
|
|
|
|
URL dirURL = class_.getClassLoader().getResource(dirPath);
|
|
if (dirURL != null && dirURL.getProtocol().equals("file")) {
|
|
try {
|
|
DirUtil.copyToDir(new FileDirectory(dirURL.getFile()), out);
|
|
} catch (UnsupportedEncodingException ex) {
|
|
throw new BrutException(ex);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (dirURL == null) {
|
|
String className = class_.getName().replace(".", "/") + ".class";
|
|
dirURL = class_.getClassLoader().getResource(className);
|
|
}
|
|
|
|
if (dirURL.getProtocol().equals("jar")) {
|
|
String jarPath;
|
|
try {
|
|
jarPath = URLDecoder.decode(dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")), "UTF-8");
|
|
DirUtil.copyToDir(new FileDirectory(jarPath), out);
|
|
} catch (UnsupportedEncodingException ex) {
|
|
throw new BrutException(ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void cleanFrameworkFile() throws BrutException {
|
|
File framework = new File(getFrameworkDirectory(), "1.apk");
|
|
|
|
if (Files.exists(framework.toPath())) {
|
|
OS.rmfile(framework.getAbsolutePath());
|
|
}
|
|
}
|
|
|
|
public static byte[] readHeaderOfFile(File file, int size) throws IOException {
|
|
byte[] buffer = new byte[size];
|
|
InputStream inputStream = Files.newInputStream(file.toPath());
|
|
if (inputStream.read(buffer) != buffer.length) {
|
|
throw new IOException("File size too small for buffer length: " + size);
|
|
}
|
|
inputStream.close();
|
|
|
|
return buffer;
|
|
}
|
|
|
|
static File getFrameworkDirectory() throws AndrolibException {
|
|
Config config = Config.getDefaultConfig();
|
|
Framework framework = new Framework(config);
|
|
return framework.getFrameworkDirectory();
|
|
}
|
|
|
|
public static String replaceNewlines(String value) {
|
|
return value.replace("\n", "").replace("\r", "");
|
|
}
|
|
}
|