mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Fix NegativeArraySizeException caused by missing unsigned conversion
Update `ZipContent` so that `eocd.totalNumberOfCentralDirectoryEntries` is converted from a short to an unsigned int to prevent a negative number from being used. This commit also updates the code to consistently use `X.toUnsigned...` helper methods rather than using bitwise operators. Fixed gh-38572
This commit is contained in:
parent
86c2f28cb4
commit
8c7e8778a6
@ -53,8 +53,8 @@ class VirtualZipDataBlock extends VirtualDataBlock implements CloseableDataBlock
|
||||
long centralRecordPos = centralRecordPositions[i];
|
||||
DataBlock name = new DataPart(
|
||||
centralRecordPos + ZipCentralDirectoryFileHeaderRecord.FILE_NAME_OFFSET + nameOffset,
|
||||
(centralRecord.fileNameLength() & 0xFFFF) - nameOffset);
|
||||
long localRecordPos = centralRecord.offsetToLocalHeader() & 0xFFFFFFFF;
|
||||
Short.toUnsignedLong(centralRecord.fileNameLength()) - nameOffset);
|
||||
long localRecordPos = Integer.toUnsignedLong(centralRecord.offsetToLocalHeader());
|
||||
ZipLocalFileHeaderRecord localRecord = ZipLocalFileHeaderRecord.load(this.data, localRecordPos);
|
||||
DataBlock content = new DataPart(localRecordPos + localRecord.size(), centralRecord.compressedSize());
|
||||
boolean hasDescriptorRecord = ZipDataDescriptorRecord.isPresentBasedOnFlag(centralRecord);
|
||||
@ -74,8 +74,8 @@ class VirtualZipDataBlock extends VirtualDataBlock implements CloseableDataBlock
|
||||
long originalRecordPos, DataBlock name, int offsetToLocalHeader) throws IOException {
|
||||
ZipCentralDirectoryFileHeaderRecord record = originalRecord.withFileNameLength((short) (name.size() & 0xFFFF))
|
||||
.withOffsetToLocalHeader(offsetToLocalHeader);
|
||||
int originalExtraFieldLength = originalRecord.extraFieldLength() & 0xFFFF;
|
||||
int originalFileCommentLength = originalRecord.fileCommentLength() & 0xFFFF;
|
||||
int originalExtraFieldLength = Short.toUnsignedInt(originalRecord.extraFieldLength());
|
||||
int originalFileCommentLength = Short.toUnsignedInt(originalRecord.fileCommentLength());
|
||||
DataBlock extraFieldAndComment = new DataPart(
|
||||
originalRecordPos + originalRecord.size() - originalExtraFieldLength - originalFileCommentLength,
|
||||
originalExtraFieldLength + originalFileCommentLength);
|
||||
@ -89,8 +89,8 @@ class VirtualZipDataBlock extends VirtualDataBlock implements CloseableDataBlock
|
||||
ZipLocalFileHeaderRecord originalRecord, ZipDataDescriptorRecord dataDescriptorRecord, DataBlock name,
|
||||
DataBlock content) throws IOException {
|
||||
ZipLocalFileHeaderRecord record = originalRecord.withFileNameLength((short) (name.size() & 0xFFFF));
|
||||
long originalRecordPos = centralRecord.offsetToLocalHeader() & 0xFFFFFFFF;
|
||||
int extraFieldLength = originalRecord.extraFieldLength() & 0xFFFF;
|
||||
long originalRecordPos = Integer.toUnsignedLong(centralRecord.offsetToLocalHeader());
|
||||
int extraFieldLength = Short.toUnsignedInt(originalRecord.extraFieldLength());
|
||||
parts.add(new ByteArrayDataBlock(record.asByteArray()));
|
||||
parts.add(name);
|
||||
parts.add(new DataPart(originalRecordPos + originalRecord.size() - extraFieldLength, extraFieldLength));
|
||||
|
@ -83,14 +83,14 @@ record ZipCentralDirectoryFileHeaderRecord(short versionMadeBy, short versionNee
|
||||
* @throws IOException on I/O error
|
||||
*/
|
||||
void copyTo(DataBlock dataBlock, long pos, ZipEntry zipEntry) throws IOException {
|
||||
int fileNameLength = fileNameLength() & 0xFFFF;
|
||||
int extraLength = extraFieldLength() & 0xFFFF;
|
||||
int commentLength = fileCommentLength() & 0xFFFF;
|
||||
zipEntry.setMethod(compressionMethod() & 0xFFFF);
|
||||
int fileNameLength = Short.toUnsignedInt(fileNameLength());
|
||||
int extraLength = Short.toUnsignedInt(extraFieldLength());
|
||||
int commentLength = Short.toUnsignedInt(fileCommentLength());
|
||||
zipEntry.setMethod(Short.toUnsignedInt(compressionMethod()));
|
||||
zipEntry.setTime(decodeMsDosFormatDateTime(lastModFileDate(), lastModFileTime()));
|
||||
zipEntry.setCrc(crc32() & 0xFFFFFFFFL);
|
||||
zipEntry.setCompressedSize(compressedSize() & 0xFFFFFFFFL);
|
||||
zipEntry.setSize(uncompressedSize() & 0xFFFFFFFFL);
|
||||
zipEntry.setCrc(Integer.toUnsignedLong(crc32()));
|
||||
zipEntry.setCompressedSize(Integer.toUnsignedLong(compressedSize()));
|
||||
zipEntry.setSize(Integer.toUnsignedLong(uncompressedSize()));
|
||||
if (extraLength > 0) {
|
||||
long extraPos = pos + MINIMUM_SIZE + fileNameLength;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(extraLength);
|
||||
|
@ -556,13 +556,16 @@ public final class ZipContent implements Closeable {
|
||||
Zip64EndOfCentralDirectoryRecord zip64Eocd = Zip64EndOfCentralDirectoryRecord.load(data, zip64Locator);
|
||||
data = data.slice(getStartOfZipContent(data, eocd, zip64Eocd));
|
||||
long centralDirectoryPos = (zip64Eocd != null) ? zip64Eocd.offsetToStartOfCentralDirectory()
|
||||
: eocd.offsetToStartOfCentralDirectory();
|
||||
: Integer.toUnsignedLong(eocd.offsetToStartOfCentralDirectory());
|
||||
long numberOfEntries = (zip64Eocd != null) ? zip64Eocd.totalNumberOfCentralDirectoryEntries()
|
||||
: eocd.totalNumberOfCentralDirectoryEntries();
|
||||
if (numberOfEntries > 0xFFFFFFFFL) {
|
||||
: Short.toUnsignedInt(eocd.totalNumberOfCentralDirectoryEntries());
|
||||
if (numberOfEntries < 0) {
|
||||
throw new IllegalStateException("Invalid number of zip entries in " + source);
|
||||
}
|
||||
if (numberOfEntries > Integer.MAX_VALUE) {
|
||||
throw new IllegalStateException("Too many zip entries in " + source);
|
||||
}
|
||||
Loader loader = new Loader(source, null, data, centralDirectoryPos, (int) (numberOfEntries & 0xFFFFFFFFL));
|
||||
Loader loader = new Loader(source, null, data, centralDirectoryPos, (int) numberOfEntries);
|
||||
ByteBuffer signatureNameSuffixBuffer = ByteBuffer.allocate(SIGNATURE_SUFFIX.length);
|
||||
boolean hasJarSignatureFile = false;
|
||||
long pos = centralDirectoryPos;
|
||||
|
@ -286,7 +286,7 @@ final class ZipString {
|
||||
}
|
||||
|
||||
private static int getCodePointSize(byte[] bytes, int i) {
|
||||
int b = bytes[i] & 0xFF;
|
||||
int b = Byte.toUnsignedInt(bytes[i]);
|
||||
if ((b & 0b1_0000000) == 0b0_0000000) {
|
||||
return 1;
|
||||
}
|
||||
@ -300,7 +300,7 @@ final class ZipString {
|
||||
}
|
||||
|
||||
private static int getCodePoint(byte[] bytes, int i, int codePointSize) {
|
||||
int codePoint = bytes[i] & 0xFF;
|
||||
int codePoint = Byte.toUnsignedInt(bytes[i]);
|
||||
codePoint &= INITIAL_BYTE_BITMASK[codePointSize - 1];
|
||||
for (int j = 1; j < codePointSize; j++) {
|
||||
codePoint = (codePoint << 6) + (bytes[i + j] & SUBSEQUENT_BYTE_BITMASK);
|
||||
|
Loading…
Reference in New Issue
Block a user