1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.commons.compress.archivers.zip; 20 21 import java.nio.ByteBuffer; 22 import java.nio.charset.Charset; 23 import java.nio.charset.StandardCharsets; 24 import java.nio.charset.UnsupportedCharsetException; 25 26 /** 27 * Static helper functions for robustly encoding filenames in zip files. 28 */ 29 public abstract class ZipEncodingHelper { 30 31 32 /** 33 * name of the encoding UTF-8 34 */ 35 static final String UTF8 = "UTF8"; 36 37 /** 38 * the encoding UTF-8 39 */ 40 static final ZipEncoding UTF8_ZIP_ENCODING = getZipEncoding(UTF8); 41 42 /** 43 * Instantiates a zip encoding. An NIO based character set encoder/decoder will be returned. 44 * As a special case, if the character set is UTF-8, the nio encoder will be configured replace malformed and 45 * unmappable characters with '?'. This matches existing behavior from the older fallback encoder. 46 * <p> 47 * If the requested characer set cannot be found, the platform default will 48 * be used instead. 49 * </p> 50 * @param name The name of the zip encoding. Specify {@code null} for 51 * the platform's default encoding. 52 * @return A zip encoding for the given encoding name. 53 */ getZipEncoding(final String name)54 public static ZipEncoding getZipEncoding(final String name) { 55 Charset cs = Charset.defaultCharset(); 56 if (name != null) { 57 try { 58 cs = Charset.forName(name); 59 } catch (UnsupportedCharsetException e) { // NOSONAR we use the default encoding instead 60 } 61 } 62 boolean useReplacement = isUTF8(cs.name()); 63 return new NioZipEncoding(cs, useReplacement); 64 } 65 66 /** 67 * Returns whether a given encoding is UTF-8. If the given name is null, then check the platform's default encoding. 68 * 69 * @param charsetName If the given name is null, then check the platform's default encoding. 70 */ isUTF8(String charsetName)71 static boolean isUTF8(String charsetName) { 72 if (charsetName == null) { 73 // check platform's default encoding 74 charsetName = Charset.defaultCharset().name(); 75 } 76 if (StandardCharsets.UTF_8.name().equalsIgnoreCase(charsetName)) { 77 return true; 78 } 79 for (final String alias : StandardCharsets.UTF_8.aliases()) { 80 if (alias.equalsIgnoreCase(charsetName)) { 81 return true; 82 } 83 } 84 return false; 85 } 86 growBufferBy(ByteBuffer buffer, int increment)87 static ByteBuffer growBufferBy(ByteBuffer buffer, int increment) { 88 buffer.limit(buffer.position()); 89 buffer.rewind(); 90 91 final ByteBuffer on = ByteBuffer.allocate(buffer.capacity() + increment); 92 93 on.put(buffer); 94 return on; 95 } 96 } 97