Foreign dex markers are named in the runtime by calling realpath(3) on the input
dexfile path and replacing "/" with "@". On the Java side, we're using
File.getCanonicalPath, which is similar but isn't quite the same. It tries
to call realpath() directly, but if that fails, it resorts to a series of
increasingly desperate measures to calculate a "canonical path". We just
use realpath instead.
Also, don't attempt to delete a profile if canonicalization fails.
bug:
28740848
Change-Id: Ie5d5af590187e793db633342a42b923865e5c005
for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) {
try {
- apkPath = new File(apkPath).getCanonicalPath();
+ apkPath = PackageManagerServiceUtils.realpath(new File(apkPath));
} catch (IOException e) {
// Log an error but continue without it.
Slog.w(TAG, "Failed to get canonical path", e);
+ continue;
}
String useMarker = apkPath.replace('/', '@');
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
try {
- path = new File(path).getCanonicalPath();
+ path = PackageManagerServiceUtils.realpath(new File(path));
} catch (IOException e) {
// TODO: Should we return early here ?
Slog.w(TAG, "Failed to get canonical path", e);
+ continue;
}
final String useMarker = path.replace('/', '@');
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.system.ErrnoException;
import android.util.ArraySet;
import android.util.Log;
+import libcore.io.Libcore;
+import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
return result;
}
-}
\ No newline at end of file
+
+ /**
+ * Returns the canonicalized path of {@code path} as per {@code realpath(3)}
+ * semantics.
+ */
+ public static String realpath(File path) throws IOException {
+ try {
+ return Libcore.os.realpath(path.getAbsolutePath());
+ } catch (ErrnoException ee) {
+ throw ee.rethrowAsIOException();
+ }
+ }
+}