mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-29 22:04:25 +02:00
fix encode decode errors
This commit is contained in:
parent
fd6d756482
commit
1b240b2281
@ -18,6 +18,7 @@ package com.reandroid.apk.xmldecoder;
|
|||||||
import com.reandroid.apk.XmlHelper;
|
import com.reandroid.apk.XmlHelper;
|
||||||
import com.reandroid.arsc.value.Entry;
|
import com.reandroid.arsc.value.Entry;
|
||||||
import com.reandroid.arsc.value.ResTableMapEntry;
|
import com.reandroid.arsc.value.ResTableMapEntry;
|
||||||
|
import com.reandroid.arsc.value.ValueType;
|
||||||
import com.reandroid.arsc.value.attribute.AttributeBag;
|
import com.reandroid.arsc.value.attribute.AttributeBag;
|
||||||
import com.reandroid.arsc.value.attribute.AttributeBagItem;
|
import com.reandroid.arsc.value.attribute.AttributeBagItem;
|
||||||
import com.reandroid.common.EntryStore;
|
import com.reandroid.common.EntryStore;
|
||||||
@ -56,7 +57,7 @@ class BagDecoderAttr<OUTPUT> extends BagDecoder<OUTPUT>{
|
|||||||
writer.attribute("name", name);
|
writer.attribute("name", name);
|
||||||
int rawVal = item.getData();
|
int rawVal = item.getData();
|
||||||
String value;
|
String value;
|
||||||
if(is_flag){
|
if(item.getBagItem().getValueType() == ValueType.INT_HEX){
|
||||||
value = String.format("0x%08x", rawVal);
|
value = String.format("0x%08x", rawVal);
|
||||||
}else {
|
}else {
|
||||||
value = String.valueOf(rawVal);
|
value = String.valueOf(rawVal);
|
||||||
|
@ -84,7 +84,13 @@ class XMLValuesEncoder {
|
|||||||
}
|
}
|
||||||
void encodeReferenceValue(Entry entry, String value){
|
void encodeReferenceValue(Entry entry, String value){
|
||||||
int resourceId = getMaterials().resolveReference(value);
|
int resourceId = getMaterials().resolveReference(value);
|
||||||
entry.setValueAsReference(resourceId);
|
ValueType valueType;
|
||||||
|
if(value.charAt(0) == '?'){
|
||||||
|
valueType = ValueType.ATTRIBUTE;
|
||||||
|
}else{
|
||||||
|
valueType = ValueType.REFERENCE;
|
||||||
|
}
|
||||||
|
entry.setValueAsRaw(valueType, resourceId);
|
||||||
}
|
}
|
||||||
void encodeStringValue(Entry entry, String value){
|
void encodeStringValue(Entry entry, String value){
|
||||||
|
|
||||||
|
@ -46,8 +46,16 @@ class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
|||||||
bagItem.setNameLow((short) (i+1));
|
bagItem.setNameLow((short) (i+1));
|
||||||
|
|
||||||
String valueText=child.getTextContent();
|
String valueText=child.getTextContent();
|
||||||
|
if(ValueDecoder.isReference(valueText)){
|
||||||
if(force_string){
|
ValueType valueType;
|
||||||
|
if(valueText.charAt(0) == '?'){
|
||||||
|
valueType = ValueType.ATTRIBUTE;
|
||||||
|
}else {
|
||||||
|
valueType = ValueType.REFERENCE;
|
||||||
|
}
|
||||||
|
bagItem.setTypeAndData(valueType,
|
||||||
|
getMaterials().resolveReference(valueText));
|
||||||
|
}else if(force_string){
|
||||||
bagItem.setValueAsString(ValueDecoder
|
bagItem.setValueAsString(ValueDecoder
|
||||||
.unEscapeSpecialCharacter(valueText));
|
.unEscapeSpecialCharacter(valueText));
|
||||||
}else if(force_integer){
|
}else if(force_integer){
|
||||||
@ -59,9 +67,6 @@ class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
|||||||
}
|
}
|
||||||
bagItem.setTypeAndData(ValueType.INT_DEC,
|
bagItem.setTypeAndData(ValueType.INT_DEC,
|
||||||
ValueDecoder.parseInteger(valueText));
|
ValueDecoder.parseInteger(valueText));
|
||||||
}else if(ValueDecoder.isReference(valueText)){
|
|
||||||
bagItem.setTypeAndData(ValueType.REFERENCE,
|
|
||||||
getMaterials().resolveReference(valueText));
|
|
||||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||||
bagItem.setTypeAndData(ValueType.NULL, 0);
|
bagItem.setTypeAndData(ValueType.NULL, 0);
|
||||||
}else {
|
}else {
|
||||||
|
@ -134,6 +134,20 @@ class XMLValuesEncoderAttr extends XMLValuesEncoderBag{
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
private boolean isFlag(XMLElement parent){
|
||||||
|
if(parent.getChildesCount()==0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String tagName=parent.getChildAt(0).getTagName();
|
||||||
|
return "flag".equals(tagName);
|
||||||
|
}
|
||||||
|
private boolean isEnum(XMLElement parent){
|
||||||
|
if(parent.getChildesCount()==0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String tagName=parent.getChildAt(0).getTagName();
|
||||||
|
return "enum".equals(tagName);
|
||||||
|
}
|
||||||
private int decodeUnknownAttributeHex(String name){
|
private int decodeUnknownAttributeHex(String name){
|
||||||
if(name.length()==0||name.charAt(0)!='@'){
|
if(name.length()==0||name.charAt(0)!='@'){
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -331,6 +331,9 @@ public class PackageBlock extends Chunk<PackageHeader>
|
|||||||
public SpecTypePair getSpecTypePair(String typeName){
|
public SpecTypePair getSpecTypePair(String typeName){
|
||||||
return getSpecTypePairArray().getSpecTypePair(typeName);
|
return getSpecTypePairArray().getSpecTypePair(typeName);
|
||||||
}
|
}
|
||||||
|
public SpecTypePair getSpecTypePair(int typeId){
|
||||||
|
return getSpecTypePairArray().getPair((byte) typeId);
|
||||||
|
}
|
||||||
public EntryGroup getEntryGroup(String typeName, String entryName){
|
public EntryGroup getEntryGroup(String typeName, String entryName){
|
||||||
return getSpecTypePairArray().getEntryGroup(typeName, entryName);
|
return getSpecTypePairArray().getEntryGroup(typeName, entryName);
|
||||||
}
|
}
|
||||||
|
114
src/main/java/com/reandroid/arsc/decoder/ColorUtil.java
Normal file
114
src/main/java/com/reandroid/arsc/decoder/ColorUtil.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
|
*
|
||||||
|
* 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 com.reandroid.arsc.decoder;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.value.ValueType;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ColorUtil {
|
||||||
|
|
||||||
|
public static String decode(ValueType valueType, int data){
|
||||||
|
if(valueType == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int index;
|
||||||
|
switch (valueType){
|
||||||
|
case INT_COLOR_RGB4:
|
||||||
|
index = 5;
|
||||||
|
break;
|
||||||
|
case INT_COLOR_ARGB4:
|
||||||
|
index = 4;
|
||||||
|
break;
|
||||||
|
case INT_COLOR_RGB8:
|
||||||
|
index = 2;
|
||||||
|
break;
|
||||||
|
case INT_COLOR_ARGB8:
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String hex = String.format("%08x", data);
|
||||||
|
return "#" + hex.substring(index);
|
||||||
|
}
|
||||||
|
public static ValueDecoder.EncodeResult encode(String hexColor){
|
||||||
|
if(hexColor == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
hexColor = hexColor.toUpperCase();
|
||||||
|
Matcher matcher = PATTERN_COLOR.matcher(hexColor);
|
||||||
|
if(!matcher.matches()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
char[] s = hexColor.toCharArray();
|
||||||
|
int len = s.length;
|
||||||
|
ValueType valueType;
|
||||||
|
int color = 0;
|
||||||
|
|
||||||
|
if (len == 4) {
|
||||||
|
valueType = ValueType.INT_COLOR_RGB4;
|
||||||
|
color |= 0xFF0000;
|
||||||
|
color |= get_hex(s[1]) << 20;
|
||||||
|
color |= get_hex(s[1]) << 16;
|
||||||
|
color |= get_hex(s[2]) << 12;
|
||||||
|
color |= get_hex(s[2]) << 8;
|
||||||
|
color |= get_hex(s[3]) << 4;
|
||||||
|
color |= get_hex(s[3]);
|
||||||
|
} else if (len == 5) {
|
||||||
|
valueType = ValueType.INT_COLOR_ARGB4;
|
||||||
|
color |= 0xFFFF0000;
|
||||||
|
color |= get_hex(s[1]) << 28;
|
||||||
|
color |= get_hex(s[1]) << 24;
|
||||||
|
color |= get_hex(s[2]) << 20;
|
||||||
|
color |= get_hex(s[2]) << 16;
|
||||||
|
color |= get_hex(s[3]) << 12;
|
||||||
|
color |= get_hex(s[3]) << 8;
|
||||||
|
color |= get_hex(s[4]) << 4;
|
||||||
|
color |= get_hex(s[4]);
|
||||||
|
} else if (len == 7) {
|
||||||
|
valueType = ValueType.INT_COLOR_RGB8;
|
||||||
|
color |= 0xFF000000;
|
||||||
|
color |= get_hex(s[1]) << 20;
|
||||||
|
color |= get_hex(s[2]) << 16;
|
||||||
|
color |= get_hex(s[3]) << 12;
|
||||||
|
color |= get_hex(s[4]) << 8;
|
||||||
|
color |= get_hex(s[5]) << 4;
|
||||||
|
color |= get_hex(s[6]);
|
||||||
|
} else if (len == 9) {
|
||||||
|
valueType = ValueType.INT_COLOR_ARGB8;
|
||||||
|
color |= get_hex(s[1]) << 28;
|
||||||
|
color |= get_hex(s[2]) << 24;
|
||||||
|
color |= get_hex(s[3]) << 20;
|
||||||
|
color |= get_hex(s[4]) << 16;
|
||||||
|
color |= get_hex(s[5]) << 12;
|
||||||
|
color |= get_hex(s[6]) << 8;
|
||||||
|
color |= get_hex(s[7]) << 4;
|
||||||
|
color |= get_hex(s[8]);
|
||||||
|
}else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ValueDecoder.EncodeResult(valueType, color);
|
||||||
|
}
|
||||||
|
private static int get_hex(char ch){
|
||||||
|
if(ch <= '9'){
|
||||||
|
return ch - '0';
|
||||||
|
}
|
||||||
|
return 10 + (ch - 'A');
|
||||||
|
}
|
||||||
|
public static final Pattern PATTERN_COLOR = Pattern.compile("^#([0-9a-fA-F]{3,8})$");
|
||||||
|
}
|
@ -165,21 +165,7 @@ public class ValueDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public static EncodeResult encodeColor(String value){
|
public static EncodeResult encodeColor(String value){
|
||||||
if(value==null){
|
return ColorUtil.encode(value);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Matcher matcher = PATTERN_COLOR.matcher(value);
|
|
||||||
if(!matcher.find()){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
value=matcher.group(1);
|
|
||||||
ValueType valueType;
|
|
||||||
if(value.length()==6){
|
|
||||||
valueType=ValueType.INT_COLOR_RGB8;
|
|
||||||
}else {
|
|
||||||
valueType=ValueType.INT_COLOR_ARGB8;
|
|
||||||
}
|
|
||||||
return new EncodeResult(valueType, parseHex(value));
|
|
||||||
}
|
}
|
||||||
public static EncodeResult encodeHexOrInt(String numString){
|
public static EncodeResult encodeHexOrInt(String numString){
|
||||||
if(numString==null){
|
if(numString==null){
|
||||||
@ -468,14 +454,13 @@ public class ValueDecoder {
|
|||||||
if(valueType==null){
|
if(valueType==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
String hexColor = ColorUtil.decode(valueType, data);
|
||||||
|
if(hexColor != null){
|
||||||
|
return hexColor;
|
||||||
|
}
|
||||||
switch (valueType){
|
switch (valueType){
|
||||||
case INT_BOOLEAN:
|
case INT_BOOLEAN:
|
||||||
return decodeBoolean(data);
|
return decodeBoolean(data);
|
||||||
case INT_COLOR_ARGB4:
|
|
||||||
case INT_COLOR_ARGB8:
|
|
||||||
case INT_COLOR_RGB4:
|
|
||||||
case INT_COLOR_RGB8:
|
|
||||||
return decodeColor(data);
|
|
||||||
case DIMENSION:
|
case DIMENSION:
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
case FRACTION:
|
case FRACTION:
|
||||||
@ -739,13 +724,6 @@ public class ValueDecoder {
|
|||||||
return "false";
|
return "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String decodeColor(int rawVal){
|
|
||||||
String hex=String.format("%x", rawVal);
|
|
||||||
if(hex.length()<=6){
|
|
||||||
return String.format("#%06x", rawVal);
|
|
||||||
}
|
|
||||||
return String.format("#%08x", rawVal);
|
|
||||||
}
|
|
||||||
private static String decodeDimensionOrFloat(ValueType valueType, int rawVal){
|
private static String decodeDimensionOrFloat(ValueType valueType, int rawVal){
|
||||||
if(valueType==ValueType.FLOAT){
|
if(valueType==ValueType.FLOAT){
|
||||||
float f=Float.intBitsToFloat(rawVal);
|
float f=Float.intBitsToFloat(rawVal);
|
||||||
@ -836,7 +814,6 @@ public class ValueDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Pattern PATTERN_COLOR = Pattern.compile("^#([0-9a-fA-F]{6,8})$");
|
|
||||||
public static final Pattern PATTERN_DIMEN = Pattern.compile("^([+\\-]?[0-9]+(\\.[0-9]+(E\\+?-?[0-9]+)?)?)(px|di?p|sp|pt|in|mm|%p?)$");
|
public static final Pattern PATTERN_DIMEN = Pattern.compile("^([+\\-]?[0-9]+(\\.[0-9]+(E\\+?-?[0-9]+)?)?)(px|di?p|sp|pt|in|mm|%p?)$");
|
||||||
private static final Pattern PATTERN_INTEGER = Pattern.compile("^(-?)([0-9]+)$");
|
private static final Pattern PATTERN_INTEGER = Pattern.compile("^(-?)([0-9]+)$");
|
||||||
private static final Pattern PATTERN_HEX = Pattern.compile("^0x[0-9a-fA-F]+$");
|
private static final Pattern PATTERN_HEX = Pattern.compile("^0x[0-9a-fA-F]+$");
|
||||||
|
@ -47,7 +47,7 @@ public class ResNameMap<VALUE> {
|
|||||||
valueMap=new HashMap<>();
|
valueMap=new HashMap<>();
|
||||||
mainMap.put(type, valueMap);
|
mainMap.put(type, valueMap);
|
||||||
}
|
}
|
||||||
valueMap.put(name, value);
|
valueMap.putIfAbsent(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void clear(){
|
public void clear(){
|
||||||
|
@ -229,6 +229,9 @@ import java.util.Objects;
|
|||||||
&& Objects.equals(str, getValueAsString())){
|
&& Objects.equals(str, getValueAsString())){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(str == null){
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
StringItem stringItem = getStringPool().getOrCreate(str);
|
StringItem stringItem = getStringPool().getOrCreate(str);
|
||||||
setData(stringItem.getIndex());
|
setData(stringItem.getIndex());
|
||||||
setValueType(ValueType.STRING);
|
setValueType(ValueType.STRING);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user