Remove SignApk output limitation of 2GiB
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 apksigner verify --in $OUT/../generic_x86_64/system/apex/com.android.art.testing.apex --print-certs -v --min-sdk-version 23 Change-Id: Id31eae0f221dd7ef333bd12aeef591463e1c931a
This commit is contained in:
parent
7bbfeb147e
commit
4045ae7871
1 changed files with 23 additions and 14 deletions
|
@ -987,6 +987,9 @@ class SignApk {
|
|||
|
||||
private static class ZipSections {
|
||||
DataSource beforeCentralDir;
|
||||
|
||||
// The following fields are still valid after closing the backing DataSource.
|
||||
long beforeCentralDirSize;
|
||||
ByteBuffer centralDir;
|
||||
ByteBuffer eocd;
|
||||
}
|
||||
|
@ -1006,7 +1009,9 @@ class SignApk {
|
|||
}
|
||||
|
||||
ZipSections result = new ZipSections();
|
||||
|
||||
result.beforeCentralDir = apk.slice(0, centralDirStartOffset);
|
||||
result.beforeCentralDirSize = result.beforeCentralDir.size();
|
||||
|
||||
long centralDirSize = centralDirEndOffset - centralDirStartOffset;
|
||||
if (centralDirSize >= Integer.MAX_VALUE) throw new IndexOutOfBoundsException();
|
||||
|
@ -1270,11 +1275,8 @@ class SignApk {
|
|||
// signatures)
|
||||
apkSigner.inputApkSigningBlock(null);
|
||||
|
||||
// Build the output APK in memory, by copying input APK's ZIP entries across
|
||||
// and then signing the output APK.
|
||||
ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
|
||||
CountingOutputStream outputJarCounter =
|
||||
new CountingOutputStream(v1SignedApkBuf);
|
||||
new CountingOutputStream(outputFile);
|
||||
JarOutputStream outputJar = new JarOutputStream(outputJarCounter);
|
||||
// Use maximum compression for compressed entries because the APK lives forever
|
||||
// on the system partition.
|
||||
|
@ -1287,10 +1289,13 @@ class SignApk {
|
|||
addV1Signature(apkSigner, addV1SignatureRequest, outputJar, timestamp);
|
||||
addV1SignatureRequest.done();
|
||||
}
|
||||
|
||||
// close output and switch to input mode
|
||||
outputJar.close();
|
||||
ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
|
||||
v1SignedApkBuf.reset();
|
||||
ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk};
|
||||
outputJar = null;
|
||||
outputJarCounter = null;
|
||||
outputFile = null;
|
||||
RandomAccessFile v1SignedApk = new RandomAccessFile(outputFilename, "r");
|
||||
|
||||
ZipSections zipSections = findMainZipSections(DataSources.asDataSource(
|
||||
v1SignedApk));
|
||||
|
@ -1299,6 +1304,9 @@ class SignApk {
|
|||
eocd.put(zipSections.eocd);
|
||||
eocd.flip();
|
||||
eocd.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
ByteBuffer[] outputChunks = new ByteBuffer[] {};
|
||||
|
||||
// This loop is supposed to be iterated twice at most.
|
||||
// The second pass is to align the file size after amending EOCD comments
|
||||
// with assumption that re-generated signing block would be the same size.
|
||||
|
@ -1325,13 +1333,8 @@ class SignApk {
|
|||
modifiedEocd,
|
||||
zipSections.beforeCentralDir.size() + padding +
|
||||
apkSigningBlock.length);
|
||||
if (zipSections.beforeCentralDir.size() >= Integer.MAX_VALUE) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
outputChunks =
|
||||
new ByteBuffer[] {
|
||||
zipSections.beforeCentralDir.getByteBuffer(0,
|
||||
(int)zipSections.beforeCentralDir.size()),
|
||||
ByteBuffer.allocate(padding),
|
||||
ByteBuffer.wrap(apkSigningBlock),
|
||||
zipSections.centralDir,
|
||||
|
@ -1345,7 +1348,7 @@ class SignApk {
|
|||
|
||||
// Calculate the file size
|
||||
eocd = modifiedEocd;
|
||||
int fileSize = 0;
|
||||
long fileSize = zipSections.beforeCentralDirSize;
|
||||
for (ByteBuffer buf : outputChunks) {
|
||||
fileSize += buf.remaining();
|
||||
}
|
||||
|
@ -1354,7 +1357,7 @@ class SignApk {
|
|||
break;
|
||||
}
|
||||
// Pad EOCD comment to align the file size.
|
||||
int commentLen = alignment - fileSize % alignment;
|
||||
int commentLen = alignment - (int)(fileSize % alignment);
|
||||
modifiedEocd = ByteBuffer.allocate(eocd.remaining() + commentLen);
|
||||
modifiedEocd.put(eocd);
|
||||
modifiedEocd.rewind();
|
||||
|
@ -1365,6 +1368,12 @@ class SignApk {
|
|||
eocd = modifiedEocd;
|
||||
}
|
||||
|
||||
// close input and switch back to output mode
|
||||
v1SignedApk.close();
|
||||
v1SignedApk = null;
|
||||
outputFile = new FileOutputStream(outputFilename, true);
|
||||
outputFile.getChannel().truncate(zipSections.beforeCentralDirSize);
|
||||
|
||||
// This assumes outputChunks are array-backed. To avoid this assumption, the
|
||||
// code could be rewritten to use FileChannel.
|
||||
for (ByteBuffer outputChunk : outputChunks) {
|
||||
|
|
Loading…
Reference in a new issue