src/java.base/share/classes/java/util/jar/Manifest.java
author weijun
Wed, 08 Aug 2018 08:05:43 +0800
changeset 52171 0da586f1ed05
parent 52159 42244a052fbb
child 53095 33a51275fee0
child 53291 8f822a19309b
permissions -rw-r--r--
8208754: The fix for JDK-8194534 needs updates Reviewed-by: alanb, igerasim, rhalade, mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
49111
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
     2
 * Copyright (c) 1997, 2018, 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
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * The Manifest class is used to maintain Manifest entry names and their
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * associated Attributes. There are main Manifest Attributes as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * per-entry Attributes. For information on the Manifest format, please
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * see the
45663
4a0cbf8f2474 8182023: some java.util.jar docs contain links to technotes
psandoz
parents: 27804
diff changeset
    43
 * <a href="{@docRoot}/../specs/jar/jar.html">
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * Manifest format specification</a>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * @author  David Connelly
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @see     Attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @since   1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
public class Manifest implements Cloneable {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    51
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // manifest main attributes
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    53
    private final Attributes attr = new Attributes();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    // manifest entries
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    56
    private final Map<String, Attributes> entries = new HashMap<>();
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    57
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    58
    // associated JarVerifier, not null when called by JarFile::getManifest.
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    59
    private final JarVerifier jv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    61
    // name of the corresponding jar archive if available.
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    62
    private final String jarFilename;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    63
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     * Constructs a new, empty Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public Manifest() {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    68
        jarFilename = null;
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    69
        jv = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * Constructs a new Manifest from the specified input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * @param is the input stream containing manifest data
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 12181
diff changeset
    76
     * @throws IOException if an I/O error has occurred
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    public Manifest(InputStream is) throws IOException {
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    79
        this(null, is, null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    /**
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    83
     * 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
    84
     *
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    85
     * @param is the input stream containing manifest data
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    86
     * @param jarFilename the name of the corresponding jar archive if available
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    87
     * @throws IOException if an I/O error has occured
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    88
     */
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    89
    Manifest(InputStream is, String jarFilename) throws IOException {
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    90
        this(null, is, jarFilename);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    91
    }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    92
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    93
    /**
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    94
     * Constructs a new Manifest from the specified input stream
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    95
     * and associates it with a JarVerifier.
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    96
     */
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
    97
    Manifest(JarVerifier jv, InputStream is, String jarFilename) throws IOException {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    98
        read(is);
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
    99
        this.jarFilename = jarFilename;
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   100
        this.jv = jv;
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   101
    }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   102
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   103
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * Constructs a new Manifest that is a copy of the specified Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * @param man the Manifest to copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    public Manifest(Manifest man) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        attr.putAll(man.getMainAttributes());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        entries.putAll(man.getEntries());
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   111
        jarFilename = null;
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   112
        jv = man.jv;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * Returns the main Attributes for the Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * @return the main Attributes for the Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    public Attributes getMainAttributes() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        return attr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * Returns a Map of the entries contained in this Manifest. Each entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * is represented by a String name (key) and associated Attributes (value).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * The Map permits the {@code null} key, but no entry with a null key is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * created by {@link #read}, nor is such an entry written by using {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * #write}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * @return a Map of the entries contained in this Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    public Map<String,Attributes> getEntries() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        return entries;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * Returns the Attributes for the specified entry name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * This method is defined as:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     *      return (Attributes)getEntries().get(name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * Though {@code null} is a valid {@code name}, when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * {@code getAttributes(null)} is invoked on a {@code Manifest}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * obtained from a jar file, {@code null} will be returned.  While jar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * files themselves do not allow {@code null}-named attributes, it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * possible to invoke {@link #getEntries} on a {@code Manifest}, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * on that result, invoke {@code put} with a null key and an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * arbitrary value.  Subsequent invocations of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * {@code getAttributes(null)} will return the just-{@code put}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * Note that this method does not return the manifest's main attributes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * see {@link #getMainAttributes}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * @param name entry name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * @return the Attributes for the specified entry name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    public Attributes getAttributes(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        return getEntries().get(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    /**
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   163
     * Returns the Attributes for the specified entry name, if trusted.
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   164
     *
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   165
     * @param name entry name
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   166
     * @return returns the same result as {@link #getAttributes(String)}
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   167
     * @throws SecurityException if the associated jar is signed but this entry
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   168
     *      has been modified after signing (i.e. the section in the manifest
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   169
     *      does not exist in SF files of all signers).
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   170
     */
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   171
    Attributes getTrustedAttributes(String name) {
52171
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   172
        // 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
   173
        // jv.isTrustedManifestEntry() isn't able to detect MANIFEST.MF change.
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   174
        // Users of this method should call SharedSecrets.javaUtilJarAccess()
0da586f1ed05 8208754: The fix for JDK-8194534 needs updates
weijun
parents: 52159
diff changeset
   175
        // .ensureInitialization() first.
52159
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   176
        Attributes result = getAttributes(name);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   177
        if (result != null && jv != null && ! jv.isTrustedManifestEntry(name)) {
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   178
            throw new SecurityException("Untrusted manifest entry: " + name);
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   179
        }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   180
        return result;
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   181
    }
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   182
42244a052fbb 8194534: Manifest better support
weijun
parents: 52040
diff changeset
   183
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * Clears the main Attributes as well as the entries in this Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        attr.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        entries.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * Writes the Manifest to the specified OutputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * Attributes.Name.MANIFEST_VERSION must be set in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * MainAttributes prior to invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * @param out the output stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @exception IOException if an I/O error has occurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * @see #getMainAttributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     */
27804
4659e70271c4 8066617: Suppress deprecation warnings in java.base module
darcy
parents: 25859
diff changeset
   200
    @SuppressWarnings("deprecation")
2
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
22078
bdec5d53e98c 8030851: Update code in java.util to use newer language features
psandoz
parents: 21278
diff changeset
   206
        for (Map.Entry<String, Attributes> e : entries.entrySet()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            StringBuffer buffer = new StringBuffer("Name: ");
11274
7e7196757acd 7117249: fix warnings in java.util.jar, .logging, .prefs, .zip
smarks
parents: 5506
diff changeset
   208
            String value = e.getKey();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            if (value != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                byte[] vb = value.getBytes("UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                value = new String(vb, 0, 0, vb.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            buffer.append(value);
49111
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   214
            make72Safe(buffer);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            buffer.append("\r\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            dos.writeBytes(buffer.toString());
11274
7e7196757acd 7117249: fix warnings in java.util.jar, .logging, .prefs, .zip
smarks
parents: 5506
diff changeset
   217
            e.getValue().write(dos);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        dos.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * Adds line breaks to enforce a maximum 72 bytes per line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    static void make72Safe(StringBuffer line) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        int length = line.length();
49111
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   227
        int index = 72;
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   228
        while (index < length) {
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   229
            line.insert(index, "\r\n ");
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   230
            index += 74; // + line width + line break ("\r\n")
1b33025ae610 6372077: JarFile.getManifest() should handle manifest attribute name 70 bytes
rriggs
parents: 47216
diff changeset
   231
            length += 3; // + line break ("\r\n") and space
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   236
    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
   237
        if (filename == null ||
d8aebcc2d3ac 8211860: Avoid reading security properties eagerly on Manifest class initialization
redestad
parents: 51879
diff changeset
   238
                !SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS) {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   239
            return "line " + lineNumber;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   240
        }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   241
        return "manifest of " + filename + ":" + lineNumber;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   242
    }
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   243
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * Reads the Manifest from the specified InputStream. The entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * names and attributes read will be merged in with the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * manifest entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * @param is the input stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * @exception IOException if an I/O error has occurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    public void read(InputStream is) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        // Buffered input stream for reading manifest data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        FastInputStream fis = new FastInputStream(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        // Line buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        byte[] lbuf = new byte[512];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        // Read the main attributes for the manifest
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   258
        int lineNumber = attr.read(fis, lbuf, jarFilename, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        // Total number of entries, attributes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        int ecount = 0, acount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        // Average size of entry attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        int asize = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        // Now parse the manifest entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        int len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        String name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        boolean skipEmptyLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        byte[] lastline = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        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
   270
            byte c = lbuf[--len];
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   271
            lineNumber++;
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   272
50413
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   273
            if (c != '\n' && c != '\r') {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   274
                throw new IOException("manifest line too long ("
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   275
                           + getErrorPosition(jarFilename, lineNumber) + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            if (len > 0 && lbuf[len-1] == '\r') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                --len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            if (len == 0 && skipEmptyLines) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            skipEmptyLines = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                name = parseName(lbuf, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                if (name == null) {
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   288
                    throw new IOException("invalid manifest format"
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   289
                              + getErrorPosition(jarFilename, lineNumber) + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                if (fis.peek() == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                    // name is wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                    lastline = new byte[len - 6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                    System.arraycopy(lbuf, 6, lastline, 0, len - 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                // continuation line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                byte[] buf = new byte[lastline.length + len - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                System.arraycopy(lastline, 0, buf, 0, lastline.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                if (fis.peek() == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                    // name is wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                    lastline = buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                name = new String(buf, 0, buf.length, "UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                lastline = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            Attributes attr = getAttributes(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            if (attr == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                attr = new Attributes(asize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                entries.put(name, attr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            }
51879
6ffa38b8da65 8207768: Improve exception messages during manifest parsing of jar archives
mbaesken
parents: 50433
diff changeset
   315
            lineNumber = attr.read(fis, lbuf, jarFilename, lineNumber);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            ecount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            acount += attr.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            //XXX: Fix for when the average is 0. When it is 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            // you get an Attributes object with an initial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            // capacity of 0, which tickles a bug in HashMap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            asize = Math.max(2, acount / ecount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            name = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            skipEmptyLines = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    private String parseName(byte[] lbuf, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        if (toLower(lbuf[0]) == 'n' && toLower(lbuf[1]) == 'a' &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            toLower(lbuf[2]) == 'm' && toLower(lbuf[3]) == 'e' &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            lbuf[4] == ':' && lbuf[5] == ' ') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                return new String(lbuf, 6, len - 6, "UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    private int toLower(int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        return (c >= 'A' && c <= 'Z') ? 'a' + (c - 'A') : c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * Returns true if the specified Object is also a Manifest and has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * the same main Attributes and entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * @param o the object to be compared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * @return true if the specified Object is also a Manifest and has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * the same main Attributes and entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    public boolean equals(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        if (o instanceof Manifest) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            Manifest m = (Manifest)o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            return attr.equals(m.getMainAttributes()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                   entries.equals(m.getEntries());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * Returns the hash code for this Manifest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        return attr.hashCode() + entries.hashCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * Returns a shallow copy of this Manifest.  The shallow copy is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * implemented as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     *     public Object clone() { return new Manifest(this); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * @return a shallow copy of this Manifest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    public Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        return new Manifest(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * A fast buffered input stream for parsing manifest files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    static class FastInputStream extends FilterInputStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        private byte buf[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        private int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        private int pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        FastInputStream(InputStream in) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            this(in, 8192);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        FastInputStream(InputStream in, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            super(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            buf = new byte[size];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        public int read() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            if (pos >= count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                if (pos >= count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            }
11828
590711df7828 7143629: JDK jar/zip code should use unsigned library support
darcy
parents: 11274
diff changeset
   406
            return Byte.toUnsignedInt(buf[pos++]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        public int read(byte[] b, int off, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            int avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                if (len >= buf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    return in.read(b, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            if (len > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                len = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            System.arraycopy(buf, pos, b, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            pos += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
         * Reads 'len' bytes from the input stream, or until an end-of-line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
         * is reached. Returns the number of bytes read.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        public int readLine(byte[] b, int off, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            byte[] tbuf = this.buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            int total = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            while (total < len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                int avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                    fill();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                    avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                    if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                int n = len - total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                if (n > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                    n = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                int tpos = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                int maxpos = tpos + n;
50413
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   451
                byte c = 0;
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   452
                // 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
   453
                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
   454
                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
   455
                    tpos++;
1234ff7199c7 8200530: '\r' is not supported as "newline" in java.util.jar.Manifest
sherman
parents: 49442
diff changeset
   456
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                n = tpos - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                System.arraycopy(tbuf, pos, b, off, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                off += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                total += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                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
   462
                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
   463
                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
   464
                    break;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   465
                }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   466
                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
   467
                    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
   468
                        // 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
   469
                        fill();
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   470
                        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
   471
                            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
   472
                                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
   473
                                total++;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   474
                            } else {
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   475
                                // 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
   476
                                // 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
   477
                                // 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
   478
                                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
   479
                            }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   480
                            pos++;
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   481
                        }
2bafeb7a1f6b 8204494: Fix for 8200530 triggered regression, closed/test/jdk/security/infra/java/security/KeyStore/BouncyCastleInterop.java failed
sherman
parents: 50413
diff changeset
   482
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            return total;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        public byte peek() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            if (pos == count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                fill();
12181
d7c6dd7a2bd5 7148584: Jar tools fails to generate manifest correctly when boundary condition hit
coffeys
parents: 11828
diff changeset
   492
            if (pos == count)
d7c6dd7a2bd5 7148584: Jar tools fails to generate manifest correctly when boundary condition hit
coffeys
parents: 11828
diff changeset
   493
                return -1; // nothing left in buffer
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            return buf[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        public int readLine(byte[] b) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            return readLine(b, 0, b.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        public long skip(long n) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            if (n <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            long avail = count - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            if (avail <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                return in.skip(n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            if (n > avail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                n = avail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            pos += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        public int available() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            return (count - pos) + in.available();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        public void close() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            if (in != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                in.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                in = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                buf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        private void fill() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            count = pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            int n = in.read(buf, 0, buf.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            if (n > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                count = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
}