More robust ResFileValue detection

Previously in 4882396163, strings that
resembled a filepath (ie res/foo/file), would be assigned to a
ResFileValue, which when attempted to be casted to ResScalarValue would
error out.

Attempting to check the filesystem for such files, slowed apktool's
execution majorly. In order to prevent this, the ClassCastException
and other checks related to checking ResFileValue when type is string
was added.

This allows bogus strings such as (res/foo/file) to be added, but the
exception is caught and allows decoding to continues. Fixes #921.
This commit is contained in:
Connor Tumbleson 2015-05-14 13:22:43 -05:00
parent 9cb3df85d8
commit 8254764c6c
5 changed files with 26 additions and 2 deletions

View File

@ -40,6 +40,10 @@ public final class ResType {
return mName;
}
public boolean isString() {
return mName.equalsIgnoreCase("string");
}
public Set<ResResSpec> listResSpecs() {
return new LinkedHashSet<ResResSpec>(mResSpecs.values());
}

View File

@ -39,4 +39,9 @@ public class ResFileValue extends ResValue {
}
return mPath.substring(4);
}
@Override
public String toString() {
return mPath;
}
}

View File

@ -67,7 +67,7 @@ public class ResValueFactory {
}
public ResValue factory(String value) {
if (value.startsWith("res/") && value.contains(".")) {
if (value.startsWith("res/")) {
return new ResFileValue(value);
}
return new ResStringValue(value);

View File

@ -202,6 +202,9 @@ public class ARSCDecoder {
ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() : readComplexEntry();
if (mType.isString() && value instanceof ResFileValue) {
value = new ResStringValue(value.toString());
}
if (mConfig == null) {
return;
}
@ -229,8 +232,19 @@ public class ARSCDecoder {
ResValueFactory factory = mPkg.getValueFactory();
Duo<Integer, ResScalarValue>[] items = new Duo[count];
ResValue resValue;
int resId;
for (int i = 0; i < count; i++) {
items[i] = new Duo<Integer, ResScalarValue>(mIn.readInt(), (ResScalarValue) readValue());
resId = mIn.readInt();
resValue = readValue();
try {
items[i] = new Duo<Integer, ResScalarValue>(resId, (ResScalarValue) resValue);
} catch (ClassCastException ex) {
resValue = new ResStringValue(resValue.toString());
items[i] = new Duo<Integer, ResScalarValue>(resId, (ResScalarValue) resValue);
}
}
return factory.bagFactory(parent, items);

View File

@ -0,0 +1 @@
This file has no extension.