/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. * * * This file incorporates work covered by the following copyright and * permission notice: * * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.naming; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import org.glassfish.grizzly.utils.Charsets; /** * Utility methods originally defined in org.apache.catalina.util.RequestUtil * and moved here in order to become accessible to code in web-naming and * war-util. */ public final class Util { /** * Normalize a relative URI path that may have relative values ("/./", * "/../", and so on ) it it. <strong>WARNING</strong> - This method is * useful only for normalizing application-generated paths. It does not * try to perform security checks for malicious input. * * @param path Relative path to be normalized * @param replaceBackSlash Should '\\' be replaced with '/' */ public static String normalize(String path, boolean replaceBackSlash) { if (path == null) return null; // Create a place for the normalized path String normalized = path; if (replaceBackSlash && normalized.indexOf('\\') >= 0) normalized = normalized.replace('\\', '/'); if (normalized.equals("/.")) return "/"; // Add a leading "/" if necessary if (!normalized.startsWith("/")) normalized = "/" + normalized; // Resolve occurrences of "//" in the normalized path while (true) { int index = normalized.indexOf("//"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 1); } // Resolve occurrences of "/./" in the normalized path while (true) { int index = normalized.indexOf("/./"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 2); } // Resolve occurrences of "/../" in the normalized path while (true) { int index = normalized.indexOf("/../"); if (index < 0) break; if (index == 0) return (null); // Trying to go outside our context int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); } // Return the normalized path that we have completed return (normalized); } /** * Decode and return the specified URL-encoded String. * When the byte array is converted to a string, the system default * character encoding is used... This may be different than some other * servers. * * @param str The url-encoded string * * @exception IllegalArgumentException if a '%' character is not followed * by a valid 2-digit hexadecimal number */ public static String urlDecode(String str) { return urlDecode(str, null); } /** * Decode and return the specified URL-encoded String. * * @param str The url-encoded string * @param enc The encoding to use; if null, the default encoding is used * @exception IllegalArgumentException if a '%' character is not followed * by a valid 2-digit hexadecimal number */ public static String urlDecode(String str, String enc) { if (str == null) return (null); // use the specified encoding to extract bytes out of the // given string so that the encoding is not lost. If an // encoding is not specified, let it use platform default byte[] bytes = null; try { if (enc == null) { bytes = str.getBytes(Charset.defaultCharset()); } else { bytes = str.getBytes(Charsets.lookupCharset(enc)); } } catch (UnsupportedCharsetException uee) {} return urlDecode(bytes, enc); } /** * Decode and return the specified URL-encoded byte array. * * @param bytes The url-encoded byte array * @exception IllegalArgumentException if a '%' character is not followed * by a valid 2-digit hexadecimal number */ public static String urlDecode(byte[] bytes) { return urlDecode(bytes, null); } /** * Decode and return the specified URL-encoded byte array. * * @param bytes The url-encoded byte array * @param enc The encoding to use; if null, the default encoding is used * @exception IllegalArgumentException if a '%' character is not followed * by a valid 2-digit hexadecimal number */ public static String urlDecode(byte[] bytes, String enc) { if (bytes == null) return (null); int len = bytes.length; int ix = 0; int ox = 0; while (ix < len) { byte b = bytes[ix++]; // Get byte to test if (b == '+') { b = (byte)' '; } else if (b == '%') { b = (byte) ((convertHexDigit(bytes[ix++]) << 4) + convertHexDigit(bytes[ix++])); } bytes[ox++] = b; } if (enc != null) { try { return new String(bytes, 0, ox, Charsets.lookupCharset(enc)); } catch (Exception e) { e.printStackTrace(); } } return new String(bytes, 0, ox, Charset.defaultCharset()); } /** * Convert a byte character value to hexidecimal digit value. * * @param b the character value byte */ public static byte convertHexDigit( byte b ) { if ((b >= '0') && (b <= '9')) return (byte)(b - '0'); if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); return 0; } }