Skip to content

Commit

Permalink
merge ResAttrDecoder into the AXmlResourceParser
Browse files Browse the repository at this point in the history
  • Loading branch information
sv99 committed Aug 1, 2023
1 parent 9d7d580 commit 242fe73
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@
import android.content.res.XmlResourceParser;
import android.util.TypedValue;
import brut.androlib.exceptions.AndrolibException;
import brut.androlib.exceptions.CantFindFrameworkResException;
import brut.androlib.exceptions.UndefinedResObjectException;
import brut.androlib.res.data.ResID;
import brut.androlib.res.data.ResResSpec;
import brut.androlib.res.data.ResTable;
import brut.androlib.res.data.arsc.ARSCHeader;
import brut.androlib.res.data.axml.NamespaceStack;
import brut.androlib.res.data.value.ResAttr;
import brut.androlib.res.data.value.ResScalarValue;
import brut.androlib.res.xml.ResXmlEncoders;
import brut.util.ExtCountingDataInput;
import com.google.common.io.LittleEndianDataInputStream;
Expand All @@ -44,20 +49,16 @@
public class AXmlResourceParser implements XmlResourceParser {

public AXmlResourceParser(ResTable resTable) {
mResTable = resTable;
resetEventInfo();
setAttrDecoder(new ResAttrDecoder(resTable));
}

public AndrolibException getFirstError() {
return mFirstError;
}

public ResAttrDecoder getAttrDecoder() {
return mAttrDecoder;
}

public void setAttrDecoder(ResAttrDecoder attrDecoder) {
mAttrDecoder = attrDecoder;
public ResTable getResTable() {
return mResTable;
}

public void open(InputStream stream) {
Expand Down Expand Up @@ -298,6 +299,19 @@ public String getAttributeNamespace(int index) {
return value;
}

public String decodeFromResourceId(int attrResId) throws AndrolibException {
if (attrResId != 0) {
try {
ResResSpec resResSpec = mResTable.getResSpec(attrResId);
if (resResSpec != null) {
return resResSpec.getName();
}
} catch (UndefinedResObjectException | CantFindFrameworkResException ignored) {}
}

return null;
}

private String getNonDefaultNamespaceUri(int offset) {
String prefix = mStringBlock.getString(mNamespaces.getPrefix(offset));
if (prefix != null) {
Expand Down Expand Up @@ -337,7 +351,7 @@ public String getAttributeName(int index) {
int resourceId = getAttributeNameResource(index);

try {
resourceMapValue = mAttrDecoder.decodeFromResourceId(resourceId);
resourceMapValue = decodeFromResourceId(resourceId);
} catch (AndrolibException ignored) {
resourceMapValue = null;
}
Expand Down Expand Up @@ -389,48 +403,56 @@ public String getAttributeValue(int index) {
int valueData = mAttributes[offset + ATTRIBUTE_IX_VALUE_DATA];
int valueRaw = mAttributes[offset + ATTRIBUTE_IX_VALUE_STRING];

if (mAttrDecoder != null) {
try {
String stringBlockValue = valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(mStringBlock.getString(valueRaw));
String resourceMapValue = null;

// Ensure we only track down obfuscated values for reference/attribute type values. Otherwise we might
// spam lookups against resource table for invalid ids.
if (valueType == TypedValue.TYPE_REFERENCE || valueType == TypedValue.TYPE_DYNAMIC_REFERENCE ||
valueType == TypedValue.TYPE_ATTRIBUTE || valueType == TypedValue.TYPE_DYNAMIC_ATTRIBUTE) {
resourceMapValue = mAttrDecoder.decodeFromResourceId(valueData);
}
String value = stringBlockValue;

if (stringBlockValue != null && resourceMapValue != null) {
int slashPos = stringBlockValue.lastIndexOf("/");
int colonPos = stringBlockValue.lastIndexOf(":");

// Handle a value with a format of "@yyy/xxx", but avoid "@yyy/zzz:xxx"
if (slashPos != -1) {
if (colonPos == -1) {
String type = stringBlockValue.substring(0, slashPos);
value = type + "/" + resourceMapValue;
}
} else if (! stringBlockValue.equals(resourceMapValue)) {
value = resourceMapValue;
try {
String stringBlockValue = valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(mStringBlock.getString(valueRaw));
String resourceMapValue = null;

// Ensure we only track down obfuscated values for reference/attribute type values. Otherwise we might
// spam lookups against resource table for invalid ids.
if (valueType == TypedValue.TYPE_REFERENCE || valueType == TypedValue.TYPE_DYNAMIC_REFERENCE ||
valueType == TypedValue.TYPE_ATTRIBUTE || valueType == TypedValue.TYPE_DYNAMIC_ATTRIBUTE) {
resourceMapValue = decodeFromResourceId(valueData);
}
String value = stringBlockValue;

if (stringBlockValue != null && resourceMapValue != null) {
int slashPos = stringBlockValue.lastIndexOf("/");
int colonPos = stringBlockValue.lastIndexOf(":");

// Handle a value with a format of "@yyy/xxx", but avoid "@yyy/zzz:xxx"
if (slashPos != -1) {
if (colonPos == -1) {
String type = stringBlockValue.substring(0, slashPos);
value = type + "/" + resourceMapValue;
}
} else if (! stringBlockValue.equals(resourceMapValue)) {
value = resourceMapValue;
}
}

// try to decode from resource table
int attrResId = getAttributeNameResource(index);
ResScalarValue resValue = mResTable.getCurrentResPackage()
.getValueFactory().factory(valueType, valueData, value);

String decoded = null;
if (attrResId > 0) {
try {
ResAttr attr = (ResAttr) mResTable.getResSpec(attrResId).getDefaultResource().getValue();

return mAttrDecoder.decode(
valueType,
valueData,
value,
getAttributeNameResource(index)
);
} catch (AndrolibException ex) {
setFirstError(ex);
LOGGER.log(Level.WARNING, String.format("Could not decode attr value, using undecoded value "
+ "instead: ns=%s, name=%s, value=0x%08x",
getAttributePrefix(index),
getAttributeName(index),
valueData), ex);
decoded = attr.convertToResXmlFormat(resValue);
} catch (UndefinedResObjectException | ClassCastException ignored) {}
}

return decoded != null ? decoded : resValue.encodeAsResXmlAttr();

} catch (AndrolibException ex) {
setFirstError(ex);
LOGGER.log(Level.WARNING, String.format("Could not decode attr value, using undecoded value "
+ "instead: ns=%s, name=%s, value=0x%08x",
getAttributePrefix(index),
getAttributeName(index),
valueData), ex);
}
return TypedValue.coerceToString(valueType, valueData);
}
Expand Down Expand Up @@ -801,7 +823,7 @@ private void setFirstError(AndrolibException error) {
}

private ExtCountingDataInput mIn;
private ResAttrDecoder mAttrDecoder;
private final ResTable mResTable;
private AndrolibException mFirstError;

private boolean isOperational = false;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import java.io.*;

public class XmlPullStreamDecoder implements ResStreamDecoder {
public XmlPullStreamDecoder(XmlPullParser parser,
public XmlPullStreamDecoder(AXmlResourceParser parser,
ExtXmlSerializer serializer) {
this.mParser = parser;
this.mSerial = serializer;
Expand All @@ -43,7 +43,7 @@ public void decode(InputStream in, OutputStream out)
try {
XmlPullWrapperFactory factory = XmlPullWrapperFactory.newInstance();
XmlPullParserWrapper par = factory.newPullParserWrapper(mParser);
final ResTable resTable = ((AXmlResourceParser) mParser).getAttrDecoder().getResTable();
final ResTable resTable = mParser.getResTable();

XmlSerializerWrapper ser = new StaticXmlSerializerWrapper(mSerial, factory) {
boolean hideSdkInfo = false;
Expand Down Expand Up @@ -149,6 +149,6 @@ public void decodeManifest(InputStream in, OutputStream out)
decode(in, out);
}

private final XmlPullParser mParser;
private final AXmlResourceParser mParser;
private final ExtXmlSerializer mSerial;
}

0 comments on commit 242fe73

Please sign in to comment.