< prev index next >

src/java.base/share/classes/java/util/jar/Manifest.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.jar;
  27 
  28 import java.io.DataOutputStream;
  29 import java.io.FilterInputStream;
  30 import java.io.IOException;
  31 import java.io.InputStream;
  32 import java.io.OutputStream;

  33 import java.util.HashMap;
  34 import java.util.Map;
  35 
  36 import sun.nio.cs.UTF_8;
  37 import sun.security.util.SecurityProperties;
  38 
  39 /**
  40  * The Manifest class is used to maintain Manifest entry names and their
  41  * associated Attributes. There are main Manifest Attributes as well as
  42  * per-entry Attributes. For information on the Manifest format, please
  43  * see the
  44  * <a href="{@docRoot}/../specs/jar/jar.html">
  45  * Manifest format specification</a>.
  46  *
  47  * @author  David Connelly
  48  * @see     Attributes
  49  * @since   1.2
  50  */
  51 public class Manifest implements Cloneable {
  52 


 213         dos.flush();
 214     }
 215 
 216     /**
 217      * Adds line breaks to enforce a maximum of 72 bytes per line.
 218      *
 219      * @deprecation Replaced with {@link #println72}.
 220      */
 221     @Deprecated(since = "13")
 222     static void make72Safe(StringBuffer line) {
 223         int length = line.length();
 224         int index = 72;
 225         while (index < length) {
 226             line.insert(index, "\r\n ");
 227             index += 74; // + line width + line break ("\r\n")
 228             length += 3; // + line break ("\r\n") and space
 229         }
 230     }
 231 
 232     /**














 233      * Writes {@code line} to {@code out} with line breaks and continuation
 234      * spaces within the limits of 72 bytes of contents per line followed
 235      * by a line break.













 236      */
 237     static void println72(OutputStream out, String line) throws IOException {
 238         if (!line.isEmpty()) {
 239             byte[] lineBytes = line.getBytes(UTF_8.INSTANCE);
 240             int length = lineBytes.length;
 241             // first line can hold one byte more than subsequent lines which
 242             // start with a continuation line break space
 243             out.write(lineBytes[0]);
 244             int pos = 1;
 245             while (length - pos > 71) {
 246                 out.write(lineBytes, pos, 71);
 247                 pos += 71;



















 248                 println(out);
 249                 out.write(' ');

 250             }
 251             out.write(lineBytes, pos, length - pos);


 252         }
 253         println(out);
 254     }
 255 
 256     /**
 257      * Writes a line break to {@code out}.
 258      */
 259     static void println(OutputStream out) throws IOException {
 260         out.write('\r');
 261         out.write('\n');
 262     }
 263 
 264     static String getErrorPosition(String filename, final int lineNumber) {
 265         if (filename == null ||
 266                 !SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS) {
 267             return "line " + lineNumber;
 268         }
 269         return "manifest of " + filename + ":" + lineNumber;
 270     }
 271 


   1 /*
   2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.jar;
  27 
  28 import java.io.DataOutputStream;
  29 import java.io.FilterInputStream;
  30 import java.io.IOException;
  31 import java.io.InputStream;
  32 import java.io.OutputStream;
  33 import java.text.BreakIterator;
  34 import java.util.HashMap;
  35 import java.util.Map;
  36 
  37 import sun.nio.cs.UTF_8;
  38 import sun.security.util.SecurityProperties;
  39 
  40 /**
  41  * The Manifest class is used to maintain Manifest entry names and their
  42  * associated Attributes. There are main Manifest Attributes as well as
  43  * per-entry Attributes. For information on the Manifest format, please
  44  * see the
  45  * <a href="{@docRoot}/../specs/jar/jar.html">
  46  * Manifest format specification</a>.
  47  *
  48  * @author  David Connelly
  49  * @see     Attributes
  50  * @since   1.2
  51  */
  52 public class Manifest implements Cloneable {
  53 


 214         dos.flush();
 215     }
 216 
 217     /**
 218      * Adds line breaks to enforce a maximum of 72 bytes per line.
 219      *
 220      * @deprecation Replaced with {@link #println72}.
 221      */
 222     @Deprecated(since = "13")
 223     static void make72Safe(StringBuffer line) {
 224         int length = line.length();
 225         int index = 72;
 226         while (index < length) {
 227             line.insert(index, "\r\n ");
 228             index += 74; // + line width + line break ("\r\n")
 229             length += 3; // + line break ("\r\n") and space
 230         }
 231     }
 232 
 233     /**
 234      * Returns {@code true} if the passed byte as parameter {@code b}
 235      * is not the first (or only) byte of a Unicode character encoded in UTF-8
 236      * and {@code false} otherwise.
 237      *
 238      * @see <a href="https://tools.ietf.org/html/rfc3629#section-3">
 239      * RFC 3629 - UTF-8, a transformation format of ISO 10646</a>
 240      * @see StringCoding#isNotContinuation(int)
 241      * @see sun.nio.cs.UTF_8.Decoder#isNotContinuation(int)
 242      */
 243     private static boolean isContinuation(byte b) {
 244         return (b & 0xc0) == 0x80;
 245     }
 246 
 247     /**
 248      * Writes {@code line} to {@code out} with line breaks and continuation
 249      * spaces within the limits of 72 bytes of contents per line
 250      * keeping byte sequences of characters encoded in UTF-8 together
 251      * also if the same character is encoded with more than one byte or
 252      * consists of a character sequence containing combining diacritical marks
 253      * followed by a line break.
 254      * <p>
 255      * Combining diacritical marks may be separated from the associated base
 256      * character or other combining diacritical marks of that base character
 257      * by a continuation line break ("{@code \r\n }") if the whole sequence of
 258      * base character and all the combining diacritical marks belonging to it
 259      * exceed 71 bytes in their binary form encoded with UTF-8. This limit is
 260      * only 71 bytes rather than 72 because continuation lines start with a
 261      * space that uses the first byte of the 72 bytes each line can hold up to
 262      * and the first line provides even less space for the value because it
 263      * starts with the name.
 264      */
 265     static void println72(OutputStream out, String line) throws IOException {
 266         int linePos = 0; // number of bytes already put out on current line
 267         BreakIterator boundary = BreakIterator.getCharacterInstance();
 268         boundary.setText(line);
 269         int start = boundary.first(), end;
 270         while ((end = boundary.next()) != BreakIterator.DONE) {
 271             String character = line.substring(start, end);
 272             start = end;
 273             byte[] characterBytes = character.getBytes(UTF_8.INSTANCE);
 274             int characterLength = characterBytes.length;
 275             // Put out a break onto a new line if the character does not fit on
 276             // the current line anymore but fits on a whole new line.
 277             // In other words, if the current character does not fit on one
 278             // whole line alone, fill the current line first before breaking
 279             // inside of the character onto a new line.
 280             if (linePos + characterLength > 72 && characterLength < 72) {
 281                 println(out);
 282                 out.write(' ');
 283                 linePos = 1;
 284             }
 285             int characterPos = 0; // number of bytes of current character
 286                                   // already put out
 287             while (linePos + characterLength - characterPos > 72) {
 288                 int nextBreakPos = 72 - linePos;
 289                 while (isContinuation(
 290                         characterBytes[characterPos + nextBreakPos])) {
 291                     nextBreakPos--;
 292                 }
 293                 out.write(characterBytes, characterPos, nextBreakPos);
 294                 characterPos += nextBreakPos;
 295                 println(out);
 296                 out.write(' ');
 297                 linePos = 1;
 298             }
 299             out.write(characterBytes,
 300                     characterPos, characterLength - characterPos);
 301             linePos += characterLength - characterPos;
 302         }
 303         println(out);
 304     }
 305 
 306     /**
 307      * Writes a line break to {@code out}.
 308      */
 309     static void println(OutputStream out) throws IOException {
 310         out.write('\r');
 311         out.write('\n');
 312     }
 313 
 314     static String getErrorPosition(String filename, final int lineNumber) {
 315         if (filename == null ||
 316                 !SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS) {
 317             return "line " + lineNumber;
 318         }
 319         return "manifest of " + filename + ":" + lineNumber;
 320     }
 321 


< prev index next >