More robust ResFileValue detection

Previously in 4882396163f978884256e008fc7fae9201f156b4, 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; return mName;
} }
public boolean isString() {
return mName.equalsIgnoreCase("string");
}
public Set<ResResSpec> listResSpecs() { public Set<ResResSpec> listResSpecs() {
return new LinkedHashSet<ResResSpec>(mResSpecs.values()); return new LinkedHashSet<ResResSpec>(mResSpecs.values());
} }

View File

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

View File

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

View File

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

View File

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