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.arsc.value.Entry;
|
||||
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.AttributeBagItem;
|
||||
import com.reandroid.common.EntryStore;
|
||||
@ -56,7 +57,7 @@ class BagDecoderAttr<OUTPUT> extends BagDecoder<OUTPUT>{
|
||||
writer.attribute("name", name);
|
||||
int rawVal = item.getData();
|
||||
String value;
|
||||
if(is_flag){
|
||||
if(item.getBagItem().getValueType() == ValueType.INT_HEX){
|
||||
value = String.format("0x%08x", rawVal);
|
||||
}else {
|
||||
value = String.valueOf(rawVal);
|
||||
|
@ -84,7 +84,13 @@ class XMLValuesEncoder {
|
||||
}
|
||||
void encodeReferenceValue(Entry entry, String 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){
|
||||
|
||||
|
@ -46,8 +46,16 @@ class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
||||
bagItem.setNameLow((short) (i+1));
|
||||
|
||||
String valueText=child.getTextContent();
|
||||
|
||||
if(force_string){
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
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
|
||||
.unEscapeSpecialCharacter(valueText));
|
||||
}else if(force_integer){
|
||||
@ -59,9 +67,6 @@ class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
||||
}
|
||||
bagItem.setTypeAndData(ValueType.INT_DEC,
|
||||
ValueDecoder.parseInteger(valueText));
|
||||
}else if(ValueDecoder.isReference(valueText)){
|
||||
bagItem.setTypeAndData(ValueType.REFERENCE,
|
||||
getMaterials().resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setTypeAndData(ValueType.NULL, 0);
|
||||
}else {
|
||||
|
@ -134,6 +134,20 @@ class XMLValuesEncoderAttr extends XMLValuesEncoderBag{
|
||||
}
|
||||
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){
|
||||
if(name.length()==0||name.charAt(0)!='@'){
|
||||
return 0;
|
||||
|
@ -331,6 +331,9 @@ public class PackageBlock extends Chunk<PackageHeader>
|
||||
public SpecTypePair getSpecTypePair(String typeName){
|
||||
return getSpecTypePairArray().getSpecTypePair(typeName);
|
||||
}
|
||||
public SpecTypePair getSpecTypePair(int typeId){
|
||||
return getSpecTypePairArray().getPair((byte) typeId);
|
||||
}
|
||||
public EntryGroup getEntryGroup(String typeName, String 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;
|
||||
}
|
||||
public static EncodeResult encodeColor(String value){
|
||||
if(value==null){
|
||||
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));
|
||||
return ColorUtil.encode(value);
|
||||
}
|
||||
public static EncodeResult encodeHexOrInt(String numString){
|
||||
if(numString==null){
|
||||
@ -468,14 +454,13 @@ public class ValueDecoder {
|
||||
if(valueType==null){
|
||||
return null;
|
||||
}
|
||||
String hexColor = ColorUtil.decode(valueType, data);
|
||||
if(hexColor != null){
|
||||
return hexColor;
|
||||
}
|
||||
switch (valueType){
|
||||
case INT_BOOLEAN:
|
||||
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 FLOAT:
|
||||
case FRACTION:
|
||||
@ -739,13 +724,6 @@ public class ValueDecoder {
|
||||
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){
|
||||
if(valueType==ValueType.FLOAT){
|
||||
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?)$");
|
||||
private static final Pattern PATTERN_INTEGER = Pattern.compile("^(-?)([0-9]+)$");
|
||||
private static final Pattern PATTERN_HEX = Pattern.compile("^0x[0-9a-fA-F]+$");
|
||||
|
@ -47,7 +47,7 @@ public class ResNameMap<VALUE> {
|
||||
valueMap=new HashMap<>();
|
||||
mainMap.put(type, valueMap);
|
||||
}
|
||||
valueMap.put(name, value);
|
||||
valueMap.putIfAbsent(name, value);
|
||||
}
|
||||
}
|
||||
public void clear(){
|
||||
|
@ -229,6 +229,9 @@ import java.util.Objects;
|
||||
&& Objects.equals(str, getValueAsString())){
|
||||
return;
|
||||
}
|
||||
if(str == null){
|
||||
str = "";
|
||||
}
|
||||
StringItem stringItem = getStringPool().getOrCreate(str);
|
||||
setData(stringItem.getIndex());
|
||||
setValueType(ValueType.STRING);
|
||||
|
Loading…
x
Reference in New Issue
Block a user