001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018 019package org.apache.commons.compress.archivers.zip; 020 021import java.nio.ByteBuffer; 022import java.nio.charset.Charset; 023import java.nio.charset.StandardCharsets; 024import java.nio.charset.UnsupportedCharsetException; 025 026/** 027 * Static helper functions for robustly encoding filenames in zip files. 028 */ 029public abstract class ZipEncodingHelper { 030 031 032 /** 033 * name of the encoding UTF-8 034 */ 035 static final String UTF8 = "UTF8"; 036 037 /** 038 * the encoding UTF-8 039 */ 040 static final ZipEncoding UTF8_ZIP_ENCODING = getZipEncoding(UTF8); 041 042 /** 043 * Instantiates a zip encoding. An NIO based character set encoder/decoder will be returned. 044 * As a special case, if the character set is UTF-8, the nio encoder will be configured replace malformed and 045 * unmappable characters with '?'. This matches existing behavior from the older fallback encoder. 046 * <p> 047 * If the requested characer set cannot be found, the platform default will 048 * be used instead. 049 * </p> 050 * @param name The name of the zip encoding. Specify {@code null} for 051 * the platform's default encoding. 052 * @return A zip encoding for the given encoding name. 053 */ 054 public static ZipEncoding getZipEncoding(final String name) { 055 Charset cs = Charset.defaultCharset(); 056 if (name != null) { 057 try { 058 cs = Charset.forName(name); 059 } catch (UnsupportedCharsetException e) { // NOSONAR we use the default encoding instead 060 } 061 } 062 boolean useReplacement = isUTF8(cs.name()); 063 return new NioZipEncoding(cs, useReplacement); 064 } 065 066 /** 067 * Returns whether a given encoding is UTF-8. If the given name is null, then check the platform's default encoding. 068 * 069 * @param charsetName If the given name is null, then check the platform's default encoding. 070 */ 071 static boolean isUTF8(String charsetName) { 072 if (charsetName == null) { 073 // check platform's default encoding 074 charsetName = Charset.defaultCharset().name(); 075 } 076 if (StandardCharsets.UTF_8.name().equalsIgnoreCase(charsetName)) { 077 return true; 078 } 079 for (final String alias : StandardCharsets.UTF_8.aliases()) { 080 if (alias.equalsIgnoreCase(charsetName)) { 081 return true; 082 } 083 } 084 return false; 085 } 086 087 static ByteBuffer growBufferBy(ByteBuffer buffer, int increment) { 088 buffer.limit(buffer.position()); 089 buffer.rewind(); 090 091 final ByteBuffer on = ByteBuffer.allocate(buffer.capacity() + increment); 092 093 on.put(buffer); 094 return on; 095 } 096}