From 8c1d9872d2766037c498685b6a674de63e7cf248 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sun, 1 Sep 2024 15:09:29 -0700 Subject: [PATCH] Fix support for large zip files Update `spring-boot-loader` to support large zip files by correctly dealing with unsigned ints. Fixes gh-42012 --- .../boot/loader/zip/FileDataBlock.java | 5 +++-- .../springframework/boot/loader/zip/ZipContent.java | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/FileDataBlock.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/FileDataBlock.java index cd0a1da4321..34acb8729f2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/FileDataBlock.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/FileDataBlock.java @@ -71,14 +71,15 @@ class FileDataBlock implements CloseableDataBlock { throw new IllegalArgumentException("Position must not be negative"); } ensureOpen(ClosedChannelException::new); - int remaining = (int) (this.size - pos); + long remaining = this.size - pos; if (remaining <= 0) { return -1; } int originalDestinationLimit = -1; if (dst.remaining() > remaining) { originalDestinationLimit = dst.limit(); - dst.limit(dst.position() + remaining); + long updatedLimit = dst.position() + remaining; + dst.limit((updatedLimit > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) updatedLimit); } int result = this.fileAccess.read(dst, this.offset + pos); if (originalDestinationLimit != -1) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/ZipContent.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/ZipContent.java index d9c5f1c689c..7a61b789a7c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/ZipContent.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/zip/ZipContent.java @@ -636,7 +636,8 @@ public final class ZipContent implements Closeable { private static long getStartOfZipContent(FileDataBlock data, ZipEndOfCentralDirectoryRecord eocd, Zip64EndOfCentralDirectoryRecord zip64Eocd) throws IOException { long specifiedOffsetToStartOfCentralDirectory = (zip64Eocd != null) - ? zip64Eocd.offsetToStartOfCentralDirectory() : eocd.offsetToStartOfCentralDirectory(); + ? zip64Eocd.offsetToStartOfCentralDirectory() + : Integer.toUnsignedLong(eocd.offsetToStartOfCentralDirectory()); long sizeOfCentralDirectoryAndEndRecords = getSizeOfCentralDirectoryAndEndRecords(eocd, zip64Eocd); long actualOffsetToStartOfCentralDirectory = data.size() - sizeOfCentralDirectoryAndEndRecords; return actualOffsetToStartOfCentralDirectory - specifiedOffsetToStartOfCentralDirectory; @@ -650,7 +651,8 @@ public final class ZipContent implements Closeable { result += Zip64EndOfCentralDirectoryLocator.SIZE; result += zip64Eocd.size(); } - result += (zip64Eocd != null) ? zip64Eocd.sizeOfCentralDirectory() : eocd.sizeOfCentralDirectory(); + result += (zip64Eocd != null) ? zip64Eocd.sizeOfCentralDirectory() + : Integer.toUnsignedLong(eocd.sizeOfCentralDirectory()); return result; } @@ -796,10 +798,10 @@ public final class ZipContent implements Closeable { private FileDataBlock getContent() throws IOException { FileDataBlock content = this.content; if (content == null) { - int pos = this.centralRecord.offsetToLocalHeader(); + long pos = Integer.toUnsignedLong(this.centralRecord.offsetToLocalHeader()); checkNotZip64Extended(pos); ZipLocalFileHeaderRecord localHeader = ZipLocalFileHeaderRecord.load(ZipContent.this.data, pos); - int size = this.centralRecord.compressedSize(); + long size = Integer.toUnsignedLong(this.centralRecord.compressedSize()); checkNotZip64Extended(size); content = ZipContent.this.data.slice(pos + localHeader.size(), size); this.content = content; @@ -807,7 +809,7 @@ public final class ZipContent implements Closeable { return content; } - private void checkNotZip64Extended(int value) throws IOException { + private void checkNotZip64Extended(long value) throws IOException { if (value == 0xFFFFFFFF) { throw new IOException("Zip64 extended information extra fields are not supported"); }