src/java.base/share/classes/java/util/jar/Manifest.java
author jboes
Fri, 20 Sep 2019 11:07:52 +0100
changeset 58242 94bb65cb37d3
parent 53293 64049c8e7452
permissions -rw-r--r--
8230648: Replace @exception tag with @throws in java.base Summary: Minor coding style update of javadoc tag in any file in java.base Reviewed-by: prappo, lancea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
     2
 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.util.jar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    28
import java.io.DataOutputStream;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.FilterInputStream;
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    30
import java.io.IOException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.OutputStream;
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    33
import java.util.HashMap;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.Map;
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    35
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    36
import sun.security.util.SecurityProperties;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
    38
import static java.nio.charset.StandardCharsets.UTF_8;
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
    39
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * The Manifest class is used to maintain Manifest entry names and their
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * associated Attributes. There are main Manifest Attributes as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * per-entry Attributes. For information on the Manifest format, please
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * see the
45663
4a0cbf8f2474 8182023: some java.util.jar docs contain links to technotes
psandoz
parents: 27804
diff changeset
    45
 * <a href="{@docRoot}/../specs/jar/jar.html">
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * Manifest format specification</a>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @author  David Connelly
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @see     Attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
public class Manifest implements Cloneable {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    53
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    // manifest main attributes
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    55
    private final Attributes attr = new Attributes();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    // manifest entries
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    58
    private final Map<String, Attributes> entries = new HashMap<>();
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    59
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    60
    // associated JarVerifier, not null when called by JarFile::getManifest.
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    61
    private final JarVerifier jv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * Constructs a new, empty Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    public Manifest() {
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    67
        jv = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     * Constructs a new Manifest from the specified input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * @param is the input stream containing manifest data
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 12181
diff changeset
    74
     * @throws IOException if an I/O error has occurred
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    public Manifest(InputStream is) throws IOException {
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    77
        this(null, is, null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /**
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    81
     * Constructs a new Manifest from the specified input stream.
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    82
     *
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    83
     * @param is the input stream containing manifest data
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    84
     * @param jarFilename the name of the corresponding jar archive if available
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    85
     * @throws IOException if an I/O error has occurred
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    86
     */
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    87
    Manifest(InputStream is, String jarFilename) throws IOException {
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    88
        this(null, is, jarFilename);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    89
    }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    90
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    91
    /**
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    92
     * Constructs a new Manifest from the specified input stream
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    93
     * and associates it with a JarVerifier.
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    94
     *
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    95
     * @param jv the JarVerifier to use
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    96
     * @param is the input stream containing manifest data
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    97
     * @param jarFilename the name of the corresponding jar archive if available
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
    98
     * @throws IOException if an I/O error has occurred
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    99
     */
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   100
    Manifest(JarVerifier jv, InputStream is, String jarFilename) throws IOException {
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   101
        read(is, jarFilename);
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   102
        this.jv = jv;
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   103
    }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   104
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   105
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * Constructs a new Manifest that is a copy of the specified Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * @param man the Manifest to copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public Manifest(Manifest man) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        attr.putAll(man.getMainAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        entries.putAll(man.getEntries());
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   113
        jv = man.jv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * Returns the main Attributes for the Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * @return the main Attributes for the Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public Attributes getMainAttributes() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        return attr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Returns a Map of the entries contained in this Manifest. Each entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * is represented by a String name (key) and associated Attributes (value).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * The Map permits the {@code null} key, but no entry with a null key is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * created by {@link #read}, nor is such an entry written by using {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * #write}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * @return a Map of the entries contained in this Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    public Map<String,Attributes> getEntries() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        return entries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * Returns the Attributes for the specified entry name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * This method is defined as:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     *      return (Attributes)getEntries().get(name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * Though {@code null} is a valid {@code name}, when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * {@code getAttributes(null)} is invoked on a {@code Manifest}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * obtained from a jar file, {@code null} will be returned.  While jar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * files themselves do not allow {@code null}-named attributes, it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * possible to invoke {@link #getEntries} on a {@code Manifest}, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * on that result, invoke {@code put} with a null key and an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * arbitrary value.  Subsequent invocations of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * {@code getAttributes(null)} will return the just-{@code put}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * Note that this method does not return the manifest's main attributes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * see {@link #getMainAttributes}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * @param name entry name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * @return the Attributes for the specified entry name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    public Attributes getAttributes(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        return getEntries().get(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    /**
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   164
     * Returns the Attributes for the specified entry name, if trusted.
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   165
     *
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   166
     * @param name entry name
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   167
     * @return returns the same result as {@link #getAttributes(String)}
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   168
     * @throws SecurityException if the associated jar is signed but this entry
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   169
     *      has been modified after signing (i.e. the section in the manifest
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   170
     *      does not exist in SF files of all signers).
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   171
     */
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   172
    Attributes getTrustedAttributes(String name) {
52171
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   173
        // Note: Before the verification of MANIFEST.MF/.SF/.RSA files is done,
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   174
        // jv.isTrustedManifestEntry() isn't able to detect MANIFEST.MF change.
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   175
        // Users of this method should call SharedSecrets.javaUtilJarAccess()
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   176
        // .ensureInitialization() first.
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   177
        Attributes result = getAttributes(name);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   178
        if (result != null && jv != null && ! jv.isTrustedManifestEntry(name)) {
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   179
            throw new SecurityException("Untrusted manifest entry: " + name);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   180
        }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   181
        return result;
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   182
    }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   183
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   184
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * Clears the main Attributes as well as the entries in this Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        attr.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        entries.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * Writes the Manifest to the specified OutputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * Attributes.Name.MANIFEST_VERSION must be set in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * MainAttributes prior to invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @param out the output stream
58242
94bb65cb37d3 8230648: Replace @exception tag with @throws in java.base
jboes
parents: 53293
diff changeset
   198
     * @throws    IOException if an I/O error has occurred
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * @see #getMainAttributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    public void write(OutputStream out) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        DataOutputStream dos = new DataOutputStream(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        // Write out the main attributes for the manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        attr.writeMain(dos);
49442
d6d1c06becda 8200124: Various cleanups in jar/zip
martin
parents: 49111
diff changeset
   205
        // Now write out the per-entry attributes
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   206
        StringBuilder buffer = entries.isEmpty() ? null : new StringBuilder(72);
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21278
diff changeset
   207
        for (Map.Entry<String, Attributes> e : entries.entrySet()) {
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   208
            buffer.setLength(0);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   209
            buffer.append("Name: ");
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   210
            buffer.append(e.getKey());
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   211
            println72(dos, buffer.toString());
11274
7e7196757acd 7117249: fix warnings in java.util.jar, .logging, .prefs, .zip
smarks
parents: 5506
diff changeset
   212
            e.getValue().write(dos);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        dos.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    /**
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   218
     * Adds line breaks to enforce a maximum of 72 bytes per line.
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   219
     *
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   220
     * @deprecation Replaced with {@link #println72}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     */
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   222
    @Deprecated(since = "13")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    static void make72Safe(StringBuffer line) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        int length = line.length();
49111
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   225
        int index = 72;
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   226
        while (index < length) {
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   227
            line.insert(index, "\r\n ");
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   228
            index += 74; // + line width + line break ("\r\n")
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   229
            length += 3; // + line break ("\r\n") and space
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        }
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   231
    }
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   232
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   233
    /**
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   234
     * Writes {@code line} to {@code out} with line breaks and continuation
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   235
     * spaces within the limits of 72 bytes of contents per line followed
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   236
     * by a line break.
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   237
     */
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   238
    static void println72(OutputStream out, String line) throws IOException {
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   239
        if (!line.isEmpty()) {
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   240
            byte[] lineBytes = line.getBytes(UTF_8);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   241
            int length = lineBytes.length;
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   242
            // first line can hold one byte more than subsequent lines which
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   243
            // start with a continuation line break space
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   244
            out.write(lineBytes[0]);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   245
            int pos = 1;
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   246
            while (length - pos > 71) {
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   247
                out.write(lineBytes, pos, 71);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   248
                pos += 71;
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   249
                println(out);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   250
                out.write(' ');
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   251
            }
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   252
            out.write(lineBytes, pos, length - pos);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   253
        }
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   254
        println(out);
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   255
    }
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   256
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   257
    /**
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   258
     * Writes a line break to {@code out}.
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   259
     */
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   260
    static void println(OutputStream out) throws IOException {
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   261
        out.write('\r');
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   262
        out.write('\n');
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   265
    static String getErrorPosition(String filename, final int lineNumber) {
52040
d8aebcc2d3ac 8211860: Avoid reading security properties eagerly on Manifest class initialization
redestad
parents: 51879
diff changeset
   266
        if (filename == null ||
d8aebcc2d3ac 8211860: Avoid reading security properties eagerly on Manifest class initialization
redestad
parents: 51879
diff changeset
   267
                !SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS) {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   268
            return "line " + lineNumber;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   269
        }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   270
        return "manifest of " + filename + ":" + lineNumber;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   271
    }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   272
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * Reads the Manifest from the specified InputStream. The entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * names and attributes read will be merged in with the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * manifest entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * @param is the input stream
58242
94bb65cb37d3 8230648: Replace @exception tag with @throws in java.base
jboes
parents: 53293
diff changeset
   279
     * @throws    IOException if an I/O error has occurred
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    public void read(InputStream is) throws IOException {
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   282
        read(is, null);
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   283
    }
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   284
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   285
    private void read(InputStream is, String jarFilename) throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        // Buffered input stream for reading manifest data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        FastInputStream fis = new FastInputStream(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        // Line buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        byte[] lbuf = new byte[512];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        // Read the main attributes for the manifest
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   291
        int lineNumber = attr.read(fis, lbuf, jarFilename, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        // Total number of entries, attributes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        int ecount = 0, acount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        // Average size of entry attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        int asize = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        // Now parse the manifest entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        int len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        String name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        boolean skipEmptyLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        byte[] lastline = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        while ((len = fis.readLine(lbuf)) != -1) {
50413
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   303
            byte c = lbuf[--len];
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   304
            lineNumber++;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   305
50413
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   306
            if (c != '\n' && c != '\r') {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   307
                throw new IOException("manifest line too long ("
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   308
                           + getErrorPosition(jarFilename, lineNumber) + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            if (len > 0 && lbuf[len-1] == '\r') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                --len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            if (len == 0 && skipEmptyLines) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            skipEmptyLines = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                name = parseName(lbuf, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                if (name == null) {
53291
8f822a19309b 8216362: Better error message handling when there is an invalid Manifest
lancea
parents: 52171
diff changeset
   321
                    throw new IOException("invalid manifest format ("
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   322
                              + getErrorPosition(jarFilename, lineNumber) + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                if (fis.peek() == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                    // name is wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                    lastline = new byte[len - 6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    System.arraycopy(lbuf, 6, lastline, 0, len - 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                // continuation line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                byte[] buf = new byte[lastline.length + len - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                System.arraycopy(lastline, 0, buf, 0, lastline.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                if (fis.peek() == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                    // name is wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                    lastline = buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                }
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   340
                name = new String(buf, 0, buf.length, UTF_8);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                lastline = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            Attributes attr = getAttributes(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            if (attr == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                attr = new Attributes(asize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                entries.put(name, attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            }
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   348
            lineNumber = attr.read(fis, lbuf, jarFilename, lineNumber);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            ecount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            acount += attr.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            //XXX: Fix for when the average is 0. When it is 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            // you get an Attributes object with an initial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            // capacity of 0, which tickles a bug in HashMap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            asize = Math.max(2, acount / ecount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            skipEmptyLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
    private String parseName(byte[] lbuf, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        if (toLower(lbuf[0]) == 'n' && toLower(lbuf[1]) == 'a' &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            toLower(lbuf[2]) == 'm' && toLower(lbuf[3]) == 'e' &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            lbuf[4] == ':' && lbuf[5] == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            try {
53095
33a51275fee0 8066619: Fix deprecation warnings in java.util.jar
rriggs
parents: 52171
diff changeset
   366
                return new String(lbuf, 6, len - 6, UTF_8);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    private int toLower(int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        return (c >= 'A' && c <= 'Z') ? 'a' + (c - 'A') : c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * Returns true if the specified Object is also a Manifest and has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * the same main Attributes and entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * @param o the object to be compared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * @return true if the specified Object is also a Manifest and has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * the same main Attributes and entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    public boolean equals(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        if (o instanceof Manifest) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            Manifest m = (Manifest)o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            return attr.equals(m.getMainAttributes()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                   entries.equals(m.getEntries());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * Returns the hash code for this Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        return attr.hashCode() + entries.hashCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * Returns a shallow copy of this Manifest.  The shallow copy is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * implemented as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     *     public Object clone() { return new Manifest(this); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * @return a shallow copy of this Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    public Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        return new Manifest(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     * A fast buffered input stream for parsing manifest files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    static class FastInputStream extends FilterInputStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        private byte buf[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        private int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        private int pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        FastInputStream(InputStream in) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            this(in, 8192);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        FastInputStream(InputStream in, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            super(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            buf = new byte[size];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        public int read() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            if (pos >= count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                if (pos >= count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            }
11828
590711df7828 7143629: JDK jar/zip code should use unsigned library support
darcy
parents: 11274
diff changeset
   439
            return Byte.toUnsignedInt(buf[pos++]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        public int read(byte[] b, int off, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            int avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                if (len >= buf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                    return in.read(b, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (len > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                len = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            System.arraycopy(buf, pos, b, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            pos += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
         * Reads 'len' bytes from the input stream, or until an end-of-line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
         * is reached. Returns the number of bytes read.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        public int readLine(byte[] b, int off, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            byte[] tbuf = this.buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            int total = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            while (total < len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                int avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                    fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                    avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                int n = len - total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                if (n > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                    n = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                int tpos = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                int maxpos = tpos + n;
50413
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   484
                byte c = 0;
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   485
                // jar.spec.newline: CRLF | LF | CR (not followed by LF)
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   486
                while (tpos < maxpos && (c = tbuf[tpos++]) != '\n' && c != '\r');
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   487
                if (c == '\r' && tpos < maxpos && tbuf[tpos] == '\n') {
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   488
                    tpos++;
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   489
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                n = tpos - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                System.arraycopy(tbuf, pos, b, off, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                off += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                total += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                pos = tpos;
50433
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   495
                c = tbuf[tpos-1];
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   496
                if (c == '\n') {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   497
                    break;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   498
                }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   499
                if (c == '\r') {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   500
                    if (count == pos) {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   501
                        // try to see if there is a trailing LF
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   502
                        fill();
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   503
                        if (pos < count && tbuf[pos] == '\n') {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   504
                            if (total < len) {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   505
                                b[off++] = '\n';
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   506
                                total++;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   507
                            } else {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   508
                                // we should always have big enough lbuf but
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   509
                                // just in case we don't, replace the last CR
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   510
                                // with LF.
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   511
                                b[off - 1] = '\n';
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   512
                            }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   513
                            pos++;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   514
                        }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   515
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            return total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        public byte peek() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            if (pos == count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                fill();
12181
d7c6dd7a2bd5 7148584: Jar tools fails to generate manifest correctly when boundary condition hit
coffeys
parents: 11828
diff changeset
   525
            if (pos == count)
d7c6dd7a2bd5 7148584: Jar tools fails to generate manifest correctly when boundary condition hit
coffeys
parents: 11828
diff changeset
   526
                return -1; // nothing left in buffer
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            return buf[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        public int readLine(byte[] b) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            return readLine(b, 0, b.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        public long skip(long n) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            if (n <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            long avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                return in.skip(n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            if (n > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                n = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            pos += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        public int available() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            return (count - pos) + in.available();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        public void close() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if (in != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                in.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                in = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                buf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        private void fill() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            count = pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            int n = in.read(buf, 0, buf.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            if (n > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                count = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
}