File: src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java
Issue: Parsing PAX headers fails with NegativeArraySizeException
The TarArchiveInputStream.parsePaxHeaders method fails with a NegativeArraySizeException when there is an empty line at the end of the headers.
The inner loop starts reading the length, but it gets a newline (10) and ends up subtracting '0' (48) from it; the result is a negative length that blows up an attempt to allocate the rest array.
I would say that a check to see if ch is less the '0' and break the loop if it is.
I used npm pack aws-sdk@2.2.16 to generate a tarball with this issue.

Buggy code:
Map<String, String> parsePaxHeaders(final InputStream i)
    throws IOException {
    final Map<String, String> headers = new HashMap<String, String>(globalPaxHeaders);
    // Format is "length keyword=value\n";
    while(true){ // get length
        int ch;
        int len = 0;
        int read = 0;
        while((ch = i.read()) != -1) {
            read++;
            if (ch == ' '){
                // Get keyword
                final ByteArrayOutputStream coll = new ByteArrayOutputStream();
                while((ch = i.read()) != -1) {
                    read++;
                    if (ch == '='){ // end of keyword
                        final String keyword = coll.toString(CharsetNames.UTF_8);
                        // Get rest of entry
                        final int restLen = len - read;
                        if (restLen == 1) { // only NL
                            headers.remove(keyword);
                        } else {
                            final byte[] rest = new byte[restLen];
                            final int got = IOUtils.readFully(i, rest);
                            if (got != restLen) {
                                throw new IOException("Failed to read "
                                                      + "Paxheader. Expected "
                                                      + restLen
                                                      + " bytes, read "
                                                      + got);
                            }
                            // Drop trailing NL
                            final String value = new String(rest, 0,
                                                      restLen - 1, CharsetNames.UTF_8);
                            headers.put(keyword, value);
                        }
                        break;
                    }
                    coll.write((byte) ch);
                }
                break; // Processed single header
            }
            len *= 10;
            len += ch - '0';
        }
        if (ch == -1){ // EOF
            break;
        }
    }
    return headers;
}

Fixed code:
Map<String, String> parsePaxHeaders(final InputStream i)
    throws IOException {
    final Map<String, String> headers = new HashMap<String, String>(globalPaxHeaders);
    // Format is "length keyword=value\n";
    while(true){ // get length
        int ch;
        int len = 0;
        int read = 0;
        while((ch = i.read()) != -1) {
            read++;
            if (ch == '\n') { // blank line in header
                break;
            } else if (ch == ' '){ // End of length string
                // Get keyword
                final ByteArrayOutputStream coll = new ByteArrayOutputStream();
                while((ch = i.read()) != -1) {
                    read++;
                    if (ch == '='){ // end of keyword
                        final String keyword = coll.toString(CharsetNames.UTF_8);
                        // Get rest of entry
                        final int restLen = len - read;
                        if (restLen == 1) { // only NL
                            headers.remove(keyword);
                        } else {
                            final byte[] rest = new byte[restLen];
                            final int got = IOUtils.readFully(i, rest);
                            if (got != restLen) {
                                throw new IOException("Failed to read "
                                                      + "Paxheader. Expected "
                                                      + restLen
                                                      + " bytes, read "
                                                      + got);
                            }
                            // Drop trailing NL
                            final String value = new String(rest, 0,
                                                      restLen - 1, CharsetNames.UTF_8);
                            headers.put(keyword, value);
                        }
                        break;
                    }
                    coll.write((byte) ch);
                }
                break; // Processed single header
            }
            len *= 10;
            len += ch - '0';
        }
        if (ch == -1){ // EOF
            break;
        }
    }
    return headers;
}