This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
commit 95541c966ba97cc1428e2c5d223f83105145b550 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sun Jan 1 09:18:51 2023 -0500 Sort members --- .../archivers/zip/X5455_ExtendedTimestamp.java | 140 +++--- .../compress/archivers/zip/ZipArchiveEntry.java | 480 ++++++++++----------- .../commons/compress/archivers/zip/ZipUtil.java | 82 ++-- .../archivers/zip/ZipArchiveEntryTest.java | 184 ++++---- .../compress/archivers/zip/ZipUtilTest.java | 66 +-- .../harmony/pack200/tests/ArchiveTest.java | 18 +- .../harmony/pack200/tests/BHSDCodecTest.java | 8 +- .../harmony/pack200/tests/CodecEncodingTest.java | 66 +-- .../compress/harmony/pack200/tests/CodecTest.java | 84 ++-- .../harmony/pack200/tests/PopulationCodecTest.java | 16 +- .../harmony/pack200/tests/RunCodecTest.java | 18 +- .../unpack200/tests/AttributeLayoutTest.java | 36 +- .../harmony/unpack200/tests/ICTupleTest.java | 18 +- .../harmony/unpack200/tests/SegmentUtilsTest.java | 12 +- .../commons/compress/utils/TimeUtilsTest.java | 62 +-- 15 files changed, 645 insertions(+), 645 deletions(-) diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java b/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java index 1e030268..12d8ab91 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java @@ -141,6 +141,12 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial return time == null ? null : unixTimeToZipLong(TimeUtils.toUnixTime(time)); } + private static FileTime unixTimeToFileTime(final ZipLong unixTime) { + return unixTime != null ? TimeUtils.unixTimeToFileTime(unixTime.getIntValue()) : null; + } + // The 3 boolean fields (below) come from this flags byte. The remaining 5 bits + // are ignored according to the current version of the spec (December 2012). + private static ZipLong unixTimeToZipLong(final long unixTime) { if (!TimeUtils.isUnixTime(unixTime)) { throw new IllegalArgumentException("X5455 timestamps must fit in a signed 32 bit integer: " + unixTime); @@ -152,12 +158,6 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial return unixTime != null ? new Date(unixTime.getIntValue() * 1000L) : null; } - private static FileTime unixTimeToFileTime(final ZipLong unixTime) { - return unixTime != null ? TimeUtils.unixTimeToFileTime(unixTime.getIntValue()) : null; - } - // The 3 boolean fields (below) come from this flags byte. The remaining 5 bits - // are ignored according to the current version of the spec (December 2012). - private byte flags; // Note: even if bit1 and bit2 are set, the Central data will still not contain // access/create fields: only local data ever holds those! This causes @@ -200,28 +200,28 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial } /** - * Gets the access time as a java.util.Date + * Gets the access time as a {@link FileTime} * of this zip entry, or null if no such timestamp exists in the zip entry. * The milliseconds are always zeroed out, since the underlying data * offers only per-second precision. * - * @return access time as java.util.Date or null. + * @return modify time as {@link FileTime} or null. + * @since 1.23 */ - public Date getAccessJavaTime() { - return zipLongToDate(accessTime); + public FileTime getAccessFileTime() { + return unixTimeToFileTime(accessTime); } /** - * Gets the access time as a {@link FileTime} + * Gets the access time as a java.util.Date * of this zip entry, or null if no such timestamp exists in the zip entry. * The milliseconds are always zeroed out, since the underlying data * offers only per-second precision. * - * @return modify time as {@link FileTime} or null. - * @since 1.23 + * @return access time as java.util.Date or null. */ - public FileTime getAccessFileTime() { - return unixTimeToFileTime(accessTime); + public Date getAccessJavaTime() { + return zipLongToDate(accessTime); } /** @@ -263,6 +263,19 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial return new ZipShort(1 + (bit0_modifyTimePresent ? 4 : 0)); } + /** + * Gets the create time as a {@link FileTime} + * of this zip entry, or null if no such timestamp exists in the zip entry. + * The milliseconds are always zeroed out, since the underlying data + * offers only per-second precision. + * + * @return modify time as {@link FileTime} or null. + * @since 1.23 + */ + public FileTime getCreateFileTime() { + return unixTimeToFileTime(createTime); + } + /** * <p> * Gets the create time as a a java.util.Date @@ -283,19 +296,6 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial return zipLongToDate(createTime); } - /** - * Gets the create time as a {@link FileTime} - * of this zip entry, or null if no such timestamp exists in the zip entry. - * The milliseconds are always zeroed out, since the underlying data - * offers only per-second precision. - * - * @return modify time as {@link FileTime} or null. - * @since 1.23 - */ - public FileTime getCreateFileTime() { - return unixTimeToFileTime(createTime); - } - /** * <p> * Gets the create time (seconds since epoch) of this zip entry @@ -386,28 +386,28 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial } /** - * Gets the modify time as a java.util.Date + * Gets the modify time as a {@link FileTime} * of this zip entry, or null if no such timestamp exists in the zip entry. * The milliseconds are always zeroed out, since the underlying data * offers only per-second precision. * - * @return modify time as java.util.Date or null. + * @return modify time as {@link FileTime} or null. + * @since 1.23 */ - public Date getModifyJavaTime() { - return zipLongToDate(modifyTime); + public FileTime getModifyFileTime() { + return unixTimeToFileTime(modifyTime); } /** - * Gets the modify time as a {@link FileTime} + * Gets the modify time as a java.util.Date * of this zip entry, or null if no such timestamp exists in the zip entry. * The milliseconds are always zeroed out, since the underlying data * offers only per-second precision. * - * @return modify time as {@link FileTime} or null. - * @since 1.23 + * @return modify time as java.util.Date or null. */ - public FileTime getModifyFileTime() { - return unixTimeToFileTime(modifyTime); + public Date getModifyJavaTime() { + return zipLongToDate(modifyTime); } /** @@ -528,8 +528,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial /** * <p> - * Sets the access time as a java.util.Date - * of this zip entry. Supplied value is truncated to per-second + * Sets the acccess time as a {@link FileTime} + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -537,16 +537,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param d access time as java.util.Date + * @param time access time as {@link FileTime} + * @since 1.23 */ - public void setAccessJavaTime(final Date d) { - setAccessTime(dateToZipLong(d)); + public void setAccessFileTime(final FileTime time) { + setAccessTime(fileTimeToZipLong(time)); } /** * <p> - * Sets the acccess time as a {@link FileTime} - * of this zip entry. Supplied value is truncated to per-second + * Sets the access time as a java.util.Date + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -554,11 +555,10 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param time access time as {@link FileTime} - * @since 1.23 + * @param d access time as java.util.Date */ - public void setAccessFileTime(final FileTime time) { - setAccessTime(fileTimeToZipLong(time)); + public void setAccessJavaTime(final Date d) { + setAccessTime(dateToZipLong(d)); } /** @@ -581,8 +581,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial /** * <p> - * Sets the create time as a java.util.Date - * of this zip entry. Supplied value is truncated to per-second + * Sets the create time as a {@link FileTime} + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -590,14 +590,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param d create time as java.util.Date + * @param time create time as {@link FileTime} + * @since 1.23 */ - public void setCreateJavaTime(final Date d) { setCreateTime(dateToZipLong(d)); } + public void setCreateFileTime(final FileTime time) { + setCreateTime(fileTimeToZipLong(time)); + } /** * <p> - * Sets the create time as a {@link FileTime} - * of this zip entry. Supplied value is truncated to per-second + * Sets the create time as a java.util.Date + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -605,12 +608,9 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param time create time as {@link FileTime} - * @since 1.23 + * @param d create time as java.util.Date */ - public void setCreateFileTime(final FileTime time) { - setCreateTime(fileTimeToZipLong(time)); - } + public void setCreateJavaTime(final Date d) { setCreateTime(dateToZipLong(d)); } /** * <p> @@ -653,8 +653,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial /** * <p> - * Sets the modify time as a java.util.Date - * of this zip entry. Supplied value is truncated to per-second + * Sets the modify time as a {@link FileTime} + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -662,16 +662,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param d modify time as java.util.Date + * @param time modify time as {@link FileTime} + * @since 1.23 */ - public void setModifyJavaTime(final Date d) { - setModifyTime(dateToZipLong(d)); + public void setModifyFileTime(final FileTime time) { + setModifyTime(fileTimeToZipLong(time)); } /** * <p> - * Sets the modify time as a {@link FileTime} - * of this zip entry. Supplied value is truncated to per-second + * Sets the modify time as a java.util.Date + * of this zip entry. Supplied value is truncated to per-second * precision (milliseconds zeroed-out). * </p><p> * Note: the setters for flags and timestamps are decoupled. @@ -679,11 +680,10 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial * out if the corresponding bit in the flags is also set. * </p> * - * @param time modify time as {@link FileTime} - * @since 1.23 + * @param d modify time as java.util.Date */ - public void setModifyFileTime(final FileTime time) { - setModifyTime(fileTimeToZipLong(time)); + public void setModifyJavaTime(final Date d) { + setModifyTime(dateToZipLong(d)); } /** diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java index bf233b12..d75d2fcb 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java @@ -236,6 +236,15 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn private static final int SHORT_SHIFT = 16; + private static boolean canConvertToInfoZipExtendedTimestamp( + final FileTime lastModifiedTime, + final FileTime lastAccessTime, + final FileTime creationTime) { + return TimeUtils.isUnixTime(lastModifiedTime) + && TimeUtils.isUnixTime(lastAccessTime) + && TimeUtils.isUnixTime(creationTime); + } + /** * The {@link java.util.zip.ZipEntry} base class only supports * the compression methods STORED and DEFLATED. We override the @@ -247,7 +256,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn * >COMPRESS-93</a> */ private int method = ZipMethod.UNKNOWN_CODE; - /** * The {@link java.util.zip.ZipEntry#setSize} method in the base * class throws an IllegalArgumentException if the size is bigger @@ -274,6 +282,7 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn private long dataOffset = OFFSET_UNKNOWN; private boolean isStreamContiguous; private NameSource nameSource = NameSource.NAME; + private CommentSource commentSource = CommentSource.COMMENT; private long diskNumberStart; @@ -355,17 +364,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setAttributes(inputPath, options); } - private void setAttributes(final Path inputPath, final LinkOption... options) throws IOException { - final BasicFileAttributes attributes = Files.readAttributes(inputPath, BasicFileAttributes.class, options); - if (attributes.isRegularFile()) { - setSize(attributes.size()); - } - super.setLastModifiedTime(attributes.lastModifiedTime()); - super.setCreationTime(attributes.creationTime()); - super.setLastAccessTime(attributes.lastAccessTime()); - setExtraTimeFields(); - } - /** * Creates a new zip entry with the specified name. * @@ -437,19 +435,38 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setExtra(); } - private void internalAddExtraField(final ZipExtraField ze) { - if (ze instanceof UnparseableExtraFieldData) { - unparseableExtra = (UnparseableExtraFieldData) ze; - } else if (extraFields == null) { - extraFields = new ZipExtraField[]{ze}; - } else { - if (getExtraField(ze.getHeaderId()) != null) { - internalRemoveExtraField(ze.getHeaderId()); - } - final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1); - zipExtraFields[zipExtraFields.length - 1] = ze; - extraFields = zipExtraFields; + private void addInfoZipExtendedTimestamp( + final FileTime lastModifiedTime, + final FileTime lastAccessTime, + final FileTime creationTime) { + final X5455_ExtendedTimestamp infoZipTimestamp = new X5455_ExtendedTimestamp(); + if (lastModifiedTime != null) { + infoZipTimestamp.setModifyFileTime(lastModifiedTime); + } + if (lastAccessTime != null) { + infoZipTimestamp.setAccessFileTime(lastAccessTime); + } + if (creationTime != null) { + infoZipTimestamp.setCreateFileTime(creationTime); + } + internalAddExtraField(infoZipTimestamp); + } + + private void addNTFSTimestamp( + final FileTime lastModifiedTime, + final FileTime lastAccessTime, + final FileTime creationTime) { + final X000A_NTFS ntfsTimestamp = new X000A_NTFS(); + if (lastModifiedTime != null) { + ntfsTimestamp.setModifyFileTime(lastModifiedTime); + } + if (lastAccessTime != null) { + ntfsTimestamp.setAccessFileTime(lastAccessTime); + } + if (creationTime != null) { + ntfsTimestamp.setCreateFileTime(creationTime); } + internalAddExtraField(ntfsTimestamp); } /** @@ -472,79 +489,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn return cpy; } - /** - * {@inheritDoc} - * - * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p> - * - * @return The last modification time of the entry in milliseconds - * since the epoch, or -1 if not specified - * - * @see #setTime(long) - * @see #setLastModifiedTime(FileTime) - */ - @Override - public long getTime() { - if (lastModifiedDateSet) { - return getLastModifiedTime().toMillis(); - } - return time != -1 ? time : super.getTime(); - } - - /** - * - * {@inheritDoc} - * - * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p> - * - * @param time - * The last modification time of the entry in milliseconds - * since the epoch - * @see #getTime() - * @see #getLastModifiedTime() - */ - @Override - public void setTime(final long time) { - if (ZipUtil.isDosTime(time)) { - super.setTime(time); - this.time = time; - lastModifiedDateSet = false; - setExtraTimeFields(); - } else { - setLastModifiedTime(FileTime.fromMillis(time)); - } - } - - @Override - public ZipEntry setLastModifiedTime(final FileTime time) { - internalSetLastModifiedTime(time); - setExtraTimeFields(); - return this; - } - - private void internalSetLastModifiedTime(final FileTime time) { - super.setLastModifiedTime(time); - this.time = time.toMillis(); - lastModifiedDateSet = true; - } - - @Override - public ZipEntry setLastAccessTime(final FileTime time) { - super.setLastAccessTime(time); - setExtraTimeFields(); - return this; - } - - @Override - public ZipEntry setCreationTime(final FileTime time) { - super.setCreationTime(time); - setExtraTimeFields(); - return this; - } - /* (non-Javadoc) - * @see Object#equals(Object) - */ - @Override public boolean equals(final Object obj) { if (this == obj) { @@ -911,6 +855,25 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn return size; } + /** + * {@inheritDoc} + * + * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p> + * + * @return The last modification time of the entry in milliseconds + * since the epoch, or -1 if not specified + * + * @see #setTime(long) + * @see #setLastModifiedTime(FileTime) + */ + @Override + public long getTime() { + if (lastModifiedDateSet) { + return getLastModifiedTime().toMillis(); + } + return time != -1 ? time : super.getTime(); + } + /** * Unix permission. * @return the unix permissions @@ -967,6 +930,43 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn return getName().hashCode(); } + private void internalAddExtraField(final ZipExtraField ze) { + if (ze instanceof UnparseableExtraFieldData) { + unparseableExtra = (UnparseableExtraFieldData) ze; + } else if (extraFields == null) { + extraFields = new ZipExtraField[]{ze}; + } else { + if (getExtraField(ze.getHeaderId()) != null) { + internalRemoveExtraField(ze.getHeaderId()); + } + final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1); + zipExtraFields[zipExtraFields.length - 1] = ze; + extraFields = zipExtraFields; + } + } + + private void internalRemoveExtraField(final ZipShort type) { + if (extraFields == null) { + return; + } + final List<ZipExtraField> newResult = new ArrayList<>(); + for (final ZipExtraField extraField : extraFields) { + if (!type.equals(extraField.getHeaderId())) { + newResult.add(extraField); + } + } + if (extraFields.length == newResult.size()) { + return; + } + extraFields = newResult.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY); + } + + private void internalSetLastModifiedTime(final FileTime time) { + super.setLastModifiedTime(time); + this.time = time.toMillis(); + lastModifiedDateSet = true; + } + /** * Is this entry a directory? * @return true if the entry is a directory @@ -1055,22 +1055,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setExtra(); } - private void internalRemoveExtraField(final ZipShort type) { - if (extraFields == null) { - return; - } - final List<ZipExtraField> newResult = new ArrayList<>(); - for (final ZipExtraField extraField : extraFields) { - if (!type.equals(extraField.getHeaderId())) { - newResult.add(extraField); - } - } - if (extraFields.length == newResult.size()) { - return; - } - extraFields = newResult.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY); - } - /** * Removes unparseable extra field data. * @@ -1084,6 +1068,13 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setExtra(); } + private boolean requiresExtraTimeFields() { + if (getLastAccessTime() != null || getCreationTime() != null) { + return true; + } + return lastModifiedDateSet; + } + /** * Sets alignment for this entry. * @@ -1099,73 +1090,15 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn this.alignment = alignment; } - private void setExtraTimeFields() { - if (getExtraField(X5455_ExtendedTimestamp.HEADER_ID) != null) { - internalRemoveExtraField(X5455_ExtendedTimestamp.HEADER_ID); - } - if (getExtraField(X000A_NTFS.HEADER_ID) != null) { - internalRemoveExtraField(X000A_NTFS.HEADER_ID); - } - if (requiresExtraTimeFields()) { - final FileTime lastModifiedTime = getLastModifiedTime(); - final FileTime lastAccessTime = getLastAccessTime(); - final FileTime creationTime = getCreationTime(); - if (canConvertToInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime)) { - addInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime); - } - addNTFSTimestamp(lastModifiedTime, lastAccessTime, creationTime); - } - setExtra(); - } - - private void addInfoZipExtendedTimestamp( - final FileTime lastModifiedTime, - final FileTime lastAccessTime, - final FileTime creationTime) { - final X5455_ExtendedTimestamp infoZipTimestamp = new X5455_ExtendedTimestamp(); - if (lastModifiedTime != null) { - infoZipTimestamp.setModifyFileTime(lastModifiedTime); - } - if (lastAccessTime != null) { - infoZipTimestamp.setAccessFileTime(lastAccessTime); - } - if (creationTime != null) { - infoZipTimestamp.setCreateFileTime(creationTime); - } - internalAddExtraField(infoZipTimestamp); - } - - private boolean requiresExtraTimeFields() { - if (getLastAccessTime() != null || getCreationTime() != null) { - return true; - } - return lastModifiedDateSet; - } - - private void addNTFSTimestamp( - final FileTime lastModifiedTime, - final FileTime lastAccessTime, - final FileTime creationTime) { - final X000A_NTFS ntfsTimestamp = new X000A_NTFS(); - if (lastModifiedTime != null) { - ntfsTimestamp.setModifyFileTime(lastModifiedTime); - } - if (lastAccessTime != null) { - ntfsTimestamp.setAccessFileTime(lastAccessTime); - } - if (creationTime != null) { - ntfsTimestamp.setCreateFileTime(creationTime); + private void setAttributes(final Path inputPath, final LinkOption... options) throws IOException { + final BasicFileAttributes attributes = Files.readAttributes(inputPath, BasicFileAttributes.class, options); + if (attributes.isRegularFile()) { + setSize(attributes.size()); } - internalAddExtraField(ntfsTimestamp); - } - - private static boolean canConvertToInfoZipExtendedTimestamp( - final FileTime lastModifiedTime, - final FileTime lastAccessTime, - final FileTime creationTime) { - return TimeUtils.isUnixTime(lastModifiedTime) - && TimeUtils.isUnixTime(lastAccessTime) - && TimeUtils.isUnixTime(creationTime); + super.setLastModifiedTime(attributes.lastModifiedTime()); + super.setCreationTime(attributes.creationTime()); + super.setLastAccessTime(attributes.lastAccessTime()); + setExtraTimeFields(); } /** @@ -1190,6 +1123,16 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn this.commentSource = commentSource; } + @Override + public ZipEntry setCreationTime(final FileTime time) { + super.setCreationTime(time); + setExtraTimeFields(); + return this; + } + /* (non-Javadoc) + * @see Object#equals(Object) + */ + /** * Sets the data offset. * @@ -1230,67 +1173,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn updateTimeFieldsFromExtraFields(); } - private void updateTimeFieldsFromExtraFields() { - // Update times from X5455_ExtendedTimestamp field - updateTimeFromExtendedTimestampField(); - // Update times from X000A_NTFS field, overriding X5455_ExtendedTimestamp if both are present - updateTimeFromNtfsField(); - } - - /** - * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} does not properly modify - * the entry's {@code xdostime} field, only setting {@code mtime}. While this is not strictly necessary, - * it's better to maintain the same behavior between this and the NTFS field. - */ - private void updateTimeFromExtendedTimestampField() { - final ZipExtraField extraField = getExtraField(X5455_ExtendedTimestamp.HEADER_ID); - if (extraField instanceof X5455_ExtendedTimestamp) { - final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) extraField; - if (extendedTimestamp.isBit0_modifyTimePresent()) { - final FileTime modifyTime = extendedTimestamp.getModifyFileTime(); - if (modifyTime != null) { - internalSetLastModifiedTime(modifyTime); - } - } - if (extendedTimestamp.isBit1_accessTimePresent()) { - final FileTime accessTime = extendedTimestamp.getAccessFileTime(); - if (accessTime != null) { - super.setLastAccessTime(accessTime); - } - } - if (extendedTimestamp.isBit2_createTimePresent()) { - final FileTime creationTime = extendedTimestamp.getCreateFileTime(); - if (creationTime != null) { - super.setCreationTime(creationTime); - } - } - } - } - - /** - * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} parses NTFS - * timestamps with a maximum precision of microseconds, which is lower than the 100ns precision - * provided by this extra field. - */ - private void updateTimeFromNtfsField() { - final ZipExtraField extraField = getExtraField(X000A_NTFS.HEADER_ID); - if (extraField instanceof X000A_NTFS) { - final X000A_NTFS ntfsTimestamp = (X000A_NTFS) extraField; - final FileTime modifyTime = ntfsTimestamp.getModifyFileTime(); - if (modifyTime != null) { - internalSetLastModifiedTime(modifyTime); - } - final FileTime accessTime = ntfsTimestamp.getAccessFileTime(); - if (accessTime != null) { - super.setLastAccessTime(accessTime); - } - final FileTime creationTime = ntfsTimestamp.getCreateFileTime(); - if (creationTime != null) { - super.setCreationTime(creationTime); - } - } - } - /** * Parses the given bytes as extra field data and consumes any * unparseable data as an {@link UnparseableExtraFieldData} @@ -1330,6 +1212,25 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setExtra(); } + private void setExtraTimeFields() { + if (getExtraField(X5455_ExtendedTimestamp.HEADER_ID) != null) { + internalRemoveExtraField(X5455_ExtendedTimestamp.HEADER_ID); + } + if (getExtraField(X000A_NTFS.HEADER_ID) != null) { + internalRemoveExtraField(X000A_NTFS.HEADER_ID); + } + if (requiresExtraTimeFields()) { + final FileTime lastModifiedTime = getLastModifiedTime(); + final FileTime lastAccessTime = getLastAccessTime(); + final FileTime creationTime = getCreationTime(); + if (canConvertToInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime)) { + addInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime); + } + addNTFSTimestamp(lastModifiedTime, lastAccessTime, creationTime); + } + setExtra(); + } + /** * The "general purpose bit" field. * @param b the general purpose bit @@ -1347,6 +1248,20 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn internalAttributes = value; } + @Override + public ZipEntry setLastAccessTime(final FileTime time) { + super.setLastAccessTime(time); + setExtraTimeFields(); + return this; + } + + @Override + public ZipEntry setLastModifiedTime(final FileTime time) { + internalSetLastModifiedTime(time); + setExtraTimeFields(); + return this; + } + protected void setLocalHeaderOffset(final long localHeaderOffset) { this.localHeaderOffset = localHeaderOffset; } @@ -1446,6 +1361,30 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn setTime(fileTime.toMillis()); } + /** + * + * {@inheritDoc} + * + * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p> + * + * @param time + * The last modification time of the entry in milliseconds + * since the epoch + * @see #getTime() + * @see #getLastModifiedTime() + */ + @Override + public void setTime(final long time) { + if (ZipUtil.isDosTime(time)) { + super.setTime(time); + this.time = time; + lastModifiedDateSet = false; + setExtraTimeFields(); + } else { + setLastModifiedTime(FileTime.fromMillis(time)); + } + } + /** * Sets Unix permissions in a way that is understood by Info-Zip's * unzip command. @@ -1479,4 +1418,65 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn public void setVersionRequired(final int versionRequired) { this.versionRequired = versionRequired; } + + private void updateTimeFieldsFromExtraFields() { + // Update times from X5455_ExtendedTimestamp field + updateTimeFromExtendedTimestampField(); + // Update times from X000A_NTFS field, overriding X5455_ExtendedTimestamp if both are present + updateTimeFromNtfsField(); + } + + /** + * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} does not properly modify + * the entry's {@code xdostime} field, only setting {@code mtime}. While this is not strictly necessary, + * it's better to maintain the same behavior between this and the NTFS field. + */ + private void updateTimeFromExtendedTimestampField() { + final ZipExtraField extraField = getExtraField(X5455_ExtendedTimestamp.HEADER_ID); + if (extraField instanceof X5455_ExtendedTimestamp) { + final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) extraField; + if (extendedTimestamp.isBit0_modifyTimePresent()) { + final FileTime modifyTime = extendedTimestamp.getModifyFileTime(); + if (modifyTime != null) { + internalSetLastModifiedTime(modifyTime); + } + } + if (extendedTimestamp.isBit1_accessTimePresent()) { + final FileTime accessTime = extendedTimestamp.getAccessFileTime(); + if (accessTime != null) { + super.setLastAccessTime(accessTime); + } + } + if (extendedTimestamp.isBit2_createTimePresent()) { + final FileTime creationTime = extendedTimestamp.getCreateFileTime(); + if (creationTime != null) { + super.setCreationTime(creationTime); + } + } + } + } + + /** + * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} parses NTFS + * timestamps with a maximum precision of microseconds, which is lower than the 100ns precision + * provided by this extra field. + */ + private void updateTimeFromNtfsField() { + final ZipExtraField extraField = getExtraField(X000A_NTFS.HEADER_ID); + if (extraField instanceof X000A_NTFS) { + final X000A_NTFS ntfsTimestamp = (X000A_NTFS) extraField; + final FileTime modifyTime = ntfsTimestamp.getModifyFileTime(); + if (modifyTime != null) { + internalSetLastModifiedTime(modifyTime); + } + final FileTime accessTime = ntfsTimestamp.getAccessFileTime(); + if (accessTime != null) { + super.setLastAccessTime(accessTime); + } + final FileTime creationTime = ntfsTimestamp.getCreateFileTime(); + if (creationTime != null) { + super.setCreationTime(creationTime); + } + } + } } diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java index 12f46ea2..28a6354b 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java @@ -102,17 +102,6 @@ public abstract class ZipUtil { */ private static final long UPPER_DOSTIME_BOUND = 128L * 365 * 24 * 60 * 60 * 1000; - /** - * Tests whether a given time (in milliseconds since Epoch) can be safely represented as DOS time - * - * @param time time in milliseconds since epoch - * @return true if the time can be safely represented as DOS time, false otherwise - * @since 1.23 - */ - public static boolean isDosTime(final long time) { - return time <= UPPER_DOSTIME_BOUND && javaToDosTime(time) != DOSTIME_BEFORE_1980; - } - /** * Assumes a negative integer really is a positive integer that * has wrapped around and re-creates the original value. @@ -170,7 +159,6 @@ public abstract class ZipUtil { } } - /** * Create a copy of the given array - or return null if the * argument is null. @@ -182,22 +170,13 @@ public abstract class ZipUtil { return null; } + static void copy(final byte[] from, final byte[] to, final int offset) { if (from != null) { System.arraycopy(from, 0, to, offset, from.length); } } - /** - * Converts DOS time to Java time (number of milliseconds since - * epoch). - * @param dosTime time to convert - * @return converted time - */ - public static long dosToJavaTime(final long dosTime) { - return dosToJavaDate(dosTime).getTime(); - } - private static Date dosToJavaDate(final long dosTime) { final Calendar cal = Calendar.getInstance(); // CheckStyle:MagicNumberCheck OFF - no point @@ -212,6 +191,16 @@ public abstract class ZipUtil { return cal.getTime(); } + /** + * Converts DOS time to Java time (number of milliseconds since + * epoch). + * @param dosTime time to convert + * @return converted time + */ + public static long dosToJavaTime(final long dosTime) { + return dosToJavaDate(dosTime).getTime(); + } + /** * Convert a DOS date/time field to a Date object. * @@ -252,6 +241,36 @@ public abstract class ZipUtil { return null; } + /** + * Tests whether a given time (in milliseconds since Epoch) can be safely represented as DOS time + * + * @param time time in milliseconds since epoch + * @return true if the time can be safely represented as DOS time, false otherwise + * @since 1.23 + */ + public static boolean isDosTime(final long time) { + return time <= UPPER_DOSTIME_BOUND && javaToDosTime(time) != DOSTIME_BEFORE_1980; + } + + private static LocalDateTime javaEpochToLocalDateTime(final long time) { + final Instant instant = Instant.ofEpochMilli(time); + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + } + + // version with integer overflow fixed - see https://bugs.openjdk.org/browse/JDK-8130914 + private static long javaToDosTime(final long t) { + final LocalDateTime ldt = javaEpochToLocalDateTime(t); + if (ldt.getYear() < 1980) { + return DOSTIME_BEFORE_1980; + } + return ((ldt.getYear() - 1980) << 25 + | ldt.getMonthValue() << 21 + | ldt.getDayOfMonth() << 16 + | ldt.getHour() << 11 + | ldt.getMinute() << 5 + | ldt.getSecond() >> 1) & 0xffffffffL; + } + /** * <p> * Converts a long into a BigInteger. Negative numbers between -1 and @@ -367,25 +386,6 @@ public abstract class ZipUtil { || entry.getMethod() == ZipMethod.BZIP2.getCode(); } - // version with integer overflow fixed - see https://bugs.openjdk.org/browse/JDK-8130914 - private static long javaToDosTime(final long t) { - final LocalDateTime ldt = javaEpochToLocalDateTime(t); - if (ldt.getYear() < 1980) { - return DOSTIME_BEFORE_1980; - } - return ((ldt.getYear() - 1980) << 25 - | ldt.getMonthValue() << 21 - | ldt.getDayOfMonth() << 16 - | ldt.getHour() << 11 - | ldt.getMinute() << 5 - | ldt.getSecond() >> 1) & 0xffffffffL; - } - - private static LocalDateTime javaEpochToLocalDateTime(final long time) { - final Instant instant = Instant.ofEpochMilli(time); - return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); - } - /** * Convert a Date object to a DOS date/time field. diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java index a64e8734..a999f39f 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java @@ -337,46 +337,6 @@ public class ZipArchiveEntryTest { assertNotEquals(entry2, entry3); } - @Test - public void testUnixMode() { - ZipArchiveEntry ze = new ZipArchiveEntry("foo"); - assertEquals(0, ze.getPlatform()); - ze.setUnixMode(0755); - assertEquals(3, ze.getPlatform()); - assertEquals(0755, - (ze.getExternalAttributes() >> 16) & 0xFFFF); - assertEquals(0, ze.getExternalAttributes() & 0xFFFF); - - ze.setUnixMode(0444); - assertEquals(3, ze.getPlatform()); - assertEquals(0444, - (ze.getExternalAttributes() >> 16) & 0xFFFF); - assertEquals(1, ze.getExternalAttributes() & 0xFFFF); - - ze = new ZipArchiveEntry("foo/"); - assertEquals(0, ze.getPlatform()); - ze.setUnixMode(0777); - assertEquals(3, ze.getPlatform()); - assertEquals(0777, - (ze.getExternalAttributes() >> 16) & 0xFFFF); - assertEquals(0x10, ze.getExternalAttributes() & 0xFFFF); - - ze.setUnixMode(0577); - assertEquals(3, ze.getPlatform()); - assertEquals(0577, - (ze.getExternalAttributes() >> 16) & 0xFFFF); - assertEquals(0x11, ze.getExternalAttributes() & 0xFFFF); - } - - @Test - public void testZipArchiveClone() throws Exception { - try (ZipFile zf = new ZipFile(getFile("COMPRESS-479.zip"))) { - final ZipArchiveEntry ze = zf.getEntry("%U20AC_for_Dollar.txt"); - final ZipArchiveEntry clonedZe = (ZipArchiveEntry) ze.clone(); - assertEquals(ze, clonedZe); - } - } - @Test public void testShouldNotSetExtraDateFieldsIfDateFitsInDosDates() { final ZipArchiveEntry ze = new ZipArchiveEntry(); @@ -393,23 +353,23 @@ public class ZipArchiveEntryTest { } @Test - public void testShouldSetExtraDateFieldsIfDateExceedsDosDate() { + public void testShouldNotSetInfoZipFieldIfAnyDatesExceedUnixTime() { final ZipArchiveEntry ze = new ZipArchiveEntry(); - final FileTime time = FileTime.from(ZipUtilTest.toLocalInstant("1975-11-27T00:00:00")); - ze.setTime(time.toMillis()); + final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z")); + final FileTime creationTime = FileTime.from(Instant.parse("2038-12-28T20:39:33.1234567Z")); + final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli(); + ze.setTime(time); + ze.setLastAccessTime(accessTime); + ze.setCreationTime(creationTime); - assertEquals(time.toMillis(), ze.getTime()); - assertEquals(time, ze.getLastModifiedTime()); - final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); - assertNotNull(extendedTimestamp); - assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue()); - assertNull(extendedTimestamp.getAccessTime()); - assertNull(extendedTimestamp.getCreateTime()); + assertEquals(time, ze.getTime()); + assertEquals(time, ze.getLastModifiedTime().toMillis()); + assertNull(ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID)); final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); assertNotNull(ntfs); assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); - assertEquals(0L, ntfs.getAccessTime().getLongValue()); - assertEquals(0L, ntfs.getCreateTime().getLongValue()); + assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue()); + assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue()); } @Test @@ -428,26 +388,6 @@ public class ZipArchiveEntryTest { assertEquals(0L, ntfs.getCreateTime().getLongValue()); } - @Test - public void testShouldSetExtraDateFieldsIfModifyDateIsExplicitlySet() { - final ZipArchiveEntry ze = new ZipArchiveEntry(); - final FileTime time = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z")); - ze.setLastModifiedTime(time); - - assertEquals(time.toMillis(), ze.getTime()); - assertEquals(time, ze.getLastModifiedTime()); - final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); - assertNotNull(extendedTimestamp); - assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue()); - assertNull(extendedTimestamp.getAccessTime()); - assertNull(extendedTimestamp.getCreateTime()); - final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); - assertNotNull(ntfs); - assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); - assertEquals(0L, ntfs.getAccessTime().getLongValue()); - assertEquals(0L, ntfs.getCreateTime().getLongValue()); - } - @Test public void testShouldSetExtraDateFieldsIfAccessDateIsSet() { final ZipArchiveEntry ze = new ZipArchiveEntry(); @@ -470,66 +410,126 @@ public class ZipArchiveEntryTest { } @Test - public void testShouldSetExtraDateFieldsIfCreationDateIsSet() { + public void testShouldSetExtraDateFieldsIfAllDatesAreSet() { final ZipArchiveEntry ze = new ZipArchiveEntry(); + final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z")); final FileTime creationTime = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z")); final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli(); ze.setTime(time); + ze.setLastAccessTime(accessTime); ze.setCreationTime(creationTime); assertEquals(time, ze.getTime()); assertEquals(time, ze.getLastModifiedTime().toMillis()); final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); assertNotNull(extendedTimestamp); - assertNull(extendedTimestamp.getAccessTime()); + assertEquals(TimeUtils.toUnixTime(accessTime), extendedTimestamp.getAccessTime().getValue()); assertEquals(TimeUtils.toUnixTime(creationTime), extendedTimestamp.getCreateTime().getValue()); final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); assertNotNull(ntfs); assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); - assertEquals(0L, ntfs.getAccessTime().getLongValue()); + assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue()); assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue()); } @Test - public void testShouldSetExtraDateFieldsIfAllDatesAreSet() { + public void testShouldSetExtraDateFieldsIfCreationDateIsSet() { final ZipArchiveEntry ze = new ZipArchiveEntry(); - final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z")); final FileTime creationTime = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z")); final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli(); ze.setTime(time); - ze.setLastAccessTime(accessTime); ze.setCreationTime(creationTime); assertEquals(time, ze.getTime()); assertEquals(time, ze.getLastModifiedTime().toMillis()); final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); assertNotNull(extendedTimestamp); - assertEquals(TimeUtils.toUnixTime(accessTime), extendedTimestamp.getAccessTime().getValue()); + assertNull(extendedTimestamp.getAccessTime()); assertEquals(TimeUtils.toUnixTime(creationTime), extendedTimestamp.getCreateTime().getValue()); final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); assertNotNull(ntfs); assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); - assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue()); + assertEquals(0L, ntfs.getAccessTime().getLongValue()); assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue()); } @Test - public void testShouldNotSetInfoZipFieldIfAnyDatesExceedUnixTime() { + public void testShouldSetExtraDateFieldsIfDateExceedsDosDate() { final ZipArchiveEntry ze = new ZipArchiveEntry(); - final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z")); - final FileTime creationTime = FileTime.from(Instant.parse("2038-12-28T20:39:33.1234567Z")); - final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli(); - ze.setTime(time); - ze.setLastAccessTime(accessTime); - ze.setCreationTime(creationTime); + final FileTime time = FileTime.from(ZipUtilTest.toLocalInstant("1975-11-27T00:00:00")); + ze.setTime(time.toMillis()); - assertEquals(time, ze.getTime()); - assertEquals(time, ze.getLastModifiedTime().toMillis()); - assertNull(ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID)); + assertEquals(time.toMillis(), ze.getTime()); + assertEquals(time, ze.getLastModifiedTime()); + final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); + assertNotNull(extendedTimestamp); + assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue()); + assertNull(extendedTimestamp.getAccessTime()); + assertNull(extendedTimestamp.getCreateTime()); final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); assertNotNull(ntfs); assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); - assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue()); - assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue()); + assertEquals(0L, ntfs.getAccessTime().getLongValue()); + assertEquals(0L, ntfs.getCreateTime().getLongValue()); + } + + @Test + public void testShouldSetExtraDateFieldsIfModifyDateIsExplicitlySet() { + final ZipArchiveEntry ze = new ZipArchiveEntry(); + final FileTime time = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z")); + ze.setLastModifiedTime(time); + + assertEquals(time.toMillis(), ze.getTime()); + assertEquals(time, ze.getLastModifiedTime()); + final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID); + assertNotNull(extendedTimestamp); + assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue()); + assertNull(extendedTimestamp.getAccessTime()); + assertNull(extendedTimestamp.getCreateTime()); + final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID); + assertNotNull(ntfs); + assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue()); + assertEquals(0L, ntfs.getAccessTime().getLongValue()); + assertEquals(0L, ntfs.getCreateTime().getLongValue()); + } + + @Test + public void testUnixMode() { + ZipArchiveEntry ze = new ZipArchiveEntry("foo"); + assertEquals(0, ze.getPlatform()); + ze.setUnixMode(0755); + assertEquals(3, ze.getPlatform()); + assertEquals(0755, + (ze.getExternalAttributes() >> 16) & 0xFFFF); + assertEquals(0, ze.getExternalAttributes() & 0xFFFF); + + ze.setUnixMode(0444); + assertEquals(3, ze.getPlatform()); + assertEquals(0444, + (ze.getExternalAttributes() >> 16) & 0xFFFF); + assertEquals(1, ze.getExternalAttributes() & 0xFFFF); + + ze = new ZipArchiveEntry("foo/"); + assertEquals(0, ze.getPlatform()); + ze.setUnixMode(0777); + assertEquals(3, ze.getPlatform()); + assertEquals(0777, + (ze.getExternalAttributes() >> 16) & 0xFFFF); + assertEquals(0x10, ze.getExternalAttributes() & 0xFFFF); + + ze.setUnixMode(0577); + assertEquals(3, ze.getPlatform()); + assertEquals(0577, + (ze.getExternalAttributes() >> 16) & 0xFFFF); + assertEquals(0x11, ze.getExternalAttributes() & 0xFFFF); + } + + @Test + public void testZipArchiveClone() throws Exception { + try (ZipFile zf = new ZipFile(getFile("COMPRESS-479.zip"))) { + final ZipArchiveEntry ze = zf.getEntry("%U20AC_for_Dollar.txt"); + final ZipArchiveEntry clonedZe = (ZipArchiveEntry) ze.clone(); + assertEquals(ze, clonedZe); + } } } diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java index f0cc3dd2..eaed76e6 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java @@ -37,7 +37,28 @@ import org.junit.jupiter.api.Test; public class ZipUtilTest { + static void assertDosDate( + final long value, + final int year, + final int month, + final int day, + final int hour, + final int minute, + final int second) { + int pos = 0; + assertEquals((year - 1980), ((int) (value << pos)) >>> (32 - 7)); + assertEquals(month, ((int) (value << (pos += 7))) >>> (32 - 4)); + assertEquals(day, ((int) (value << (pos += 4))) >>> (32 - 5)); + assertEquals(hour, ((int) (value << (pos += 5))) >>> (32 - 5)); + assertEquals(minute, ((int) (value << (pos += 5))) >>> (32 - 6)); + assertEquals(second, ((int) (value << (pos + 6))) >>> (32 - 5) << 1); // DOS dates only store even seconds + } + static Instant toLocalInstant(final String date) { + return LocalDateTime.parse(date).atZone(ZoneId.systemDefault()).toInstant(); + } + private Date time; + private ZipLong zl; @BeforeEach @@ -122,6 +143,12 @@ public class ZipUtilTest { assertEquals(65, b1[2]); assertEquals(10, b1[3]); } + @Test + public void testInsideCalendar_bigValue(){ + final long date = toLocalInstant("2097-11-27T23:59:59").toEpochMilli(); + final long value = ZipLong.getValue(ZipUtil.toDosTime(date)); + assertDosDate(value, 2097, 11, 27, 23, 59, 58); // DOS dates only store even seconds + } @Test public void testInsideCalendar_long(){ @@ -136,11 +163,13 @@ public class ZipUtilTest { final long value = ZipLong.getValue(ZipUtil.toDosTime(date)); assertDosDate(value, 2022, 12, 27, 16, 18, 22); // DOS dates only store even seconds } + @Test - public void testInsideCalendar_bigValue(){ - final long date = toLocalInstant("2097-11-27T23:59:59").toEpochMilli(); - final long value = ZipLong.getValue(ZipUtil.toDosTime(date)); - assertDosDate(value, 2097, 11, 27, 23, 59, 58); // DOS dates only store even seconds + public void testIsDosTime(){ + assertFalse(ZipUtil.isDosTime(toLocalInstant("1975-01-31T23:00:00").toEpochMilli())); + assertTrue(ZipUtil.isDosTime(toLocalInstant("1980-01-03T00:00:00").toEpochMilli())); + assertTrue(ZipUtil.isDosTime(toLocalInstant("2097-11-27T00:00:00").toEpochMilli())); + assertFalse(ZipUtil.isDosTime(toLocalInstant("2099-01-01T00:00:00").toEpochMilli())); } @Test @@ -194,35 +223,6 @@ public class ZipUtilTest { assertDosDate(value, 1980, 1, 1, 0, 0, 0); } - @Test - public void testIsDosTime(){ - assertFalse(ZipUtil.isDosTime(toLocalInstant("1975-01-31T23:00:00").toEpochMilli())); - assertTrue(ZipUtil.isDosTime(toLocalInstant("1980-01-03T00:00:00").toEpochMilli())); - assertTrue(ZipUtil.isDosTime(toLocalInstant("2097-11-27T00:00:00").toEpochMilli())); - assertFalse(ZipUtil.isDosTime(toLocalInstant("2099-01-01T00:00:00").toEpochMilli())); - } - - static void assertDosDate( - final long value, - final int year, - final int month, - final int day, - final int hour, - final int minute, - final int second) { - int pos = 0; - assertEquals((year - 1980), ((int) (value << pos)) >>> (32 - 7)); - assertEquals(month, ((int) (value << (pos += 7))) >>> (32 - 4)); - assertEquals(day, ((int) (value << (pos += 4))) >>> (32 - 5)); - assertEquals(hour, ((int) (value << (pos += 5))) >>> (32 - 5)); - assertEquals(minute, ((int) (value << (pos += 5))) >>> (32 - 6)); - assertEquals(second, ((int) (value << (pos + 6))) >>> (32 - 5) << 1); // DOS dates only store even seconds - } - - static Instant toLocalInstant(final String date) { - return LocalDateTime.parse(date).atZone(ZoneId.systemDefault()).toInstant(); - } - @Test public void testReverse() { final byte[][] bTest = new byte[6][]; diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java index 3c003fa5..1187dc82 100755 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java @@ -49,8 +49,17 @@ import org.junit.jupiter.params.provider.MethodSource; public class ArchiveTest { + static Stream<Arguments> loadMultipleJars() throws URISyntaxException, IOException { + return Files.list(Paths.get(Archive.class.getResource("/pack200/jars").toURI())) + .filter(child -> { + final String fileName = child.getFileName().toString(); + return fileName.endsWith(".jar") && !fileName.endsWith("Unpacked.jar"); + }) + .map(Arguments::of); + } JarFile in; OutputStream out; + File file; private void compareFiles(final JarFile jarFile, final JarFile jarFile2) @@ -294,15 +303,6 @@ public class ArchiveTest { compareFiles(jarFile, jarFile2); } - static Stream<Arguments> loadMultipleJars() throws URISyntaxException, IOException { - return Files.list(Paths.get(Archive.class.getResource("/pack200/jars").toURI())) - .filter(child -> { - final String fileName = child.getFileName().toString(); - return fileName.endsWith(".jar") && !fileName.endsWith("Unpacked.jar"); - }) - .map(Arguments::of); - } - @ParameterizedTest @MethodSource("loadMultipleJars") public void testMultipleJars(final Path path) throws URISyntaxException, IOException, Pack200Exception { diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java index 71d1ff5d..42a57db2 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java @@ -39,6 +39,10 @@ import org.junit.jupiter.params.provider.MethodSource; */ public class BHSDCodecTest { + static Stream<Arguments> encodeDecodeRange() { + return IntStream.range(1, 116).mapToObj(Arguments::of); + } + @Test public void testDeltaEncodings() throws IOException, Pack200Exception { final Codec c = Codec.UDELTA5; @@ -50,10 +54,6 @@ public class BHSDCodecTest { } } - static Stream<Arguments> encodeDecodeRange() { - return IntStream.range(1, 116).mapToObj(Arguments::of); - } - @ParameterizedTest @MethodSource("encodeDecodeRange") public void testEncodeDecode(final int i) throws IOException, Pack200Exception { diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java index d3ebe43c..ea2ba4ab 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java @@ -49,18 +49,6 @@ public class CodecEncodingTest { ); } - @ParameterizedTest - @MethodSource("arbitraryCodec") - public void testArbitraryCodec(final String expected, final byte[] bytes) throws IOException, Pack200Exception { - assertEquals(expected, CodecEncoding.getCodec(116, new ByteArrayInputStream(bytes), null).toString()); - } - - @Test - public void testDefaultCodec() throws Pack200Exception, IOException { - final Codec defaultCodec = new BHSDCodec(2, 16, 0, 0); - assertEquals(defaultCodec, CodecEncoding.getCodec(0, null, defaultCodec)); - } - // These are the canonical encodings specified by the Pack200 spec static Stream<Arguments> canonicalEncodings() { return Stream.of( @@ -182,12 +170,45 @@ public class CodecEncodingTest { ); } + // Test canonical codecs + static Stream<Arguments> canonicalGetSpecifier() { + return IntStream.range(1, 115).mapToObj(Arguments::of); + } + + static Stream<Arguments> specifier() { + return Stream.of( + Arguments.of(new BHSDCodec(2, 125, 0, 1)), + Arguments.of(new BHSDCodec(3, 125, 2, 1)), + Arguments.of(new BHSDCodec(4, 125)), + Arguments.of(new BHSDCodec(5, 125, 2, 0)), + Arguments.of(new BHSDCodec(3, 5, 2, 1)) + ); + } + + @ParameterizedTest + @MethodSource("arbitraryCodec") + public void testArbitraryCodec(final String expected, final byte[] bytes) throws IOException, Pack200Exception { + assertEquals(expected, CodecEncoding.getCodec(116, new ByteArrayInputStream(bytes), null).toString()); + } + @ParameterizedTest @MethodSource("canonicalEncodings") void testCanonicalEncodings(final int i, final String expectedCodec) throws IOException, Pack200Exception { assertEquals(expectedCodec, CodecEncoding.getCodec(i, null, null).toString()); } + @ParameterizedTest + @MethodSource("canonicalGetSpecifier") + public void testCanonicalGetSpecifier(final int i) throws Pack200Exception, IOException { + assertEquals(i, CodecEncoding.getSpecifier(CodecEncoding.getCodec(i, null, null), null)[0]); + } + + @Test + public void testDefaultCodec() throws Pack200Exception, IOException { + final Codec defaultCodec = new BHSDCodec(2, 16, 0, 0); + assertEquals(defaultCodec, CodecEncoding.getCodec(0, null, defaultCodec)); + } + @Test public void testGetSpeciferForPopulationCodec() throws IOException, Pack200Exception { final PopulationCodec pCodec = new PopulationCodec(Codec.BYTE1, Codec.CHAR3, Codec.UNSIGNED5); @@ -275,27 +296,6 @@ public class CodecEncodingTest { assertEquals(bCodec.getBCodec(), bCodec2.getBCodec()); } - // Test canonical codecs - static Stream<Arguments> canonicalGetSpecifier() { - return IntStream.range(1, 115).mapToObj(Arguments::of); - } - - @ParameterizedTest - @MethodSource("canonicalGetSpecifier") - public void testCanonicalGetSpecifier(final int i) throws Pack200Exception, IOException { - assertEquals(i, CodecEncoding.getSpecifier(CodecEncoding.getCodec(i, null, null), null)[0]); - } - - static Stream<Arguments> specifier() { - return Stream.of( - Arguments.of(new BHSDCodec(2, 125, 0, 1)), - Arguments.of(new BHSDCodec(3, 125, 2, 1)), - Arguments.of(new BHSDCodec(4, 125)), - Arguments.of(new BHSDCodec(5, 125, 2, 0)), - Arguments.of(new BHSDCodec(3, 5, 2, 1)) - ); - } - @ParameterizedTest @MethodSource("specifier") void testGetSpecifier(final Codec c1) throws IOException, Pack200Exception { diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java index bdb06288..eb1d6f3d 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java @@ -43,6 +43,38 @@ import org.junit.jupiter.params.provider.MethodSource; */ public class CodecTest { + static Stream<Arguments> bCodings(){ + return IntStream.rangeClosed(1, 5).mapToObj(Arguments::of); + } + + static Stream<Arguments> codecFamily() { + return Stream.of( + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs1), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs2), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs3), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs4), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs5), + Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs1), + Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs2), + Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs3), + Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs4), + Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs5), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs1), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs2), + Arguments.of((Object) CanonicalCodecFamilies.nonDeltaDoubleSignedCodecs1), + Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs1), + Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs2), + Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs3), + Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs4), + Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs5), + Arguments.of((Object) CanonicalCodecFamilies.deltaDoubleSignedCodecs1) + ); + } + + static Stream<Arguments> hCodings() { + return IntStream.range(0, 256).mapToObj(Arguments::of); + } + private long decode(final Codec codec, final byte[] data, final long value, final long last) throws IOException, Pack200Exception { final ByteArrayInputStream in = new ByteArrayInputStream(data); @@ -56,6 +88,16 @@ public class CodecTest { assertThrowsExactly(EOFException.class, () -> decode(codec, data, 0, 0), "Should have detected an EOFException"); } + @ParameterizedTest + @MethodSource("bCodings") + public void testBCodings(final int i) { + if (i == 5) { + assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(i, 256)); + } else { + assertDoesNotThrow(() -> new BHSDCodec(i, 256)); + } + } + @Test public void testByte1() throws Exception { for (int i = 0; i < 255; i++) { @@ -154,30 +196,6 @@ public class CodecTest { assertFalse(byte2s.encodes(256)); } - static Stream<Arguments> codecFamily() { - return Stream.of( - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs1), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs2), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs3), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs4), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs5), - Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs1), - Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs2), - Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs3), - Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs4), - Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs5), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs1), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs2), - Arguments.of((Object) CanonicalCodecFamilies.nonDeltaDoubleSignedCodecs1), - Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs1), - Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs2), - Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs3), - Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs4), - Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs5), - Arguments.of((Object) CanonicalCodecFamilies.deltaDoubleSignedCodecs1) - ); - } - @ParameterizedTest @MethodSource("codecFamily") public void testCodecFamilies(final BHSDCodec[] family) { @@ -206,30 +224,12 @@ public class CodecTest { assertEquals("(5,64,2,1)", Codec.MDELTA5.toString()); } - static Stream<Arguments> hCodings() { - return IntStream.range(0, 256).mapToObj(Arguments::of); - } - @ParameterizedTest @MethodSource("hCodings") public void testInvalidHCodings(final int i) { assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(1, i), "b=1 -> h=256"); } - static Stream<Arguments> bCodings(){ - return IntStream.rangeClosed(1, 5).mapToObj(Arguments::of); - } - - @ParameterizedTest - @MethodSource("bCodings") - public void testBCodings(final int i) { - if (i == 5) { - assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(i, 256)); - } else { - assertDoesNotThrow(() -> new BHSDCodec(i, 256)); - } - } - @Test public void testUnsigned5() throws Exception { decode(Codec.UNSIGNED5, new byte[] { 1 }, 1, 0); diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java index d3edd889..1a0d65f8 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java @@ -34,14 +34,6 @@ import org.junit.jupiter.params.provider.MethodSource; public class PopulationCodecTest { - @Test - public void testEncodeSingleValue() { - assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5), - "Should not allow a single value to be encoded as we don't know which codec to use"); - assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8), - "Should not allow a single value to be encoded as we don't know which codec to use"); - } - static Stream<Arguments> populationCodec() { return Stream.of( Arguments.of(new byte[] { 4, 5, 6, 4, 2, 1, 3, 0, 7 }, new long[] { 5, 4, 6, 7 }, Codec.BYTE1), @@ -60,6 +52,14 @@ public class PopulationCodecTest { ); } + @Test + public void testEncodeSingleValue() { + assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5), + "Should not allow a single value to be encoded as we don't know which codec to use"); + assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8), + "Should not allow a single value to be encoded as we don't know which codec to use"); + } + @ParameterizedTest @MethodSource("populationCodec") public void testPopulationCodec(final byte[] data, final long[] expectedResult, final Codec codec) throws IOException, Pack200Exception { diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java index da37b2fb..504f79fd 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java @@ -36,6 +36,15 @@ import org.junit.jupiter.params.provider.MethodSource; */ public class RunCodecTest { + static Stream<Arguments> runCodec() { + return Stream.of( + Arguments.of(0, Codec.SIGNED5, Codec.UDELTA5, "Should not allow a k value of 0"), + Arguments.of(10, null, Codec.UDELTA5, "Should not allow a null codec"), + Arguments.of(10, Codec.UDELTA5, null, "Should not allow a null codec"), + Arguments.of(10, null, null, "Should not allow a null codec") + ); + } + @Test public void testDecode() throws Exception { RunCodec runCodec = new RunCodec(1, Codec.UNSIGNED5, Codec.BYTE1); @@ -131,15 +140,6 @@ public class RunCodecTest { } } - static Stream<Arguments> runCodec() { - return Stream.of( - Arguments.of(0, Codec.SIGNED5, Codec.UDELTA5, "Should not allow a k value of 0"), - Arguments.of(10, null, Codec.UDELTA5, "Should not allow a null codec"), - Arguments.of(10, Codec.UDELTA5, null, "Should not allow a null codec"), - Arguments.of(10, null, null, "Should not allow a null codec") - ); - } - @ParameterizedTest @MethodSource("runCodec") public void testRunCodec(final int k, final Codec aCodec, final Codec bCodec, final String failureMessage) { diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java index e2b4d05c..72a66512 100644 --- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java @@ -84,10 +84,15 @@ public class AttributeLayoutTest { ); } - @ParameterizedTest - @MethodSource("badData") - public void testBadData(final String name, final int context, final String layout) { - assertThrows(Pack200Exception.class, () -> new AttributeLayout(name, context, layout, -1)); + static Stream<Arguments> codec() { + return Stream.of( + Arguments.of("O", AttributeLayout.CONTEXT_CLASS, "HOBS", Codec.BRANCH5), + Arguments.of("P", AttributeLayout.CONTEXT_METHOD, "PIN", Codec.BCI5), + Arguments.of("S", AttributeLayout.CONTEXT_FIELD, "HS", Codec.SIGNED5), + Arguments.of("RS", AttributeLayout.CONTEXT_CODE, "RRRS", Codec.UNSIGNED5), + Arguments.of("KS", AttributeLayout.CONTEXT_CLASS, "RKS", Codec.UNSIGNED5), + Arguments.of("B", AttributeLayout.CONTEXT_CLASS, "TRKSB", Codec.BYTE1) + ); } static Stream<Arguments> okData() { @@ -100,20 +105,9 @@ public class AttributeLayoutTest { } @ParameterizedTest - @MethodSource("okData") - public void testOkData(final String name, final int context, final String layout) { - assertDoesNotThrow(() -> new AttributeLayout(name, context, layout, -1)); - } - - static Stream<Arguments> codec() { - return Stream.of( - Arguments.of("O", AttributeLayout.CONTEXT_CLASS, "HOBS", Codec.BRANCH5), - Arguments.of("P", AttributeLayout.CONTEXT_METHOD, "PIN", Codec.BCI5), - Arguments.of("S", AttributeLayout.CONTEXT_FIELD, "HS", Codec.SIGNED5), - Arguments.of("RS", AttributeLayout.CONTEXT_CODE, "RRRS", Codec.UNSIGNED5), - Arguments.of("KS", AttributeLayout.CONTEXT_CLASS, "RKS", Codec.UNSIGNED5), - Arguments.of("B", AttributeLayout.CONTEXT_CLASS, "TRKSB", Codec.BYTE1) - ); + @MethodSource("badData") + public void testBadData(final String name, final int context, final String layout) { + assertThrows(Pack200Exception.class, () -> new AttributeLayout(name, context, layout, -1)); } @ParameterizedTest @@ -162,4 +156,10 @@ public class AttributeLayoutTest { assertEquals("Zero", ((CPUTF8)layout.getValue(1, segment.getConstantPool())).underlyingString()); assertEquals("One", ((CPUTF8)layout.getValue(2, segment.getConstantPool())).underlyingString()); } + + @ParameterizedTest + @MethodSource("okData") + public void testOkData(final String name, final int context, final String layout) { + assertDoesNotThrow(() -> new AttributeLayout(name, context, layout, -1)); + } } diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java index cd63c2fd..bb7547fc 100644 --- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java @@ -36,6 +36,15 @@ public class ICTupleTest { ); } + static Stream<Arguments> predicted() { + return Stream.of( + Arguments.of("orw/SimpleHelloWorld$SimpleHelloWorldInner", "SimpleHelloWorldInner", "orw/SimpleHelloWorld"), + Arguments.of("java/util/AbstractList$2$Local", "Local", "java/util/AbstractList$2"), + Arguments.of("java/util/AbstractList#2#Local", "Local", "java/util/AbstractList$2"), + Arguments.of("java/util/AbstractList$1", "1", "java/util/AbstractList") + ); + } + @ParameterizedTest @MethodSource("explicit") public void testExplicitClassTupleParsing(final String c, final String c2, final String n, final String expectedSimpleClassName, final String expectedOuterClass) { @@ -46,15 +55,6 @@ public class ICTupleTest { ); } - static Stream<Arguments> predicted() { - return Stream.of( - Arguments.of("orw/SimpleHelloWorld$SimpleHelloWorldInner", "SimpleHelloWorldInner", "orw/SimpleHelloWorld"), - Arguments.of("java/util/AbstractList$2$Local", "Local", "java/util/AbstractList$2"), - Arguments.of("java/util/AbstractList#2#Local", "Local", "java/util/AbstractList$2"), - Arguments.of("java/util/AbstractList$1", "1", "java/util/AbstractList") - ); - } - @ParameterizedTest @MethodSource("predicted") public void testPredictedClassTupleParsing(final String c, final String expectedSimpleClass, final String expectedOuterClass) { diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java index 1eeca2ab..1eecb6d2 100644 --- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java @@ -60,12 +60,6 @@ public class SegmentUtilsTest { ); } - @ParameterizedTest - @MethodSource("countArgs") - public void testCountArgs(final String descriptor, final int expectedArgsCount) { - assertEquals(expectedArgsCount, SegmentUtils.countArgs(descriptor)); - } - static Stream<Arguments> countInvokeInterfaceArgs() { return Stream.of( Arguments.of("(Z)V", 1), @@ -80,6 +74,12 @@ public class SegmentUtilsTest { ); } + @ParameterizedTest + @MethodSource("countArgs") + public void testCountArgs(final String descriptor, final int expectedArgsCount) { + assertEquals(expectedArgsCount, SegmentUtils.countArgs(descriptor)); + } + @ParameterizedTest @MethodSource("countInvokeInterfaceArgs") public void testCountInvokeInterfaceArgs(final String descriptor, final int expectedCountInvokeInterfaceArgs) { diff --git a/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java b/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java index 9aff262f..1c7de4da 100644 --- a/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java +++ b/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java @@ -80,6 +80,14 @@ public class TimeUtilsTest { ); } + public static Stream<Arguments> fileTimeToUnixTimeArguments() { + return Stream.of( + Arguments.of(0L, "1970-01-01T00:00:00Z"), + Arguments.of(1672141989L, "2022-12-27T11:53:09Z"), + Arguments.of(Integer.MAX_VALUE, "2038-01-19T03:14:07Z") + ); + } + public static Stream<Arguments> truncateFileTimeProvider() { return Stream.of( Arguments.of( @@ -117,6 +125,17 @@ public class TimeUtilsTest { ); } + @Test + public void shouldCheckWhetherTimeCanBeRepresentedAsUnixTime() { + assertTrue(TimeUtils.isUnixTime(null)); + assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2022-12-27T12:45:22Z")))); + assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:07Z")))); + assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T23:14:08Z")))); + assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T03:14:08Z")))); + assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:08Z")))); + assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2099-06-30T12:31:42Z")))); + } + @ParameterizedTest @MethodSource("dateToNtfsProvider") public void shouldConvertDateToFileTime(final String instant, final long ignored) { @@ -153,6 +172,12 @@ public class TimeUtilsTest { assertEquals(ntfsTime, toNtfsTime(parsed)); } + @ParameterizedTest + @MethodSource("fileTimeToUnixTimeArguments") + public void shouldConvertFileTimeToUnixTime(final long expectedUnixTime, final String instant) { + assertEquals(expectedUnixTime, TimeUtils.toUnixTime(FileTime.from(Instant.parse(instant)))); + } + @ParameterizedTest @MethodSource("dateToNtfsProvider") public void shouldConvertNtfsTimeToDate(final String instant, final long ntfsTime) { @@ -179,6 +204,12 @@ public class TimeUtilsTest { assertNull(toDate(null)); } + @ParameterizedTest + @MethodSource("fileTimeToUnixTimeArguments") + public void shouldConvertUnixTimeToFileTime(final long unixTime, final String expectedInstant) { + assertEquals(Instant.parse(expectedInstant), TimeUtils.unixTimeToFileTime(unixTime).toInstant()); + } + @ParameterizedTest @MethodSource("truncateFileTimeProvider") public void shouldTruncateFileTimeToHundredNanos(final String original, final String truncated) { @@ -186,35 +217,4 @@ public class TimeUtilsTest { final FileTime truncatedTime = FileTime.from(Instant.parse(truncated)); assertEquals(truncatedTime, TimeUtils.truncateToHundredNanos(originalTime)); } - - @Test - public void shouldCheckWhetherTimeCanBeRepresentedAsUnixTime() { - assertTrue(TimeUtils.isUnixTime(null)); - assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2022-12-27T12:45:22Z")))); - assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:07Z")))); - assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T23:14:08Z")))); - assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T03:14:08Z")))); - assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:08Z")))); - assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2099-06-30T12:31:42Z")))); - } - - public static Stream<Arguments> fileTimeToUnixTimeArguments() { - return Stream.of( - Arguments.of(0L, "1970-01-01T00:00:00Z"), - Arguments.of(1672141989L, "2022-12-27T11:53:09Z"), - Arguments.of(Integer.MAX_VALUE, "2038-01-19T03:14:07Z") - ); - } - - @ParameterizedTest - @MethodSource("fileTimeToUnixTimeArguments") - public void shouldConvertFileTimeToUnixTime(final long expectedUnixTime, final String instant) { - assertEquals(expectedUnixTime, TimeUtils.toUnixTime(FileTime.from(Instant.parse(instant)))); - } - - @ParameterizedTest - @MethodSource("fileTimeToUnixTimeArguments") - public void shouldConvertUnixTimeToFileTime(final long unixTime, final String expectedInstant) { - assertEquals(Instant.parse(expectedInstant), TimeUtils.unixTimeToFileTime(unixTime).toInstant()); - } }