Replace some ByteBuffers with DataSource

This avoids ByteArray 2GiB limit in a few places, but requires more
changes to SignApk to fully support large archives.

Bug: 302112430
Test: build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_x86_64 TARGET_RELEASE=trunk_staging CLANG_COVERAGE=true NATIVE_COVERAGE_PATHS="art external/aac external/boringssl external/conscrypt external/cpu_features external/dlmalloc external/fdlibm external/libaom external/libavc external/libcxx external/libfuse external/libgav1 external/libgsm external/libhevc external/libmpeg2 external/libopus external/libtextclassifier external/libvpx external/libxaac external/oj-libjdwp external/sonivox external/speex external/tremolo external/vixl frameworks/av frameworks/base/media libcore libnativehelper packages/modules/Bluetooth packages/modules/Connectivity packages/modules/DnsResolver packages/modules/ExtServices packages/modules/NetworkStack packages/modules/NeuralNetworks packages/modules/SdkExtensions packages/modules/StatsD packages/providers/MediaProvider system/core/base system/core/libcutils system/core/libstats system/media/audio_utils system/netd/resolv" com.android.art.testing
Change-Id: Ie7fc0bbce9ef43b6331143703ac5568cf1b2186a
This commit is contained in:
Tomasz Wasilczyk
2024-03-13 03:16:53 +00:00
parent 933d07a1b3
commit 4b114c29ec

View File

@@ -986,15 +986,14 @@ class SignApk {
} }
private static class ZipSections { private static class ZipSections {
ByteBuffer beforeCentralDir; DataSource beforeCentralDir;
ByteBuffer centralDir; ByteBuffer centralDir;
ByteBuffer eocd; ByteBuffer eocd;
} }
private static ZipSections findMainZipSections(ByteBuffer apk) private static ZipSections findMainZipSections(DataSource apk)
throws IOException, ZipFormatException { throws IOException, ZipFormatException {
apk.slice(); ApkUtils.ZipSections sections = ApkUtils.findZipSections(apk);
ApkUtils.ZipSections sections = ApkUtils.findZipSections(DataSources.asDataSource(apk));
long centralDirStartOffset = sections.getZipCentralDirectoryOffset(); long centralDirStartOffset = sections.getZipCentralDirectoryOffset();
long centralDirSizeBytes = sections.getZipCentralDirectorySizeBytes(); long centralDirSizeBytes = sections.getZipCentralDirectorySizeBytes();
long centralDirEndOffset = centralDirStartOffset + centralDirSizeBytes; long centralDirEndOffset = centralDirStartOffset + centralDirSizeBytes;
@@ -1005,25 +1004,18 @@ class SignApk {
+ ". CD end: " + centralDirEndOffset + ". CD end: " + centralDirEndOffset
+ ", EoCD start: " + eocdStartOffset); + ", EoCD start: " + eocdStartOffset);
} }
apk.position(0);
apk.limit((int) centralDirStartOffset);
ByteBuffer beforeCentralDir = apk.slice();
apk.position((int) centralDirStartOffset);
apk.limit((int) centralDirEndOffset);
ByteBuffer centralDir = apk.slice();
apk.position((int) eocdStartOffset);
apk.limit(apk.capacity());
ByteBuffer eocd = apk.slice();
apk.position(0);
apk.limit(apk.capacity());
ZipSections result = new ZipSections(); ZipSections result = new ZipSections();
result.beforeCentralDir = beforeCentralDir; result.beforeCentralDir = apk.slice(0, centralDirStartOffset);
result.centralDir = centralDir;
result.eocd = eocd; long centralDirSize = centralDirEndOffset - centralDirStartOffset;
if (centralDirSize >= Integer.MAX_VALUE) throw new IndexOutOfBoundsException();
result.centralDir = apk.getByteBuffer(centralDirStartOffset, (int)centralDirSize);
long eocdSize = apk.size() - eocdStartOffset;
if (eocdSize >= Integer.MAX_VALUE) throw new IndexOutOfBoundsException();
result.eocd = apk.getByteBuffer(eocdStartOffset, (int)eocdSize);
return result; return result;
} }
@@ -1300,7 +1292,8 @@ class SignApk {
v1SignedApkBuf.reset(); v1SignedApkBuf.reset();
ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk}; ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk};
ZipSections zipSections = findMainZipSections(v1SignedApk); ZipSections zipSections = findMainZipSections(DataSources.asDataSource(
v1SignedApk));
ByteBuffer eocd = ByteBuffer.allocate(zipSections.eocd.remaining()); ByteBuffer eocd = ByteBuffer.allocate(zipSections.eocd.remaining());
eocd.put(zipSections.eocd); eocd.put(zipSections.eocd);
@@ -1312,7 +1305,7 @@ class SignApk {
while (true) { while (true) {
ApkSignerEngine.OutputApkSigningBlockRequest2 addV2SignatureRequest = ApkSignerEngine.OutputApkSigningBlockRequest2 addV2SignatureRequest =
apkSigner.outputZipSections2( apkSigner.outputZipSections2(
DataSources.asDataSource(zipSections.beforeCentralDir), zipSections.beforeCentralDir,
DataSources.asDataSource(zipSections.centralDir), DataSources.asDataSource(zipSections.centralDir),
DataSources.asDataSource(eocd)); DataSources.asDataSource(eocd));
if (addV2SignatureRequest == null) break; if (addV2SignatureRequest == null) break;
@@ -1330,11 +1323,15 @@ class SignApk {
modifiedEocd.order(ByteOrder.LITTLE_ENDIAN); modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
ApkUtils.setZipEocdCentralDirectoryOffset( ApkUtils.setZipEocdCentralDirectoryOffset(
modifiedEocd, modifiedEocd,
zipSections.beforeCentralDir.remaining() + padding + zipSections.beforeCentralDir.size() + padding +
apkSigningBlock.length); apkSigningBlock.length);
if (zipSections.beforeCentralDir.size() >= Integer.MAX_VALUE) {
throw new IndexOutOfBoundsException();
}
outputChunks = outputChunks =
new ByteBuffer[] { new ByteBuffer[] {
zipSections.beforeCentralDir, zipSections.beforeCentralDir.getByteBuffer(0,
(int)zipSections.beforeCentralDir.size()),
ByteBuffer.allocate(padding), ByteBuffer.allocate(padding),
ByteBuffer.wrap(apkSigningBlock), ByteBuffer.wrap(apkSigningBlock),
zipSections.centralDir, zipSections.centralDir,