Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

guessPath not to depend on the first level of app directory #156

Merged
merged 1 commit into from
Feb 26, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -32,40 +32,45 @@
public final class AppDataDirGuesserTest {
@Test
public void testGuessCacheDir_SimpleExample() {
guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache");
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk")
.shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor("/data/app/a.b.c.tests-xxx/base.apk")
.shouldGive("/data/data/a.b.c.tests/cache");
}

@Test
public void testGuessCacheDir_MultipleResultsSeparatedByColon() {
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
.shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache");
}

@Test
public void testGuessCacheDir_NotWriteableSkipped() {
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
.withNonWriteable("/data/data/a.b.c/cache")
.shouldGive("/data/data/d.e.f/cache");
}

@Test
public void testGuessCacheDir_ForSecondaryUser() {
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
.withNonWriteable("/data/data/a.b.c", "/data/data/d.e.f")
.withProcessUid(1110009)
.shouldGive("/data/user/11/a.b.c/cache", "/data/user/11/d.e.f/cache");
}

@Test
public void testGuessCacheDir_StripHyphenatedSuffixes() {
guessCacheDirFor("/data/app/a.b.c-2.apk").shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor("/data/app/a.b.c-2/base.apk")
.shouldGive("/data/data/a.b.c/cache");
}

@Test
public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() {
guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:asdf:")
.shouldGive("/data/data/a.b.c/cache");
guessCacheDirFor(":asdf:/data/app/a.b.c-xxx/base.apk")
.shouldGive("/data/data/a.b.c/cache");
}

@Test
@@ -82,8 +87,38 @@ public void testGuessCacheDir_JarsIgnored() {
@Test
public void testGuessCacheDir_RealWorldExample() {
String realPath = "/system/framework/android.test.runner.jar:" +
"/data/app/com.google.android.voicesearch.tests-2.apk:" +
"/data/app/com.google.android.voicesearch-1.apk";
"/data/app/com.google.android.voicesearch.tests-2/base.apk:" +
"/data/app/com.google.android.voicesearch-1/base.apk";
guessCacheDirFor(realPath)
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
.shouldGive("/data/data/com.google.android.voicesearch/cache");
}

@Test
public void testGuessCacheDir_RealWorldExampleWithOneLevelSubDirectories() {
String realPath = "/system/framework/android.test.runner.jar:" +
"/data/app/com.google.android.voicesearch.tests-abcde/base.apk:" +
"/data/app/com.google.android.voicesearch-fghij/base.apk";
guessCacheDirFor(realPath)
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
.shouldGive("/data/data/com.google.android.voicesearch/cache");
}

@Test
public void testGuessCacheDir_RealWorldExampleWithTwoLevelSubDirectories() {
String realPath = "/system/framework/android.test.runner.jar:" +
"/data/app/abcde/com.google.android.voicesearch.tests-fghij/base.apk:" +
"/data/app/klmno/com.google.android.voicesearch-pqrst/base.apk";
guessCacheDirFor(realPath)
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
.shouldGive("/data/data/com.google.android.voicesearch/cache");
}

@Test
public void testGuessCacheDir_RealWorldExampleWithHyphensInPath() {
String realPath = "/system/framework/android.test.runner.jar:" +
"/data/app/a-b-c/com.google.android.voicesearch.tests-e-f-g/base.apk:" +
"/data/app/com.google.android.voicesearch-k-l-n/base.apk";
guessCacheDirFor(realPath)
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
.shouldGive("/data/data/com.google.android.voicesearch/cache");
23 changes: 17 additions & 6 deletions dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java
Original file line number Diff line number Diff line change
@@ -136,20 +136,31 @@ private static String processClassLoaderString43OrLater(String input) {

File[] guessPath(String input) {
List<File> results = new ArrayList<>();
String apkPathRoot = "/data/app/";
for (String potential : splitPathList(input)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if we include the example path /data/app/[randomStringA]/[packageName]-[randomStringB]/base.apk as a comment.

if (!potential.startsWith("/data/app/")) {
if (!potential.startsWith(apkPathRoot)) {
continue;
}
int start = "/data/app/".length();
int end = potential.lastIndexOf(".apk");
if (end != potential.length() - 4) {
continue;
}
int dash = potential.indexOf("-");
if (dash != -1) {
end = dash;
int endSlash = potential.lastIndexOf("/", end);
if (endSlash == apkPathRoot.length() - 1) {
// Apks cannot be directly under /data/app
continue;
}
int startSlash = potential.lastIndexOf("/", endSlash - 1);
if (startSlash == -1) {
continue;
}
// Look for the first dash after the package name
int dash = potential.indexOf("-", startSlash);
if (dash == -1) {
continue;
}
String packageName = potential.substring(start, end);
end = dash;
String packageName = potential.substring(startSlash + 1, end);
File dataDir = getWriteableDirectory("/data/data/" + packageName);

if (dataDir == null) {