Duplicate apk names on package update.
+minor fixes
Bug: 187710420
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest
Change-Id: Iced479532b38bddcd8655df3ce08611434965cf4
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
index 1814a8e..a1e5153 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
@@ -33,9 +33,12 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Collection;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Callback data loader for PackageManagerShellCommand installations.
@@ -136,6 +139,12 @@
private final byte mMode;
private final String mData;
+ private final String mSalt;
+
+ private static AtomicLong sGlobalSalt = new AtomicLong((new SecureRandom()).nextLong());
+ private static Long nextGlobalSalt() {
+ return sGlobalSalt.incrementAndGet();
+ }
static Metadata forStdIn(String fileId) {
return new Metadata(STDIN, fileId);
@@ -144,7 +153,7 @@
/** @hide */
@VisibleForTesting
public static Metadata forLocalFile(String filePath) {
- return new Metadata(LOCAL_FILE, filePath);
+ return new Metadata(LOCAL_FILE, filePath, nextGlobalSalt().toString());
}
static Metadata forDataOnlyStreaming(String fileId) {
@@ -156,26 +165,71 @@
}
private Metadata(byte mode, String data) {
+ this(mode, data, null);
+ }
+
+ private Metadata(byte mode, String data, String salt) {
this.mMode = mode;
this.mData = (data == null) ? "" : data;
+ this.mSalt = salt;
}
static Metadata fromByteArray(byte[] bytes) throws IOException {
- if (bytes == null || bytes.length == 0) {
+ if (bytes == null || bytes.length < 5) {
return null;
}
- byte mode = bytes[0];
- String data = new String(bytes, 1, bytes.length - 1, StandardCharsets.UTF_8);
- return new Metadata(mode, data);
+ int offset = 0;
+ final byte mode = bytes[offset];
+ offset += 1;
+ final String data;
+ final String salt;
+ switch (mode) {
+ case LOCAL_FILE: {
+ int dataSize = ByteBuffer.wrap(bytes, offset, 4).order(
+ ByteOrder.LITTLE_ENDIAN).getInt();
+ offset += 4;
+ data = new String(bytes, offset, dataSize, StandardCharsets.UTF_8);
+ offset += dataSize;
+ salt = new String(bytes, offset, bytes.length - offset,
+ StandardCharsets.UTF_8);
+ break;
+ }
+ default:
+ data = new String(bytes, offset, bytes.length - offset,
+ StandardCharsets.UTF_8);
+ salt = null;
+ break;
+ }
+ return new Metadata(mode, data, salt);
}
/** @hide */
@VisibleForTesting
public byte[] toByteArray() {
- byte[] dataBytes = this.mData.getBytes(StandardCharsets.UTF_8);
- byte[] result = new byte[1 + dataBytes.length];
- result[0] = this.mMode;
- System.arraycopy(dataBytes, 0, result, 1, dataBytes.length);
+ final byte[] result;
+ final byte[] dataBytes = this.mData.getBytes(StandardCharsets.UTF_8);
+ switch (this.mMode) {
+ case LOCAL_FILE: {
+ int dataSize = dataBytes.length;
+ byte[] saltBytes = this.mSalt.getBytes(StandardCharsets.UTF_8);
+ result = new byte[1 + 4 + dataSize + saltBytes.length];
+ int offset = 0;
+ result[offset] = this.mMode;
+ offset += 1;
+ ByteBuffer.wrap(result, offset, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(
+ dataSize);
+ offset += 4;
+ System.arraycopy(dataBytes, 0, result, offset, dataSize);
+ offset += dataSize;
+ System.arraycopy(saltBytes, 0, result, offset, saltBytes.length);
+ break;
+ }
+ default:
+ result = new byte[1 + dataBytes.length];
+ result[0] = this.mMode;
+ System.arraycopy(dataBytes, 0, result, 1, dataBytes.length);
+ break;
+ }
return result;
}
diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
index db52683..f439777 100644
--- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
+++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
@@ -293,8 +293,8 @@
auto mode = read<int8_t>(metadata).value_or(STDIN);
if (mode == LOCAL_FILE) {
// local file and possibly signature
- return openLocalFile(env, jni, shellCommand, size,
- std::string(metadata.data, metadata.size));
+ auto dataSize = le32toh(read<int32_t>(metadata).value_or(0));
+ return openLocalFile(env, jni, shellCommand, size, std::string(metadata.data, dataSize));
}
if (!shellCommand) {
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 24699d9..8b816d0 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1174,7 +1174,8 @@
return -EINVAL;
}
if (auto err = mIncFs->makeFile(ifs->control, normPath, mode, id, params); err) {
- LOG(ERROR) << "Internal error: storageId " << storage << " failed to makeFile: " << err;
+ LOG(ERROR) << "Internal error: storageId " << storage << " failed to makeFile [" << normPath
+ << "]: " << err;
return err;
}
if (params.size > 0) {
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index bf4e9616..73e00ae 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -171,7 +171,9 @@
}
details::CStrWrapper::CStrWrapper(std::string_view sv) {
- if (sv[sv.size()] == '\0') {
+ if (!sv.data()) {
+ mCstr = "";
+ } else if (sv[sv.size()] == '\0') {
mCstr = sv.data();
} else {
mCopy.emplace(sv);