[Git][java-team/plexus-archiver][master] 7 commits: Standards-Version updated to 4.1.4

Emmanuel Bourg gitlab at salsa.debian.org
Thu Jun 7 11:01:24 BST 2018


Emmanuel Bourg pushed to branch master at Debian Java Maintainers / plexus-archiver


Commits:
5c32e9ad by Emmanuel Bourg at 2018-06-07T11:29:16+02:00
Standards-Version updated to 4.1.4

- - - - -
51908fb8 by Emmanuel Bourg at 2018-06-07T11:33:38+02:00
New upstream version 3.6.0
- - - - -
fed452ac by Emmanuel Bourg at 2018-06-07T11:37:20+02:00
Switch to debhelper level 11

- - - - -
7f801c07 by Emmanuel Bourg at 2018-06-07T11:37:25+02:00
Use salsa.debian.org Vcs-* URLs

- - - - -
01f016d4 by Emmanuel Bourg at 2018-06-07T11:37:25+02:00
Removed Damien Raude-Morvan from the uploaders (Closes: #889426)

- - - - -
ee5ef6d5 by Emmanuel Bourg at 2018-06-07T11:37:25+02:00
Update upstream source from tag 'upstream/3.6.0'

Update to upstream version '3.6.0'
with Debian dir e6ed92d82d0c4590c314156f969c2a3907547d10

- - - - -
35f70760 by Emmanuel Bourg at 2018-06-07T11:50:48+02:00
New upstream release (3.6.0)
Fixes CVE-2018-1002200: Arbitrary file write vulnerability using a specially crafted zip file (Closes: #900953)

- - - - -


28 changed files:

- .travis.yml
- README.md
- ReleaseNotes.md
- debian/changelog
- debian/compat
- debian/control
- debian/rules
- pom.xml
- src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
- src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
- src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
- + src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java
- + src/main/java/org/codehaus/plexus/archiver/jar/ModularJarArchiver.java
- src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
- src/main/java/org/codehaus/plexus/archiver/zip/PlexusIoZipFileResourceCollection.java
- src/main/resources/META-INF/plexus/components.xml
- src/test/java/org/codehaus/plexus/archiver/BasePlexusArchiverTest.java
- + src/test/java/org/codehaus/plexus/archiver/jar/BaseJarArchiverTest.java
- src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
- + src/test/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiverTest.java
- src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java
- + src/test/resources/java-classes/com/example/app/Main.class
- + src/test/resources/java-classes/com/example/resources/test.properties
- + src/test/resources/java-module-descriptor/module-info.class
- + src/test/resources/java-src/REAMDE.md
- + src/test/resources/java-src/com/example/app/Main.java
- + src/test/resources/java-src/module-info.java
- + src/test/zips/zip-slip.zip


Changes:

=====================================
.travis.yml
=====================================
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,8 @@
 language: java
 jdk:
-  - oraclejdk7
+  - openjdk7
   - oraclejdk8
+  - oraclejdk9
 
 # No need for preliminary install step.
 install: true


=====================================
README.md
=====================================
--- a/README.md
+++ b/README.md
@@ -11,6 +11,8 @@ The current master is now at https://github.com/codehaus-plexus/plexus-archiver
 
 You can find details about the different releases in the [Release Notes](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md).
 
- * [Release 3.4](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#release-34).
- * [Release 3.3](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#release-33).
- * [Release 3.2](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#release-32).
+ * [Release 3.6.0](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#plexus-archiver-360).
+ * [Release 3.5](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#plexus-archiver-35).
+ * [Release 3.4](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#plexus-archiver-34).
+ * [Release 3.3](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#plexus-archiver-33).
+ * [Release 3.2](https://github.com/codehaus-plexus/plexus-archiver/blob/master/ReleaseNotes.md#plexus-archiver-32).


=====================================
ReleaseNotes.md
=====================================
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -4,375 +4,516 @@ Plexus Archiver and Plexus-IO combined release notes
 Since archiver depends on a given version of IO this list is cumulative,
 any version includes *all* changes below.
 
-## Release 3.4
+Plexus Archiver 3.6.0
+---------------------
 
- * [Fixed #45][issue-45]
-   Default 'ArchiveManager' does not support 'tar.xz' and 'tar.snappy' file extensions.
+Plexus Archiver 3.6.0 requires Java 7. 
 
- * [Fixed #46][issue-46]
-   'JarSecurityFileSelector' needs to support signature files ending in '.EC' or '.ec'.
+### Improvements
 
-## Release 3.3
+ * [Pull Request #87][pr-87] - of Levan Giguashvili (odinn1984)
+   Snyk eng team to fix a possible security issue.
+   (See https://gist.github.com/grnd/eafd7dab7c4cc6197d817a07fa46b2df)
 
- * [Fixed #43][issue-43]
-   Updated to stop failing creating 'Created-by' manifest entries, when the version
-   of the archiver cannot be determined.
 
- * [Fixed #42][issue-42]
-   No need to fallback to unicode path extra field policy NOT_ENCODEABLE.
+Plexus Archiver 3.5
+-------------------
 
- * [Fixed #40][issue-40]
-   Updated to upgrade 'plexus-utils' to latest patch release.
+Plexus Archiver 3.5 requires Java 7. Now Plexus Archiver uses pure Java
+implementations to deal with file attributes so the `useJvmChmod` is no
+longer used and it is just ignored. `Archiver#setUseJvmChmod`,
+`Archiver#isUseJvmChmod()`, `UnArchiver#setUseJvmChmod`,
+`UnArchiver#isUseJvmChmod()`,
+`ArchiveEntryUtils#chmod( File, int, Logger, boolean )` and
+`ArchiveEntryUtils#chmod( File, int, Logger )` are deprecated and are
+subject to removal in a future version.
 
- * [Fixed #39][issue-39]
-   Updated to stop falling back to the unicode path extra field policy
-   NOT_ENCODEABLE. If a name is not encodeable in UTF-8, it also is not
-   encodeable in the extra field.
+### Improvements
+
+ * [Pull Request #51][pr-51] - More specific exception for cases when
+   there are no files to archive. Now `EmptyArchiveException` is thrown
+   when you try to create empty archive. Previously the more generic
+   `ArchiverException` was thrown.
+
+### Bugs
+
+ * [Issue #47][issue-47] - Archiver follows symlinks on Windows
+ * [Issue #53][issue-53] - `AbstractZipArchiver` no longer respects
+   `recompressAddedZips`
+ * [Issue #58][issue-58] - Creates corrupt JARs
+
+### Tasks
+
+ * [Pull Request #56][pr-56] - Upgrade the minimum required Java version to 7
+   and Plexus IO to 3.0.0
+ * [Issue #60][issue-60] - Upgrade dependencies.
+   `plexus-container-default` to `1.0-alpha-30`,
+   `commons-compress` to 1.14, `org.tukaani.xz` to 1.6 and
+   `com.google.code.findbugs.jsr305` to 3.0.2
+
+Plexus IO 3.0.0
+---------------
+
+Plexus IO 3.0.0 requires Java 7 and introduces backward incompatible changes:
+
+ * `Java7FileAttributes` is renamed to `FileAttributes`, replacing
+   the old `FileAttributes` implementation
+ * `Java7AttributeUtils` is renamed to `AttributeUtils`
+ * `PlexusIoResourceAttributeUtils#getFileAttributesByPath( File, boolean, boolean )`
+   is deleted
+
+### Improvements
 
+ * [Pull Request #5][io-pr-5] - The required Java version is upgraded to 7.
+   Classes that use native tools like `ls` are removed and the pure Java
+   implementations are used instead.
+
+### Tasks
+
+ * [Issue #8][io-issue-8] - Update of `plexus-utils` to 3.0.24 and
+   `commons-io` to 2.5
+
+Plexus Archiver 3.4
+-------------------
+
+### Bugs
+
+ * [Issue #45][issue-45] - Default `ArchiveManager` does not support
+   `tar.xz` and `tar.snappy` file extensions
+ * [Issue #46][issue-46] - `JarSecurityFileSelector` needs to support
+   signature files ending in `.EC` or `.ec`
+
+Plexus Archiver 3.3
+-------------------
+
+### Improvements
+
+ * [Issue #42][issue-42] - No need to fallback to unicode path extra field
+   policy `NOT_ENCODEABLE`
+ * [Issue #39][issue-39] - Updated to stop falling back to the unicode path extra field
+   policy `NOT_ENCODEABLE`. If a name is not encodeable in UTF-8, it also is not
+   encodeable in the extra field.
    Updated to always add the Info-ZIP Unicode Path Extra Field when creating an
    archive using an encoding different from UTF-8 instead of only when a name is
    not encodeable. Additionally support that extra field when unarchiving.
+ * [Issue #38][issue-38] - Downgrade `PrintWriter` to `Writer` in `Manifest`
+ * [Issue #36][issue-36] - `Created-by` entry does not reflect who created the JAR
+ * [Issue #35][issue-35] - Replace `defaultManifest.mf` with inline code
+ * [Issue #17][issue-17] - Remove unnecessary conversion in `Manifest#Attribute#write`
+ * [Issue #16][issue-16] - Manifest entry `Archiver-Version` is incomplete/wrong.
+   Entry does not reflect the archiver version. Remove since it
+   adds not information it pretends to add.
+ * [Issue #5][issue-5] - Added proper bound on memory usage, patch by Björn Eickvonder
+ * [Pull Request #41][pr-41] - Support the Info-ZIP Unicode Path Extra Field.
 
- * [Fixed #38][issue-38]
-   Downgrade PrintWriter to Writer in Manifest
+### Bugs
 
- * [Fixed #37][issue-37]
-   Deprecate Manifest(Reader) and update all related Implemenation does not properly
-   map characters to map and makes assumptions about character encoding which might
-   lead to failures. Deprecate and rely on Java Manifest reader to do the right thing.
+ * [Issue #43][issue-43] - Updated to stop failing creating `Created-by` manifest entries,
+   when the version of the archiver cannot be determined
+ * [Issue #37][issue-37] - Deprecate `Manifest(Reader)` and update all related
+   Implemenation does not properly map characters to map and makes assumptions
+   about character encoding which might lead to failures.
+   Deprecate and rely on Java Manifest reader to do the right thing.
+ * [Issue #20][issue-20] - `Manifest#write` blindly casts bytes to chars
+ * [Issue #18][issue-18] - `Manifest#Attribute#writeLine` does not properly calculate
+   max line length
 
- * [Fixed #36][issue-36]
-   Created-by entry does not reflect who created the JAR
+### Tasks
 
- * [Fixed #35][issue-35]
-   Replace defaultManifest.mf with inline code
+ * [Issue #40][issue-40] - Updated to upgrade `plexus-utils` to latest patch release
 
- * [Fixed #20][issue-20]
-   Manifest#write blindly casts bytes to chars
+Plexus Archiver 3.2
+-------------------
 
- * [Fixed #18][issue-18]
-   Manifest#Attribute#writeLine does not properly calculate max line length
+### New Features
 
- * [Fixed #17][issue-17]
-   Remove unnecessary conversion in Manifest#Attribute#write
+ * [Pull Request #27][pr-27] - Added xz compression support
 
- * [Fixed #16][issue-16]
-   Manifest entry "Archiver-Version" is incomplete/wrong
-   Entry does not reflect the archiver version. Remove since it
-   adds not information it pretends to add.
+### Improvements
+
+ * [Issue #33][issue-33] - Exceptions are suppressed incorrectly
+
+### Tasks
+
+ * [Issue #31][issue-31] - Upgrade of `plexus-utils` to 3.0.23
+ * [Issue #32][issue-32] - Upgrade of `commons-io` to 2.5
+
+Plexus Archiver 3.1.1
+---------------------
+
+### Bugs
+
+ * [Issue #28][issue-28] - which checks for null preventing NPE
+
+### Improvements
+
+ * [Pull Request #26][pr-26] - Improvement from Plamen Totev
+
+Plexus IO 2.6.1
+---------------
+
+### Improvement
+
+ * Performance improvement affecting mac/linux users
+   with lots of small files in large archives.
+
+Plexus Archiver 3.0.2
+---------------------
+
+### Improvement
+
+ * `DirectoryArhiver` now respects filemode for directories.
+   Thanks for Olivier Fayau for patch.
+
+Plexus Archiver 3.0.1
+---------------------
+
+### Improvements
+
+ * [Issue #3][issue-3] - Switched to pure-java snappy
 
- * [Fixed #5][issue-5]
-   Added proper bound on memory usage, patch by Björn Eickvonder
+Plexus Archiver 3.0
+-------------------
 
- * [Pull Request #41][pr-41]
-   Support the Info-ZIP Unicode Path Extra Field.
+### Improvements
 
-## Release 3.2
+ * PLXCOMP-282 - Add Snappy compression support
 
- * Task [#31](https://github.com/codehaus-plexus/plexus-archiver/issues/31) Upgrade of 'plexus-utils' to 3.0.23.
- * Task [#32](https://github.com/codehaus-plexus/plexus-archiver/issues/32) Upgrade of 'commons-io' to 2.5.
- * Fixed [#33](https://github.com/codehaus-plexus/plexus-archiver/issues/32) Exceptions are suppressed incorrectly.
- * Pull Request [#27](https://github.com/codehaus-plexus/plexus-archiver/issues/27) Added xz compression support.
+Plexus Archiver 2.10.3
+----------------------
 
-## Release 3.1.1
+### Bugs
 
- * Fixed [#28](https://github.com/codehaus-plexus/plexus-archiver/issues/28) which checks for null preventing NPE.
- * Pull Request [#26](https://github.com/codehaus-plexus/plexus-archiver/issues/26) - Improvement from Plamen Totev.
+ * [Issue #6][issue-6] - "Too many open files" when building large jars
 
-Plexus Components - Version plexus-io-2.6.1
------
+Plexus Archiver 2.10.2
+----------------------
 
-** Improvement
+### Bugs
 
-Performance improvement affecting mac/linux users with lots of small files in large archives.
+ * https://issues.apache.org/jira/browse/MASSEMBLY-769
 
-Plexus Archiver - 3.0.2
-------
+Plexus Archiver 2.10.1
+----------------------
 
-DirectoryArhiver now respects filemode for directories. Thanks for Olivier Fayau for patch.
+### Bugs
 
+ * https://issues.apache.org/jira/browse/MASSEMBLY-768
 
-Plexus Archiver - Version 3.0.1
-------
-** Improvement
+Plexus Archiver 2.10
+--------------------
 
-Switched to pure-java snappy. Fixed issue [#3](https://github.com/codehaus-plexus/plexus-archiver/issues/3)
+ * Symlink support in DirectoryArchiver
+ * Multithreaded ZIP support
+ * Fixed resource leak on ZIP files included in ZIP files.
+ * Added encoding supporting overload: addArchivedFileSet( final ArchivedFileSet fileSet, Charset charset )
+ * Fixed NPE with missing folder in TAR
+ * Moved all "zip" support to archiver (from io).
 
-Plexus Archiver - Version 3.0
-------
-** Improvement
+Plexus IO 2.5
+-------------
 
-  * [PLXCOMP-282] - Add Snappy compression support
+ * Proper support for closeable on zip archives.
+ * Removed zip supporting PlexusIoZipFileResourceCollection; which now exists in plexus-archiver. (Drop in replacement,
+   just change/add jar file).
 
-Plexus Components - Version plexus-archiver-2.10.3
------
+Plexus Archiver 2.9.1
+---------------------
 
-Issue [#6](https://github.com/codehaus-plexus/plexus-archiver/issues/6) fix
+ * Wrap-up release with plexus-io-2.4.1
 
-Plexus Components - Version plexus-archiver-2.10.2
------
+Plexus IO 2.4.1
+---------------
 
-https://issues.apache.org/jira/browse/MASSEMBLY-769 fix.
+### Bugs
 
+ * PLXCOMP-279 - PlexusIoProxyResourceCollection does not provide Closeable iterator
+ * Fixed PLXCOMP-280 - SimpleResourceAttributes has incorrect value for
+   default file mode
 
-Plexus Components - Version plexus-archiver-2.10.1
------
+Plexus Archiver 2.9
+-------------------
 
-https://issues.apache.org/jira/browse/MASSEMBLY-768 fix.
+### Improvements
 
-Plexus Components - Version plexus-archiver-2.10
------
+ * PLXCOMP-276 - Reduce number of ways to create a PlexusIoResource
 
-* Symlink support in DirectoryArchiver
-* Multithreaded ZIP support
-* Fixed resource leak on ZIP files included in ZIP files.
-* Added encoding supporting overload: addArchivedFileSet( final ArchivedFileSet fileSet, Charset charset )
-* Fixed NPE with missing folder in TAR
-* Moved all "zip" support to archiver (from io).
+### Bugs
 
+ * PLXCOMP-277 - Archiver unable to determine file equailty
 
-Plexus Components - Version plexus-io-2.5
------
-* Proper support for closeable on zip archives.
-* Removed zip supporting PlexusIoZipFileResourceCollection; which now exists in plexus-archiver. (Drop in replacement,
-just change/add jar file).
+Plexus IO 2.4
+-------------
 
-Plexus Components - Version plexus-archiver-2.9.1
------
+### Improvements
 
-Wrap-up release with plexus-io-2.4.1
+ * PLXCOMP-274 - Simplify use of proxies
+ * PLXCOMP-275 - Avoid leaky abstractions
+ * PLXCOMP-276 - Reduce number of ways to create a PlexusIoResource
 
-Plexus Components - Version plexus-io-2.4.1
------
-** Bug
+Plexus Archiver 2.8.4
+---------------------
 
-    * [PLXCOMP-279] - PlexusIoProxyResourceCollection does not provide Closeable iterator
-    * [PLXCOMP-280] - SimpleResourceAttributes has incorrect value for default file mode
+### Bugs
 
-Plexus Components - Version plexus-archiver-2.9
------
-** Bug
+ * PLXCOMP-273 - Normalize file separators for duplicate check
 
-    * [PLXCOMP-277] - Archiver unable to determine file equailty
+Plexus Archiver 2.8.3
+---------------------
 
-** Improvement
+### Bugs
 
-    * [PLXCOMP-276] - Reduce number of ways to create a PlexusIoResource
-Plexus Components - Version plexus-io-2.4
------
-** Improvement
+ * PLXCOMP-271 - Implicit created directories do not obey proper dirMode
+ * PLXCOMP-272 - Overriding dirmode/filemode breaks symlinks
 
-    * [PLXCOMP-274] - Simplify use of proxies
-    * [PLXCOMP-275] - Avoid leaky abstractions
-    * [PLXCOMP-276] - Reduce number of ways to create a PlexusIoResource
-Plexus Components - Version plexus-archiver-2.8.4
------
-** Bug
+Plexus IO 2.3.5
+---------------
 
-    * [PLXCOMP-273] - Normalize file separators for duplicate check
-Plexus Components - Version plexus-archiver-2.8.3
------
-** Bug
+### Bugs
 
-    * [PLXCOMP-271] - Implicit created directories do not obey proper dirMode
-    * [PLXCOMP-272] - overriding dirmode/filemode breaks symlinks
-Plexus Components - Version plexus-io-2.3.5
------
-** Bug
+ * PLXCOMP-278 - Symlink attribute was not preserved through merged/overridden attributes
 
-    * [PLXCOMP-278] - Symlink attribute was not preserved through merged/overridden attributes
-Plexus Components - Version plexus-archiver-2.8.2
------
-** Bug
+Plexus Archiver 2.8.2
+---------------------
 
-    * [PLXCOMP-266] - In-place filtering of streams give incorrect content length for tar files
-Plexus Components - Version plexus-io-2.3.4
------
-** Bug
+### Bugs
 
-    * [PLXCOMP-270] - Escaping algoritghm leaks through to system classloader
-    * [PLXCOMP-272] - overriding dirmode/filemode breaks symlinks
-Plexus Components - Version plexus-io-2.3.3
------
-** Bug
+ * PLXCOMP-266 - In-place filtering of streams give incorrect content length
+   for tar files
 
-    * [PLXCOMP-267] - StreamTransformers are consistently applied to all collections
-Plexus Components - Version plexus-archiver-2.8.1
------
-** Improvement
+Plexus IO 2.3.4
+---------------
 
-    * [PLXCOMP-268] - Add diagnostic archivers
-Plexus Components - Version plexus-io-2.3.2
------
-** Bug
+### Bugs
 
-    * [PLXCOMP-265] - Locale in shell influences "ls" parsing for screenscraper
-Plexus Components - Version plexus-io-2.3.1
------
-** Bug
+ * PLXCOMP-270 - Escaping algoritghm leaks through to system classloader
+ * PLXCOMP-272 - Overriding dirmode/filemode breaks symlinks
 
-    * [PLXCOMP-264] - Thread safety issue in streamconsumer
-Plexus Components - Version plexus-archiver-2.8
------
-** Bug
+Plexus IO 2.3.3
+---------------
 
-    * [PLXCOMP-262] - Directory symlinks in zip files are incorrect
+### Bugs
 
-** Improvement
+ * PLXCOMP-267 - StreamTransformers are consistently applied to all collections
 
-    * [PLXCOMP-255] - Removed dependency plexus-container-default:1.0-alpha-9-stable-1
+Plexus Archiver 2.8.1
+---------------------
 
-** New Feature
-
-    * [PLXCOMP-263] - Support on-the fly stream filtering
-Plexus Components - Version plexus-io-2.3
------
-** Improvement
+### Improvements
 
-    * [PLXCOMP-260] - Make plexus io collections iterable
-** New Feature
+ * PLXCOMP-268 - Add diagnostic archivers
 
-    * [PLXCOMP-261] - Make plexus io collections support on-the-fly filtering
-Plexus Components - Version plexus-archiver-2.7.1
------
-** Bug
+Plexus IO 2.3.2
+---------------
 
-    * [PLXCOMP-256] - Several archivers leaks file handles
+### Bugs
 
-** Improvement
+ * PLXCOMP-265 - Locale in shell influences "ls" parsing for screenscraper
 
-    * [PLXCOMP-257] - Inconsistent buffering
-Plexus Components - Version plexus-io-2.2
------
-** Bug
+Plexus IO 2.3.1
+---------------
 
-   * [PLXCOMP-251] - Date parsing in "ls" screenscraping has locale dependencies
-   * [PLXCOMP-254] - Fix File.separatorChar normalization when prefixes are used
-Plexus Components - Version plexus-archiver-2.7
------
-** Bug
+### Bugs
 
-    * [PLXCOMP-252] - Tar archivers cannot roundtrip own archives on windows, UTF8 bug
+ * PLXCOMP-264 - Thread safety issue in streamconsumer
 
+Plexus Archiver 2.8
+-------------------
 
-** Improvement
+### New Features
 
-    * [PLXCOMP-253] - Switch default encoding to UTF-8
-Plexus Components - Version plexus-archiver-2.6.4
------
-** Bug
+ * PLXCOMP-263 - Support on-the fly stream filtering
 
-    * [PLXCOMP-45] - ignoreWebXML flag use is opposite of what the name implies.
-    * [PLXCOMP-107] - Fail to unzip archive, which contains file with name  'How_can_I_annotate_a_part_in_the_AAM%3F.Help' .
-    * [PLXCOMP-234] - plexus archiver TarOptions setDirMode and setMode do not do anything unless TarArchiver.setOptions is called
-Plexus Components - Version plexus-io-2.1.4
------
-** Bug
+### Improvements
 
-    * [PLXCOMP-107] - Fail to unzip archive, which contains file with name  'How_can_I_annotate_a_part_in_the_AAM%3F.Help' .
+ * PLXCOMP-255 - Removed dependency plexus-container-default:1.0-alpha-9-stable-1
 
-** Improvement
+### Bugs
 
-    * [PLXCOMP-250] - Upgrade maven-enforcer-plugin to 1.3.1
-Plexus Components - Version plexus-archiver-2.6.3
------
-** Bug
+ * PLXCOMP-262 - Directory symlinks in zip files are incorrect
 
-    * [PLXCOMP-233] - plexus archiver can create tarfiles with empty uid and gid bytes
-    * [PLXCOMP-247] - Bug with windows AND java5
-Plexus Components - Version plexus-io-2.1.3
------
-** Bug
+Plexus IO 2.3
+-------------
 
-    * [PLXCOMP-247] - Bug with windows AND java5
-Plexus Components - Version plexus-archiver-2.6.2
------
-** Bug
+### New Features
 
-    * [PLXCOMP-238] - CRC Failure if compress=false and file size <= 4 bytes
-    * [PLXCOMP-245] - Archives created on windows get zero permissions, creates malformed permissions on linux
-Plexus Components - Version plexus-io-2.1.2
------
-** Bug
+ * PLXCOMP-261 - Make plexus io collections support on-the-fly filtering
 
-    * [PLXCOMP-244] - Don't try to set attributes of symbolic links
-    * [PLXCOMP-245] - Archives created on windows get zero permissions, creates malformed permissions on linux
-Plexus Components - Version plexus-archiver-2.6.1
------
-** Bug
+### Improvements
 
-    * [PLXCOMP-243] - Restore JDK1.5 compatibility
+ * PLXCOMP-260 - Make plexus io collections iterable
 
-Plexus Components - Version plexus-io-2.1.1
------
-** Bug
+Plexus Archiver 2.7.1
+---------------------
 
-    * [PLXCOMP-243] - Restore JDK1.5 compatibility
-Plexus Components - Version plexus-archiver-2.6
------
-** Bug
+### Improvements
 
-    * [PLXCOMP-113] - zip unarchiver doesn't support symlinks (and trivial to fix)
-** Improvement
+ * PLXCOMP-257 - Inconsistent buffering
 
-    * [PLXCOMP-64] - add symlink support to tar unarchiver
-    * [PLXCOMP-117] - add symbolic links managment
-Plexus Components - Version plexus-io-2.1
------
-** Bug
+### Bugs
 
-    * [PLXCOMP-113] - zip unarchiver doesn't support symlinks (and trivial to fix)
-    * [PLXCOMP-241] - ResourcesTest.compare test failure
-    * [PLXCOMP-248] - Use java7 setAttributes and ignore useJvmChmod flag when applicable
+ * PLXCOMP-256 - Several archivers leaks file handles
 
-** Improvement
+Plexus IO 2.2
+-------------
 
-    * [PLXCOMP-64] - add symlink support to tar unarchiver
-    * [PLXCOMP-117] - add symbolic links managment
+### Bugs
 
+ * PLXCOMP-251 - Date parsing in "ls" screenscraping has locale dependencies
+ * PLXCOMP-254 - Fix File.separatorChar normalization when prefixes are used
 
+Plexus Archiver 2.7
+-------------------
 
-Plexus Components - Version plexus-archiver-2.5 (plexus-io 2.0.12)
------
-** Bug
+### Improvements
 
-    * [PLXCOMP-13] - Plexus Archiver fails on certain Jars
-    * [PLXCOMP-205] - Tar unarchiver does not respect includes/excludes flags
-    * [PLXCOMP-216] - Unarchiver extracts files into wrong directory
-    * [PLXCOMP-232] - Failures to unpack .tar.gz files
-    * [PLXCOMP-236] - ZipUnArchiver fails to extract large (>4GB) ZIP files
+ * PLXCOMP-253 - Switch default encoding to UTF-8
 
-** Improvement
+### Bugs
 
-    * [PLXCOMP-153] - TarUnArchiver does not support includes/excludes
-    * [PLXCOMP-240] - Convert everything to commons-compress
+ * PLXCOMP-252 - Tar archivers cannot roundtrip own archives on windows, UTF8 bug
 
+Plexus Archiver 2.6.4
+---------------------
 
-Plexus Components - Version plexus-io-2.0.12
------
+### Bugs
 
-** Bug
+ * PLXCOMP-45 - ignoreWebXML flag use is opposite of what the name implies
+ * PLXCOMP-107 - Fail to unzip archive, which contains file with name
+   'How_can_I_annotate_a_part_in_the_AAM%3F.Help'
+ * PLXCOMP-234 - Plexus archiver TarOptions setDirMode and setMode do not do
+   anything unless TarArchiver.setOptions is called
 
-    * [PLXCOMP-249] - Add support for java7 chmod
+Plexus IO 2.1.4
+---------------
 
-Plexus Components - Version plexus-archiver-2.4.4 (plexus-io 2.0.10)
------
+### Improvements
 
-** Bug
-    * [PLXCOMP-178] - last modification time is not preserved
-    * [PLXCOMP-222] - ZipOutputStream does not set Language encoding flag (EFS) when using UTF-8 encoding
-    * [PLXCOMP-226] - Bug in org.codehaus.plexus.archiver.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:352)
+ * PLXCOMP-250 - Upgrade maven-enforcer-plugin to 1.3.1
 
+### Bugs
 
+ * PLXCOMP-107 - Fail to unzip archive, which contains file with name
+   'How_can_I_annotate_a_part_in_the_AAM%3F.Help'
 
-Older history in JIRA at http://jira.codehaus.org/browse/PLXCOMP
------
+Plexus Archiver 2.6.3
+---------------------
 
+### Bugs
+
+* PLXCOMP-233 - Plexus archiver can create tarfiles with empty uid and gid bytes
+* PLXCOMP-247 - Bug with windows AND java5
+
+Plexus IO 2.1.3
+---------------
+
+### Bugs
+
+ * PLXCOMP-247 - Bug with windows AND java5
+
+Plexus Archiver 2.6.2
+---------------------
+
+### Bugs
+
+  * PLXCOMP-238 - CRC Failure if compress=false and file size <= 4 bytes
+  * PLXCOMP-245 - Archives created on windows get zero permissions,
+    creates malformed permissions on linux
+
+Plexus IO 2.1.2
+---------------
+
+### Bugs
+
+ * PLXCOMP-244 - Don't try to set attributes of symbolic links
+ * PLXCOMP-245 - Archives created on windows get zero permissions,
+   creates malformed permissions on linux
+
+Plexus Archiver 2.6.1
+---------------------
+
+### Bugs
+
+ * PLXCOMP-243 - Restore JDK1.5 compatibility
+
+Plexus IO 2.1.1
+---------------
+
+### Bugs
+
+ * PLXCOMP-243 - Restore JDK1.5 compatibility
+
+Plexus Archiver 2.6
+-------------------
+
+### Bugs
+
+ * PLXCOMP-113 - zip unarchiver doesn't support symlinks (and trivial to fix)
+
+### Improvement
+
+ * PLXCOMP-64 - add symlink support to tar unarchiver
+ * PLXCOMP-117 - add symbolic links managment
+
+Plexus IO 2.1
+-------------
+
+### Improvements
+
+ * PLXCOMP-64 - add symlink support to tar unarchiver
+ * PLXCOMP-117 - add symbolic links managment
+
+### Bugs
+
+ * PLXCOMP-113 - zip unarchiver doesn't support symlinks (and trivial to fix)
+ * PLXCOMP-241 - ResourcesTest.compare test failure
+ * PLXCOMP-248 - Use java7 setAttributes and ignore useJvmChmod flag when applicable
+
+Plexus Archiver 2.5
+-------------------
+
+### Improvements
+
+ * PLXCOMP-153 - TarUnArchiver does not support includes/excludes
+ * PLXCOMP-240 - Convert everything to commons-compress
+
+### Bugs
+
+ * PLXCOMP-13 - Plexus Archiver fails on certain Jars
+ * PLXCOMP-205 - Tar unarchiver does not respect includes/excludes flags
+ * PLXCOMP-216 - Unarchiver extracts files into wrong directory
+ * PLXCOMP-232 - Failures to unpack .tar.gz files
+ * PLXCOMP-236 - ZipUnArchiver fails to extract large (>4GB) ZIP files
+
+Plexus IO 2.0.12
+----------------
+
+### Bugs
+
+ * PLXCOMP-249 - Add support for java7 chmod
+
+Plexus Archiver 2.4.4
+---------------------
+
+### Bugs
+
+ * PLXCOMP-178 - last modification time is not preserved
+ * PLXCOMP-222 - ZipOutputStream does not set Language encoding flag (EFS)
+   when using UTF-8 encoding
+ * PLXCOMP-226 - Bug in org.codehaus.plexus.archiver.zip.ZipOutputStream.closeEntry
+   (ZipOutputStream.java:352)
+
+[issue-3]: https://github.com/codehaus-plexus/plexus-archiver/issues/3
 [issue-5]: https://github.com/codehaus-plexus/plexus-archiver/issues/5
+[issue-6]: https://github.com/codehaus-plexus/plexus-archiver/issues/6
 [issue-16]: https://github.com/codehaus-plexus/plexus-archiver/issues/16
 [issue-17]: https://github.com/codehaus-plexus/plexus-archiver/issues/17
 [issue-18]: https://github.com/codehaus-plexus/plexus-archiver/issues/18
 [issue-20]: https://github.com/codehaus-plexus/plexus-archiver/issues/20
+[issue-28]: https://github.com/codehaus-plexus/plexus-archiver/issues/28
+[issue-31]: https://github.com/codehaus-plexus/plexus-archiver/issues/31
+[issue-32]: https://github.com/codehaus-plexus/plexus-archiver/issues/32
+[issue-33]: https://github.com/codehaus-plexus/plexus-archiver/issues/32
 [issue-34]: https://github.com/codehaus-plexus/plexus-archiver/issues/34
 [issue-35]: https://github.com/codehaus-plexus/plexus-archiver/issues/35
 [issue-36]: https://github.com/codehaus-plexus/plexus-archiver/issues/36
@@ -384,4 +525,16 @@ Older history in JIRA at http://jira.codehaus.org/browse/PLXCOMP
 [issue-43]: https://github.com/codehaus-plexus/plexus-archiver/issues/43
 [issue-45]: https://github.com/codehaus-plexus/plexus-archiver/issues/45
 [issue-46]: https://github.com/codehaus-plexus/plexus-archiver/issues/46
+[issue-47]: https://github.com/codehaus-plexus/plexus-archiver/issues/47
+[issue-53]: https://github.com/codehaus-plexus/plexus-archiver/issues/53
+[issue-58]: https://github.com/codehaus-plexus/plexus-archiver/issues/58
+[issue-60]: https://github.com/codehaus-plexus/plexus-archiver/issues/60
+[pr-26]: https://github.com/codehaus-plexus/plexus-archiver/issues/26
+[pr-27]: https://github.com/codehaus-plexus/plexus-archiver/issues/27
 [pr-41]: https://github.com/codehaus-plexus/plexus-archiver/pull/41
+[pr-51]: https://github.com/codehaus-plexus/plexus-archiver/pull/51
+[pr-56]: https://github.com/codehaus-plexus/plexus-archiver/pull/56
+[pr-87]: https://github.com/codehaus-plexus/plexus-archiver/pull/87
+
+[io-issue-8]: https://github.com/codehaus-plexus/plexus-io/issues/8
+[io-pr-5]: https://github.com/codehaus-plexus/plexus-io/pull/5


=====================================
debian/changelog
=====================================
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+plexus-archiver (3.6.0-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream release
+    - Fixes CVE-2018-1002200: Arbitrary file write vulnerability using
+      a specially crafted zip file (Closes: #900953)
+  * Removed Damien Raude-Morvan from the uploaders (Closes: #889426)
+  * Standards-Version updated to 4.1.4
+  * Switch to debhelper level 11
+  * Use salsa.debian.org Vcs-* URLs
+
+ -- Emmanuel Bourg <ebourg at apache.org>  Thu, 07 Jun 2018 11:50:41 +0200
+
 plexus-archiver (3.5-2) unstable; urgency=medium
 
   * Team upload.


=====================================
debian/compat
=====================================
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-10
+11


=====================================
debian/control
=====================================
--- a/debian/control
+++ b/debian/control
@@ -4,10 +4,9 @@ Priority: optional
 Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
 Uploaders:
  Torsten Werner <twerner at debian.org>,
- Ludovic Claude <ludovic.claude at laposte.net>,
- Damien Raude-Morvan <drazzib at debian.org>
+ Ludovic Claude <ludovic.claude at laposte.net>
 Build-Depends:
- debhelper (>= 10),
+ debhelper (>= 11~),
  default-jdk,
  junit4,
  libcommons-compress-java (>= 1.9),
@@ -18,9 +17,9 @@ Build-Depends:
  libsnappy-java,
  libxz-java,
  maven-debian-helper (>= 2.2)
-Standards-Version: 4.1.0
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/plexus-archiver.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/plexus-archiver.git
+Standards-Version: 4.1.4
+Vcs-Git: https://salsa.debian.org/java-team/plexus-archiver.git
+Vcs-Browser: https://salsa.debian.org/java-team/plexus-archiver
 Homepage: https://codehaus-plexus.github.io/plexus-archiver/
 
 Package: libplexus-archiver-java


=====================================
debian/rules
=====================================
--- a/debian/rules
+++ b/debian/rules
@@ -2,6 +2,3 @@
 
 %:
 	dh $@
-
-get-orig-source:
-	uscan --download-current-version --force-download --rename


=====================================
pom.xml
=====================================
--- a/pom.xml
+++ b/pom.xml
@@ -10,14 +10,14 @@
   </parent>
 
   <artifactId>plexus-archiver</artifactId>
-  <version>3.5</version>
+  <version>3.6.0</version>
   <name>Plexus Archiver Component</name>
 
   <scm>
     <connection>scm:git:git at github.com:codehaus-plexus/plexus-archiver.git</connection>
     <developerConnection>scm:git:git at github.com:codehaus-plexus/plexus-archiver.git</developerConnection>
     <url>http://github.com/codehaus-plexus/plexus-archiver</url>
-    <tag>plexus-archiver-3.5</tag>
+    <tag>plexus-archiver-3.6.0</tag>
   </scm>
   <issueManagement>
     <system>jira</system>
@@ -57,17 +57,17 @@
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-utils</artifactId>
-      <version>3.0.24</version>
+      <version>3.1.0</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-io</artifactId>
-      <version>3.0.0</version>
+      <version>3.0.1</version>
     </dependency>
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-compress</artifactId>
-      <version>1.14</version>
+      <version>1.16.1</version>
     </dependency>
     <dependency>
       <groupId>org.iq80.snappy</groupId>
@@ -89,7 +89,7 @@
     <dependency>
       <groupId>org.tukaani</groupId>
       <artifactId>xz</artifactId>
-      <version>1.6</version>
+      <version>1.8</version>
       <scope>runtime</scope>
     </dependency>
   </dependencies>


=====================================
src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
=====================================
--- a/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
+++ b/src/main/java/org/codehaus/plexus/archiver/AbstractArchiver.java
@@ -1007,6 +1007,8 @@ public final void createArchive()
         {
             cleanUp();
         }
+
+        postCreateArchive();
     }
 
     protected boolean hasVirtualFiles()
@@ -1036,6 +1038,21 @@ protected void validate()
     {
     }
 
+    /**
+     * This method is called after the archive creation
+     * completes successfully (no exceptions are thrown).
+     *
+     * Subclasses may override this method in order to
+     * augment or validate the archive after it is
+     * created.
+     *
+     * @since 3.6
+     */
+    protected void postCreateArchive()
+        throws ArchiverException, IOException
+    {
+    }
+
     protected abstract String getArchiveType();
 
     private void addCloseable( Object maybeCloseable )


=====================================
src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
=====================================
--- a/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
+++ b/src/main/java/org/codehaus/plexus/archiver/AbstractUnArchiver.java
@@ -308,6 +308,15 @@ protected void extractFile( final File srcF, final File dir, final InputStream c
         // Hmm. Symlinks re-evaluate back to the original file here. Unsure if this is a good thing...
         final File f = FileUtils.resolveFile( dir, entryName );
 
+        // Make sure that the resolved path of the extracted file doesn't escape the destination directory
+        String canonicalDirPath = dir.getCanonicalPath();
+        String canonicalDestPath = f.getCanonicalPath();
+
+        if ( !canonicalDestPath.startsWith( canonicalDirPath ) )
+        {
+            throw new ArchiverException( "Entry is outside of the target directory (" + entryName + ")" );
+        }
+
         try
         {
             if ( !isOverwrite() && f.exists() && ( f.lastModified() >= entryDate.getTime() ) )


=====================================
src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
=====================================
--- a/src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
+++ b/src/main/java/org/codehaus/plexus/archiver/jar/JarArchiver.java
@@ -484,7 +484,10 @@ protected void zipFile( InputStreamSupplier is, ConcurrentJarCreator zOut, Strin
         {
             if ( !doubleFilePass || skipWriting )
             {
-                filesetManifest( fromArchive, is.get() );
+                try ( InputStream manifestInputStream = is.get() )
+                {
+                    filesetManifest( fromArchive, manifestInputStream );
+                }
             }
         }
         else if ( INDEX_NAME.equalsIgnoreCase( vPath ) && index )


=====================================
src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java
=====================================
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiver.java
@@ -0,0 +1,256 @@
+/**
+ *
+ * Copyright 2018 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.plexus.archiver.jar;
+
+import org.apache.commons.compress.parallel.InputStreamSupplier;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
+import org.codehaus.plexus.archiver.util.ResourceUtils;
+import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;
+import org.codehaus.plexus.components.io.resources.PlexusIoResource;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * A {@link ModularJarArchiver} implementation that uses
+ * the {@code jar} tool provided by
+ * {@code java.util.spi.ToolProvider} to create
+ * modular JAR files.
+ *
+ * <p>
+ * The basic JAR archive is created by {@link JarArchiver}
+ * and the {@code jar} tool is used to upgrade it to modular JAR.
+ *
+ * <p>
+ * If the JAR file does not contain module descriptor
+ * or the JDK does not provide the {@code jar} tool
+ * (for example JDK prior to Java 9), then the
+ * archive created by {@link JarArchiver}
+ * is left unchanged.
+ */
+public class JarToolModularJarArchiver
+    extends ModularJarArchiver
+{
+    private static final String MODULE_DESCRIPTOR_FILE_NAME
+        = "module-info.class";
+
+    private static final Pattern MRJAR_VERSION_AREA
+        = Pattern.compile( "META-INF/versions/\\d+/" );
+
+    private Object jarTool;
+
+    private boolean moduleDescriptorFound;
+
+    private Path tempDir;
+
+    public JarToolModularJarArchiver()
+    {
+        try
+        {
+            Class<?> toolProviderClass =
+                Class.forName( "java.util.spi.ToolProvider" );
+            Object jarToolOptional = toolProviderClass
+                .getMethod( "findFirst", String.class )
+                .invoke( null, "jar" );
+
+            jarTool = jarToolOptional.getClass().getMethod( "get" )
+                .invoke( jarToolOptional );
+        }
+        catch ( ReflectiveOperationException | SecurityException e )
+        {
+            // Ignore. It is expected that the jar tool
+            // may not be available.
+        }
+    }
+
+    @Override
+    protected void zipFile( InputStreamSupplier is, ConcurrentJarCreator zOut,
+                            String vPath, long lastModified, File fromArchive,
+                            int mode, String symlinkDestination,
+                            boolean addInParallel )
+        throws IOException, ArchiverException
+    {
+        // We store the module descriptors in temporary location
+        // and then add it to the JAR file using the JDK jar tool.
+        // It may look strange at first, but to update a JAR file
+        // you need to add new files[1] and the only files
+        //  we're sure that exists in modular JAR file
+        // are the module descriptors.
+        //
+        // [1] There are some exceptions but we need at least one file to
+        // ensure it will work in all cases.
+        if ( jarTool != null && isModuleDescriptor( vPath ) )
+        {
+            getLogger().debug( "Module descriptor found: " + vPath );
+
+            moduleDescriptorFound = true;
+
+            // Copy the module descriptor to temporary directory
+            // so later then can be added to the JAR archive
+            // by the jar tool.
+
+            if ( tempDir == null )
+            {
+                tempDir = Files
+                    .createTempDirectory( "plexus-archiver-modular_jar-" );
+                tempDir.toFile().deleteOnExit();
+            }
+
+            File destFile = tempDir.resolve( vPath ).toFile();
+            destFile.getParentFile().mkdirs();
+            destFile.deleteOnExit();
+
+            ResourceUtils.copyFile( is.get(), destFile );
+            ArchiveEntryUtils.chmod( destFile,  mode );
+            destFile.setLastModified( lastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
+                                                      ? System.currentTimeMillis()
+                                                      : lastModified );
+        }
+        else
+        {
+            super.zipFile( is, zOut, vPath, lastModified,
+                fromArchive, mode, symlinkDestination, addInParallel );
+        }
+    }
+
+    @Override
+    protected void postCreateArchive()
+        throws ArchiverException
+    {
+        if ( !moduleDescriptorFound )
+        {
+            // no need to update the JAR archive
+            return;
+        }
+
+        try
+        {
+            getLogger().debug( "Using the jar tool to " +
+                "update the archive to modular JAR." );
+
+			Integer result = (Integer) jarTool.getClass()
+                .getMethod( "run",
+                    PrintStream.class, PrintStream.class, String[].class )
+                .invoke( jarTool,
+                    System.out, System.err,
+                    getJarToolArguments() );
+
+            if ( result != null && result != 0 )
+            {
+                throw new ArchiverException( "Could not create modular JAR file. " +
+                    "The JDK jar tool exited with " + result );
+            }
+        }
+        catch ( ReflectiveOperationException | SecurityException e )
+        {
+            throw new ArchiverException( "Exception occurred " +
+                "while creating modular JAR file", e );
+        }
+        finally
+        {
+            clearTempDirectory();
+        }
+    }
+
+    /**
+     * Returns {@code true} if {@code path}
+     * is a module descriptor.
+     */
+    private boolean isModuleDescriptor( String path )
+    {
+        if ( path.endsWith( MODULE_DESCRIPTOR_FILE_NAME ) )
+        {
+            String prefix = path.substring( 0,
+                path.lastIndexOf( MODULE_DESCRIPTOR_FILE_NAME ) );
+
+            // the path is a module descriptor if it located
+            // into the root of the archive or into the
+            // version are of a multi-release JAR file
+            return prefix.isEmpty() ||
+                MRJAR_VERSION_AREA.matcher( prefix ).matches();
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Prepares the arguments for the jar tool.
+     * It takes into account the module version,
+     * main class, etc.
+     */
+    private String[] getJarToolArguments()
+    {
+        List<String> args = new ArrayList<>();
+
+        args.add( "--update" );
+        args.add( "--file" );
+        args.add( getDestFile().getAbsolutePath() );
+
+        if ( getModuleMainClass() != null )
+        {
+            args.add( "--main-class" );
+            args.add( getModuleMainClass() );
+        }
+
+        if ( getModuleVersion() != null )
+        {
+            args.add( "--module-version" );
+            args.add( getModuleVersion() );
+        }
+
+        if ( !isCompress() )
+        {
+            args.add( "--no-compress" );
+        }
+
+        args.add( "-C" );
+        args.add( tempDir.toFile().getAbsolutePath() );
+        args.add( "." );
+
+        return args.toArray( new String[]{} );
+    }
+
+    /**
+     * Makes best effort the clean up
+     * the temporary directory used.
+     */
+    private void clearTempDirectory()
+    {
+        try
+        {
+            if ( tempDir != null )
+            {
+                FileUtils.deleteDirectory( tempDir.toFile() );
+            }
+        }
+        catch ( IOException e )
+        {
+            // Ignore. It is just best effort.
+        }
+    }
+
+}


=====================================
src/main/java/org/codehaus/plexus/archiver/jar/ModularJarArchiver.java
=====================================
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/archiver/jar/ModularJarArchiver.java
@@ -0,0 +1,76 @@
+/**
+ *
+ * Copyright 2018 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.plexus.archiver.jar;
+
+/**
+ * Base class for creating modular JAR archives.
+ *
+ * Subclasses are required to be able to handle both
+ * JAR archives with module descriptor (modular JAR)
+ * and without ("regular" JAR).
+ * That would allow clients of this class to use
+ * it without prior knowledge if the classes
+ * they are going to add are part of module
+ * (contain module descriptor class) or not.
+ *
+ * @since 3.6
+ */
+public abstract class ModularJarArchiver
+    extends JarArchiver
+{
+    private String moduleMainClass;
+
+    private String moduleVersion;
+
+    public String getModuleMainClass()
+    {
+        return moduleMainClass;
+    }
+
+    /**
+     * Sets the module main class.
+     * Ignored if the JAR file does not contain
+     * module descriptor.
+     *
+     * <p>Note that implementations may choose
+     * to replace the value set in the manifest as well.
+     *
+     * @param moduleMainClass the module main class.
+     */
+    public void setModuleMainClass( String moduleMainClass )
+    {
+        this.moduleMainClass = moduleMainClass;
+    }
+
+    public String getModuleVersion()
+    {
+        return moduleVersion;
+    }
+
+    /**
+     * Sets the module version.
+     * Ignored if the JAR file does not contain
+     * module descriptor.
+     *
+     * @param moduleVersion the module version.
+     */
+    public void setModuleVersion( String moduleVersion )
+    {
+        this.moduleVersion = moduleVersion;
+    }
+
+}


=====================================
src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
=====================================
--- a/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
+++ b/src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
@@ -23,6 +23,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.SequenceInputStream;
+import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.util.Hashtable;
 import java.util.Stack;
@@ -502,8 +503,7 @@ protected void zipFile( InputStreamSupplier in, ConcurrentJarCreator zOut, Strin
             InputStream payload;
             if ( ze.isUnixSymlink() )
             {
-                ZipEncoding enc = ZipEncodingHelper.getZipEncoding( getEncoding() );
-                final byte[] bytes = enc.encode( symlinkDestination ).array();
+                final byte[] bytes = encodeArchiveEntry( symlinkDestination, getEncoding() );
                 payload = new ByteArrayInputStream( bytes );
                 zOut.addArchiveEntry( ze, createInputStreamSupplier( payload ), true );
             }
@@ -644,14 +644,24 @@ protected void zipDir( PlexusIoResource dir, ConcurrentJarCreator zOut, String v
             else
             {
                 String symlinkDestination = ( (SymlinkDestinationSupplier) dir ).getSymlinkDestination();
-                ZipEncoding enc = ZipEncodingHelper.getZipEncoding( encodingToUse );
-                final byte[] bytes = enc.encode( symlinkDestination ).array();
+                final byte[] bytes = encodeArchiveEntry( symlinkDestination, encodingToUse );
                 ze.setMethod( ZipArchiveEntry.DEFLATED );
                 zOut.addArchiveEntry( ze, createInputStreamSupplier( new ByteArrayInputStream( bytes ) ), true );
             }
         }
     }
 
+    private byte[] encodeArchiveEntry( String payload, String encoding )
+        throws IOException
+    {
+        ZipEncoding enc = ZipEncodingHelper.getZipEncoding( encoding );
+        ByteBuffer encodedPayloadByteBuffer = enc.encode( payload );
+        byte[] encodedPayloadBytes = new byte[encodedPayloadByteBuffer.limit()];
+        encodedPayloadByteBuffer.get( encodedPayloadBytes );
+
+        return encodedPayloadBytes;
+    }
+
     protected InputStreamSupplier createInputStreamSupplier( final InputStream inputStream )
     {
         return new InputStreamSupplier()


=====================================
src/main/java/org/codehaus/plexus/archiver/zip/PlexusIoZipFileResourceCollection.java
=====================================
--- a/src/main/java/org/codehaus/plexus/archiver/zip/PlexusIoZipFileResourceCollection.java
+++ b/src/main/java/org/codehaus/plexus/archiver/zip/PlexusIoZipFileResourceCollection.java
@@ -196,7 +196,14 @@ public void remove()
         public void close()
             throws IOException
         {
-            zipFile.close();
+            try
+            {
+                urlClassLoader.close();
+            }
+            finally
+            {
+                zipFile.close();
+            }
         }
 
     }


=====================================
src/main/resources/META-INF/plexus/components.xml
=====================================
--- a/src/main/resources/META-INF/plexus/components.xml
+++ b/src/main/resources/META-INF/plexus/components.xml
@@ -41,6 +41,12 @@
       <implementation>org.codehaus.plexus.archiver.jar.JarArchiver</implementation>
       <instantiation-strategy>per-lookup</instantiation-strategy>
     </component>
+    <component>
+      <role>org.codehaus.plexus.archiver.Archiver</role>
+      <role-hint>mjar</role-hint>
+      <implementation>org.codehaus.plexus.archiver.jar.JarToolModularJarArchiver</implementation>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
+    </component>
 
     <component>
       <role>org.codehaus.plexus.archiver.Archiver</role>


=====================================
src/test/java/org/codehaus/plexus/archiver/BasePlexusArchiverTest.java
=====================================
--- a/src/test/java/org/codehaus/plexus/archiver/BasePlexusArchiverTest.java
+++ b/src/test/java/org/codehaus/plexus/archiver/BasePlexusArchiverTest.java
@@ -24,6 +24,10 @@
 package org.codehaus.plexus.archiver;
 
 import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.FileTime;
+
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.util.FileUtils;
 
@@ -35,31 +39,54 @@
 {
 
     /**
-     * Ensure that when a new file is created at the specified location that the timestamp of
-     * that file will be greater than the one specified as a reference.
-     *
-     * Warning: Runs in a busy loop creating a file until the output file is newer than the reference timestamp.
-     * This should be better than sleeping for a race condition time out value.
+     * Ensure that the last modified timestamp of a file will be greater
+     * than the one specified as a reference.
      *
-     * @param outputFile the file to be created
-     * @param timestampReference the created file will have a newer timestamp than this reference timestamp.
+     * @param outputFile the file
+     * @param timestampReference the file will have a newer timestamp
+     *        than this reference timestamp.
      *
-     * @throws Exception failures
+     * @throws IOException if the timestamp could not be modified
      */
-    protected void waitUntilNewTimestamp( File outputFile, long timestampReference ) throws Exception
+    protected void waitUntilNewTimestamp( File outputFile, long timestampReference )
+        throws IOException
     {
-        File tmpFile = File.createTempFile( "ZipArchiverTest.waitUntilNewTimestamp", null );
-        // slurp the file into a temp file and then copy the temp back over the top until it is newer.
-        FileUtils.copyFile( outputFile, tmpFile );
+        long startTime = System.currentTimeMillis();
+        File tmpFile = File.createTempFile(
+            "BasePlexusArchiverTest.waitUntilNewTimestamp", null );
+        long newTimestamp;
 
-        FileUtils.copyFile( tmpFile, outputFile );
-        while ( timestampReference >= outputFile.lastModified() )
+        // We could easily just set the last modified time using
+        // Files.setLastModifiedTime and System.currentTimeMillis(),
+        // but the problem is that tests are using this method to verify that
+        // the force flag is working. To ensure that modified or
+        // newly created files will have timestamp newer than
+        // `timestampReference`, we need to modify a file ourself.
+        // Otherwise the build may fail because when the test overrides
+        // `outputFile` it will have timestamp that is equal
+        // to `timestampReference`.
+        do
         {
-            FileUtils.copyFile( tmpFile, outputFile );
+            FileUtils.fileWrite( tmpFile, "waitUntilNewTimestamp" );
+            newTimestamp = tmpFile.lastModified();
             Thread.yield();
         }
+        while ( timestampReference >= newTimestamp
+                // A simple guard to ensure that we'll not do this forever.
+                // If the last modified timestamp is not changed to
+                // a newer value after 10 seconds, probably it never will.
+                && System.currentTimeMillis() - startTime < 10_000 );
 
         tmpFile.delete();
+
+        if ( timestampReference >= newTimestamp )
+        {
+            throw new IOException("Could not modify the last modified timestamp "
+                + "to newer than the refence value." );
+        }
+
+        FileTime newTimestampTime = FileTime.fromMillis( newTimestamp );
+        Files.setLastModifiedTime( outputFile.toPath(), newTimestampTime );
     }
 
     /**


=====================================
src/test/java/org/codehaus/plexus/archiver/jar/BaseJarArchiverTest.java
=====================================
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/archiver/jar/BaseJarArchiverTest.java
@@ -0,0 +1,71 @@
+/**
+ *
+ * Copyright 2018 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.plexus.archiver.jar;
+
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.util.IOUtil;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public abstract class BaseJarArchiverTest
+{
+
+    /*
+     * Verify that the JarArchiver implementation
+     * could create basic JAR file
+     */
+    @Test
+    public void testCreateJar()
+        throws IOException, ArchiverException
+    {
+        File jarFile = new File( "target/output/testJar.jar" );
+        jarFile.delete();
+
+        JarArchiver archiver = getJarArchiver();
+        archiver.setDestFile( jarFile );
+        archiver.addDirectory( new File( "src/test/resources/java-classes" ) );
+
+        archiver.createArchive();
+
+        // verify that the JAR file is created and contains the expected files
+        try ( ZipFile resultingArchive = new ZipFile( jarFile ) )
+        {
+            // verify that the JAR file contains manifest file
+            assertNotNull( resultingArchive.getEntry( "META-INF/MANIFEST.MF" )  );
+
+            // verify the JAR contains the class and it is not corrupted
+            ZipEntry classFileEntry = resultingArchive.getEntry( "com/example/app/Main.class" );
+            InputStream resultingClassFile = resultingArchive.getInputStream( classFileEntry );
+            InputStream originalClassFile =
+                new FileInputStream( "src/test/resources/java-classes/com/example/app/Main.class" );
+
+            assertTrue( IOUtil.contentEquals( originalClassFile, resultingClassFile ) );
+        }
+    }
+
+    protected abstract JarArchiver getJarArchiver();
+
+}


=====================================
src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
=====================================
--- a/src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
+++ b/src/test/java/org/codehaus/plexus/archiver/jar/JarArchiverTest.java
@@ -5,19 +5,20 @@
 import java.io.IOException;
 import java.util.Random;
 import org.codehaus.plexus.archiver.ArchiverException;
-import junit.framework.TestCase;
+import org.junit.Test;
 
 public class JarArchiverTest
-    extends TestCase
+    extends BaseJarArchiverTest
 {
 
+    @Test
     public void testCreateManifestOnlyJar()
         throws IOException, ManifestException, ArchiverException
     {
         File jarFile = File.createTempFile( "JarArchiverTest.", ".jar" );
         jarFile.deleteOnExit();
 
-        JarArchiver archiver = new JarArchiver();
+        JarArchiver archiver = getJarArchiver();
         archiver.setDestFile( jarFile );
 
         Manifest manifest = new Manifest();
@@ -30,18 +31,20 @@ public void testCreateManifestOnlyJar()
         archiver.createArchive();
     }
 
+    @Test
     public void testNonCompressed()
         throws IOException, ManifestException, ArchiverException
     {
         File jarFile = new File( "target/output/jarArchiveNonCompressed.jar" );
 
-        JarArchiver archiver = new JarArchiver();
+        JarArchiver archiver = getJarArchiver();
         archiver.setDestFile( jarFile );
         archiver.setCompress( false );
         archiver.addDirectory( new File( "src/test/resources/mjar179" ) );
         archiver.createArchive();
     }
 
+    @Test
     public void testVeryLargeJar()
         throws IOException, ManifestException, ArchiverException
     {
@@ -65,10 +68,15 @@ public void testVeryLargeJar()
 
         File jarFile = new File( "target/output/veryLargeJar.jar" );
 
-        JarArchiver archiver = new JarArchiver();
+        JarArchiver archiver = getJarArchiver();
         archiver.setDestFile( jarFile );
         archiver.addDirectory( tmpDir );
         archiver.createArchive();
     }
 
+    @Override
+    protected JarArchiver getJarArchiver()
+    {
+        return new JarArchiver();
+    }
 }


=====================================
src/test/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiverTest.java
=====================================
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/archiver/jar/JarToolModularJarArchiverTest.java
@@ -0,0 +1,308 @@
+/**
+ *
+ * Copyright 2018 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codehaus.plexus.archiver.jar;
+
+import java.io.File;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+public class JarToolModularJarArchiverTest
+    extends BaseJarArchiverTest
+{
+
+    private ModularJarArchiver archiver;
+
+    /*
+     * Configures the ModularJarArchiver for the test cases.
+     */
+    @Before
+    public void ModularJarArchiver()
+        throws Exception
+    {
+        File jarFile = new File( "target/output/modular.jar" );
+        jarFile.delete();
+
+        archiver = getJarArchiver();
+        archiver.setDestFile( jarFile );
+        archiver.addDirectory( new File( "src/test/resources/java-classes" ) );
+    }
+
+    /*
+     * Verify that the main class and the version are properly set for a modular JAR file.
+     */
+    @Test
+    public void testModularJarWithMainClassAndVersion()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        archiver.setModuleVersion( "1.0.0" );
+        archiver.setModuleMainClass( "com.example.app.Main" );
+
+        archiver.createArchive();
+
+        // verify that the proper version and main class are set
+        assertModularJarFile( archiver.getDestFile(),
+            "1.0.0", "com.example.app.Main", "com.example.app", "com.example.resources" );
+    }
+
+    /*
+     * Verify that a modular JAR file is created even when no additional attributes are set.
+     */
+    @Test
+    public void testModularJar()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        archiver.createArchive();
+
+        // verify that the proper version and main class are set
+        assertModularJarFile( archiver.getDestFile(),
+            null, null, "com.example.app", "com.example.resources" );
+    }
+
+    /*
+     * Verify that exception is thrown when the modular JAR is not valid.
+     */
+    @Test( expected = ArchiverException.class )
+    public void testInvalidModularJar()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        // Not a valid version
+        archiver.setModuleVersion( "notAValidVersion" );
+
+        archiver.createArchive();
+    }
+
+    /*
+     * Verify that modular JAR files could be created even
+     * if the Java version does not support modules.
+     */
+    @Test
+    public void testModularJarPriorJava9()
+        throws Exception
+    {
+        assumeFalse( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        archiver.setModuleVersion( "1.0.0" );
+        archiver.setModuleMainClass( "com.example.app.Main" );
+
+        archiver.createArchive();
+
+        // verify that the modular jar is created
+        try ( ZipFile resultingArchive = new ZipFile( archiver.getDestFile() ) )
+        {
+            assertNotNull( resultingArchive.getEntry( "module-info.class" )  );
+        }
+    }
+
+    /*
+     * Verify that the compression flag is respected.
+     */
+    @Test
+    public void testNoCompression()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        archiver.setCompress( false );
+
+        archiver.createArchive();
+
+        // verify that the entries are not compressed
+        try ( ZipFile resultingArchive = new ZipFile( archiver.getDestFile() ) )
+        {
+            Enumeration<? extends ZipEntry> entries = resultingArchive.entries();
+
+            while ( entries.hasMoreElements() )
+            {
+                ZipEntry entry = entries.nextElement();
+
+                assertEquals( ZipEntry.STORED, entry.getMethod() );
+            }
+        }
+    }
+
+    /*
+     * Verify that the compression set in the "plain" JAR file
+     * is kept after it is updated to modular JAR file.
+     */
+    @Test
+    public void testCompression()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addDirectory( new File( "src/test/resources/java-module-descriptor" ) );
+        archiver.addFile( new File( "src/test/jars/test.jar" ), "META-INF/lib/test.jar" );
+        archiver.setRecompressAddedZips( false );
+
+        archiver.createArchive();
+
+        // verify that the compression is kept
+        try ( ZipFile resultingArchive = new ZipFile( archiver.getDestFile() ) )
+        {
+            Enumeration<? extends ZipEntry> entries = resultingArchive.entries();
+
+            while ( entries.hasMoreElements() )
+            {
+                ZipEntry entry = entries.nextElement();
+
+                int expectedMethod = entry.isDirectory() || entry.getName().endsWith( ".jar" )
+                                     ? ZipEntry.STORED
+                                     : ZipEntry.DEFLATED;
+                assertEquals( expectedMethod, entry.getMethod() );
+            }
+        }
+    }
+
+    /*
+     * Verify that a module descriptor in the versioned area is handled correctly.
+     */
+    @Test
+    public void testModularMultiReleaseJar()
+        throws Exception
+    {
+        assumeTrue( modulesAreSupported() );
+
+        archiver.addFile( new File( "src/test/resources/java-module-descriptor/module-info.class" ),
+            "META-INF/versions/9/module-info.class" );
+        Manifest manifest = new Manifest();
+        manifest.addConfiguredAttribute( new Manifest.Attribute( "Multi-Release", "true" ) );
+        archiver.addConfiguredManifest( manifest );
+        archiver.setModuleVersion( "1.0.0" );
+        archiver.setModuleMainClass( "com.example.app.Main" );
+
+        archiver.createArchive();
+
+        // verify that the resulting modular jar has the proper version and main class set
+        try ( ZipFile resultingArchive = new ZipFile( archiver.getDestFile() ) )
+        {
+            ZipEntry moduleDescriptorEntry =
+                resultingArchive.getEntry( "META-INF/versions/9/module-info.class" );
+            InputStream resultingModuleDescriptor = resultingArchive.getInputStream( moduleDescriptorEntry );
+
+            assertModuleDescriptor( resultingModuleDescriptor,
+                    "1.0.0", "com.example.app.Main", "com.example.app", "com.example.resources" );
+        }
+    }
+
+    @Override
+    protected JarToolModularJarArchiver getJarArchiver()
+    {
+        return new JarToolModularJarArchiver();
+    }
+
+    private void assertModularJarFile( File jarFile ,
+                                       String expectedVersion, String expectedMainClass,
+                                       String... expectedPackages )
+        throws Exception
+    {
+        try ( ZipFile resultingArchive = new ZipFile( jarFile ) )
+        {
+            ZipEntry moduleDescriptorEntry = resultingArchive.getEntry( "module-info.class" );
+            InputStream resultingModuleDescriptor = resultingArchive.getInputStream( moduleDescriptorEntry );
+
+            assertModuleDescriptor( resultingModuleDescriptor,
+                expectedVersion, expectedMainClass, expectedPackages );
+        }
+    }
+
+    private void assertModuleDescriptor( InputStream moduleDescriptorInputStream,
+                                         String expectedVersion, String expectedMainClass,
+                                         String... expectedPackages )
+        throws Exception
+    {
+        // ModuleDescriptor methods are available from Java 9 so let's get by reflection
+        Class<?> moduleDescriptorClass = Class.forName( "java.lang.module.ModuleDescriptor" );
+        Class<?> optionalClass = Class.forName( "java.util.Optional" );
+        Method readMethod = moduleDescriptorClass.getMethod( "read", InputStream.class );
+        Method mainClassMethod = moduleDescriptorClass.getMethod( "mainClass" );
+        Method rawVersionMethod = moduleDescriptorClass.getMethod( "rawVersion" );
+        Method packagesMethod = moduleDescriptorClass.getMethod( "packages" );
+        Method isPresentMethod = optionalClass.getMethod( "isPresent" );
+        Method getMethod = optionalClass.getMethod( "get" );
+
+        // Read the module from the input stream
+        Object moduleDescriptor = readMethod.invoke( null, moduleDescriptorInputStream );
+
+        // Get the module main class
+        Object mainClassOptional = mainClassMethod.invoke( moduleDescriptor );
+        String actualMainClass = null;
+        if ( (boolean) isPresentMethod.invoke( mainClassOptional ) )
+        {
+            actualMainClass = (String) getMethod.invoke( mainClassOptional );
+        }
+
+        // Get the module version
+        Object versionOptional = rawVersionMethod.invoke( moduleDescriptor );
+        String actualVersion = null;
+        if ( (boolean) isPresentMethod.invoke( versionOptional ) )
+        {
+            actualVersion = (String) getMethod.invoke( versionOptional );
+        }
+
+        // Get the module packages
+        Set<String> actualPackagesSet = (Set<String>) packagesMethod.invoke( moduleDescriptor );
+        Set<String> expectedPackagesSet = new HashSet<>( Arrays.asList( expectedPackages ) );
+
+        assertEquals( expectedMainClass, actualMainClass );
+        assertEquals( expectedVersion, actualVersion );
+        assertEquals( expectedPackagesSet, actualPackagesSet );
+    }
+
+    /*
+     * Returns true if the current version of Java does support modules.
+     */
+    private boolean modulesAreSupported()
+    {
+        try
+        {
+            Class.forName( "java.lang.module.ModuleDescriptor" );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+}


=====================================
src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java
=====================================
--- a/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java
+++ b/src/test/java/org/codehaus/plexus/archiver/zip/ZipUnArchiverTest.java
@@ -190,6 +190,30 @@ public void testSelectors()
                        } );
     }
 
+    public void testExtractingZipWithEntryOutsideDestDirThrowsException()
+            throws Exception
+    {
+        Exception ex = null;
+        String s = "target/zip-unarchiver-slip-tests";
+        File testZip = new File( getBasedir(), "src/test/zips/zip-slip.zip" );
+        File outputDirectory = new File( getBasedir(), s );
+
+        FileUtils.deleteDirectory( outputDirectory );
+
+        try
+        {
+            ZipUnArchiver zu = getZipUnArchiver( testZip );
+            zu.extract( "", outputDirectory );
+        }
+        catch ( Exception e )
+        {
+            ex = e;
+        }
+
+        assertNotNull( ex );
+        assertTrue( ex.getMessage().startsWith( "Entry is outside of the target directory" ) );
+    }
+
     private ZipArchiver getZipArchiver()
     {
         try


=====================================
src/test/resources/java-classes/com/example/app/Main.class
=====================================
Binary files /dev/null and b/src/test/resources/java-classes/com/example/app/Main.class differ


=====================================
src/test/resources/java-classes/com/example/resources/test.properties
=====================================
--- /dev/null
+++ b/src/test/resources/java-classes/com/example/resources/test.properties
@@ -0,0 +1 @@
+ley=value


=====================================
src/test/resources/java-module-descriptor/module-info.class
=====================================
Binary files /dev/null and b/src/test/resources/java-module-descriptor/module-info.class differ


=====================================
src/test/resources/java-src/REAMDE.md
=====================================
--- /dev/null
+++ b/src/test/resources/java-src/REAMDE.md
@@ -0,0 +1,2 @@
+This is the source code for the Java classes
+inside `java-classes` and `java-module`  directories.


=====================================
src/test/resources/java-src/com/example/app/Main.java
=====================================
--- /dev/null
+++ b/src/test/resources/java-src/com/example/app/Main.java
@@ -0,0 +1,10 @@
+package com.example.app;
+
+public class Main
+{
+
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello from Main" );
+    }
+}


=====================================
src/test/resources/java-src/module-info.java
=====================================
--- /dev/null
+++ b/src/test/resources/java-src/module-info.java
@@ -0,0 +1,4 @@
+module com.example.app
+{
+    exports com.example.app;
+}


=====================================
src/test/zips/zip-slip.zip
=====================================
Binary files /dev/null and b/src/test/zips/zip-slip.zip differ



View it on GitLab: https://salsa.debian.org/java-team/plexus-archiver/compare/496f98b58db72048f78c9add43b3a732595dbe95...35f70760eb10ddde30dbdb337546cc09e533183f

-- 
View it on GitLab: https://salsa.debian.org/java-team/plexus-archiver/compare/496f98b58db72048f78c9add43b3a732595dbe95...35f70760eb10ddde30dbdb337546cc09e533183f
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20180607/0e5031f3/attachment.html>


More information about the pkg-java-commits mailing list