SEC-2469: Support Spring LDAP 2.0.1+
This commit is contained in:
		
							parent
							
								
									058b9debef
								
							
						
					
					
						commit
						e17adad878
					
				| 
						 | 
				
			
			@ -27,12 +27,15 @@ allprojects {
 | 
			
		|||
    ext.snapshotBuild = version.endsWith('SNAPSHOT')
 | 
			
		||||
    ext.springVersion = '3.2.7.RELEASE'
 | 
			
		||||
    ext.spring4Version = '4.0.1.RELEASE'
 | 
			
		||||
    ext.springLdapVersion = '1.3.2.RELEASE'
 | 
			
		||||
    ext.springLdap2Version = '2.0.1.CI-SNAPSHOT'
 | 
			
		||||
 | 
			
		||||
    group = 'org.springframework.security'
 | 
			
		||||
 | 
			
		||||
    repositories {
 | 
			
		||||
       mavenCentral()
 | 
			
		||||
       maven { url "http://repo.springsource.org/plugins-release" }
 | 
			
		||||
       maven { url "https://repo.spring.io/libs-snapshot" }
 | 
			
		||||
       maven { url "https://repo.spring.io/plugins-release" }
 | 
			
		||||
       maven { url "http://repo.terracotta.org/maven2/" }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +120,9 @@ configure(coreModuleProjects) {
 | 
			
		|||
            if (details.requested.name == 'ehcache-terracotta') {
 | 
			
		||||
                details.useVersion '2.1.1'
 | 
			
		||||
            }
 | 
			
		||||
            if (details.requested.group == 'org.springframework.ldap') {
 | 
			
		||||
                details.useVersion springLdap2Version
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ apply plugin: 'propdeps-eclipse'
 | 
			
		|||
sourceCompatibility = 1.5
 | 
			
		||||
targetCompatibility = 1.5
 | 
			
		||||
 | 
			
		||||
ext.springLdapVersion = '1.3.2.RELEASE'
 | 
			
		||||
ext.ehcacheVersion = '1.6.2'
 | 
			
		||||
ext.aspectjVersion = '1.6.10'
 | 
			
		||||
ext.apacheDsVersion = '1.5.5'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,237 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2005-2010 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.springframework.security.ldap;
 | 
			
		||||
 | 
			
		||||
import org.springframework.ldap.BadLdapGrammarException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class to encode and decode ldap names and values.
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * NOTE: This is a copy from Spring LDAP so that both Spring LDAP 1.x and 2.x
 | 
			
		||||
 * can be supported without reflection.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Adam Skogman
 | 
			
		||||
 * @author Mattias Hellborg Arthursson
 | 
			
		||||
 */
 | 
			
		||||
final class LdapEncoder {
 | 
			
		||||
 | 
			
		||||
    private static final int HEX = 16;
 | 
			
		||||
    private static String[] NAME_ESCAPE_TABLE = new String[96];
 | 
			
		||||
 | 
			
		||||
    private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
 | 
			
		||||
        // Name encoding table -------------------------------------
 | 
			
		||||
 | 
			
		||||
        // all below 0x20 (control chars)
 | 
			
		||||
        for (char c = 0; c < ' '; c++) {
 | 
			
		||||
            NAME_ESCAPE_TABLE[c] = "\\" + toTwoCharHex(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NAME_ESCAPE_TABLE['#'] = "\\#";
 | 
			
		||||
        NAME_ESCAPE_TABLE[','] = "\\,";
 | 
			
		||||
        NAME_ESCAPE_TABLE[';'] = "\\;";
 | 
			
		||||
        NAME_ESCAPE_TABLE['='] = "\\=";
 | 
			
		||||
        NAME_ESCAPE_TABLE['+'] = "\\+";
 | 
			
		||||
        NAME_ESCAPE_TABLE['<'] = "\\<";
 | 
			
		||||
        NAME_ESCAPE_TABLE['>'] = "\\>";
 | 
			
		||||
        NAME_ESCAPE_TABLE['\"'] = "\\\"";
 | 
			
		||||
        NAME_ESCAPE_TABLE['\\'] = "\\\\";
 | 
			
		||||
 | 
			
		||||
        // Filter encoding table -------------------------------------
 | 
			
		||||
 | 
			
		||||
        // fill with char itself
 | 
			
		||||
        for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
 | 
			
		||||
            FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // escapes (RFC2254)
 | 
			
		||||
        FILTER_ESCAPE_TABLE['*'] = "\\2a";
 | 
			
		||||
        FILTER_ESCAPE_TABLE['('] = "\\28";
 | 
			
		||||
        FILTER_ESCAPE_TABLE[')'] = "\\29";
 | 
			
		||||
        FILTER_ESCAPE_TABLE['\\'] = "\\5c";
 | 
			
		||||
        FILTER_ESCAPE_TABLE[0] = "\\00";
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * All static methods - not to be instantiated.
 | 
			
		||||
     */
 | 
			
		||||
    private LdapEncoder() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static String toTwoCharHex(char c) {
 | 
			
		||||
 | 
			
		||||
        String raw = Integer.toHexString(c).toUpperCase();
 | 
			
		||||
 | 
			
		||||
        if (raw.length() > 1) {
 | 
			
		||||
            return raw;
 | 
			
		||||
        } else {
 | 
			
		||||
            return "0" + raw;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Escape a value for use in a filter.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the value to escape.
 | 
			
		||||
     * @return a properly escaped representation of the supplied value.
 | 
			
		||||
     */
 | 
			
		||||
    public static String filterEncode(String value) {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer roomy
 | 
			
		||||
        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
 | 
			
		||||
 | 
			
		||||
        int length = value.length();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
 | 
			
		||||
            char c = value.charAt(i);
 | 
			
		||||
 | 
			
		||||
            if (c < FILTER_ESCAPE_TABLE.length) {
 | 
			
		||||
                encodedValue.append(FILTER_ESCAPE_TABLE[c]);
 | 
			
		||||
            } else {
 | 
			
		||||
                // default: add the char
 | 
			
		||||
                encodedValue.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return encodedValue.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LDAP Encodes a value for use with a DN. Escapes for LDAP, not JNDI!
 | 
			
		||||
     * 
 | 
			
		||||
     * <br/>Escapes:<br/> ' ' [space] - "\ " [if first or last] <br/> '#'
 | 
			
		||||
     * [hash] - "\#" <br/> ',' [comma] - "\," <br/> ';' [semicolon] - "\;" <br/> '=
 | 
			
		||||
     * [equals] - "\=" <br/> '+' [plus] - "\+" <br/> '<' [less than] -
 | 
			
		||||
     * "\<" <br/> '>' [greater than] - "\>" <br/> '"' [double quote] -
 | 
			
		||||
     * "\"" <br/> '\' [backslash] - "\\" <br/>
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the value to escape.
 | 
			
		||||
     * @return The escaped value.
 | 
			
		||||
     */
 | 
			
		||||
    public static String nameEncode(String value) {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer roomy
 | 
			
		||||
        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
 | 
			
		||||
 | 
			
		||||
        int length = value.length();
 | 
			
		||||
        int last = length - 1;
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
 | 
			
		||||
            char c = value.charAt(i);
 | 
			
		||||
 | 
			
		||||
            // space first or last
 | 
			
		||||
            if (c == ' ' && (i == 0 || i == last)) {
 | 
			
		||||
                encodedValue.append("\\ ");
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (c < NAME_ESCAPE_TABLE.length) {
 | 
			
		||||
                // check in table for escapes
 | 
			
		||||
                String esc = NAME_ESCAPE_TABLE[c];
 | 
			
		||||
 | 
			
		||||
                if (esc != null) {
 | 
			
		||||
                    encodedValue.append(esc);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // default: add the char
 | 
			
		||||
            encodedValue.append(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return encodedValue.toString();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Decodes a value. Converts escaped chars to ordinary chars.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            Trimmed value, so no leading an trailing blanks, except an
 | 
			
		||||
     *            escaped space last.
 | 
			
		||||
     * @return The decoded value as a string.
 | 
			
		||||
     * @throws BadLdapGrammarException
 | 
			
		||||
     */
 | 
			
		||||
    static public String nameDecode(String value)
 | 
			
		||||
            throws BadLdapGrammarException {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer same size
 | 
			
		||||
        StringBuilder decoded = new StringBuilder(value.length());
 | 
			
		||||
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        while (i < value.length()) {
 | 
			
		||||
            char currentChar = value.charAt(i);
 | 
			
		||||
            if (currentChar == '\\') {
 | 
			
		||||
                if (value.length() <= i + 1) {
 | 
			
		||||
                    // Ending with a single backslash is not allowed
 | 
			
		||||
                    throw new BadLdapGrammarException(
 | 
			
		||||
                            "Unexpected end of value " + "unterminated '\\'");
 | 
			
		||||
                } else {
 | 
			
		||||
                    char nextChar = value.charAt(i + 1);
 | 
			
		||||
                    if (nextChar == ',' || nextChar == '=' || nextChar == '+'
 | 
			
		||||
                            || nextChar == '<' || nextChar == '>'
 | 
			
		||||
                            || nextChar == '#' || nextChar == ';'
 | 
			
		||||
                            || nextChar == '\\' || nextChar == '\"'
 | 
			
		||||
                            || nextChar == ' ') {
 | 
			
		||||
                        // Normal backslash escape
 | 
			
		||||
                        decoded.append(nextChar);
 | 
			
		||||
                        i += 2;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (value.length() <= i + 2) {
 | 
			
		||||
                            throw new BadLdapGrammarException(
 | 
			
		||||
                                    "Unexpected end of value "
 | 
			
		||||
                                            + "expected special or hex, found '"
 | 
			
		||||
                                            + nextChar + "'");
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // This should be a hex value
 | 
			
		||||
                            String hexString = "" + nextChar
 | 
			
		||||
                                    + value.charAt(i + 2);
 | 
			
		||||
                            decoded.append((char) Integer.parseInt(hexString,
 | 
			
		||||
                                    HEX));
 | 
			
		||||
                            i += 3;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // This character wasn't escaped - just append it
 | 
			
		||||
                decoded.append(currentChar);
 | 
			
		||||
                i++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return decoded.toString();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,6 @@ import org.springframework.ldap.core.ContextSource;
 | 
			
		|||
import org.springframework.ldap.core.DirContextAdapter;
 | 
			
		||||
import org.springframework.ldap.core.DirContextOperations;
 | 
			
		||||
import org.springframework.ldap.core.DistinguishedName;
 | 
			
		||||
import org.springframework.ldap.core.LdapEncoder;
 | 
			
		||||
import org.springframework.ldap.core.LdapTemplate;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,6 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.security.ldap.authentication;
 | 
			
		||||
 | 
			
		||||
import org.springframework.ldap.core.LdapEncoder;
 | 
			
		||||
import org.springframework.security.core.SpringSecurityMessageSource;
 | 
			
		||||
import org.springframework.security.ldap.search.LdapUserSearch;
 | 
			
		||||
import org.springframework.beans.factory.InitializingBean;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,237 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2005-2010 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.springframework.security.ldap.authentication;
 | 
			
		||||
 | 
			
		||||
import org.springframework.ldap.BadLdapGrammarException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class to encode and decode ldap names and values.
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>
 | 
			
		||||
 * NOTE: This is a copy from Spring LDAP so that both Spring LDAP 1.x and 2.x
 | 
			
		||||
 * can be supported without reflection.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Adam Skogman
 | 
			
		||||
 * @author Mattias Hellborg Arthursson
 | 
			
		||||
 */
 | 
			
		||||
final class LdapEncoder {
 | 
			
		||||
 | 
			
		||||
    private static final int HEX = 16;
 | 
			
		||||
    private static String[] NAME_ESCAPE_TABLE = new String[96];
 | 
			
		||||
 | 
			
		||||
    private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
 | 
			
		||||
        // Name encoding table -------------------------------------
 | 
			
		||||
 | 
			
		||||
        // all below 0x20 (control chars)
 | 
			
		||||
        for (char c = 0; c < ' '; c++) {
 | 
			
		||||
            NAME_ESCAPE_TABLE[c] = "\\" + toTwoCharHex(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NAME_ESCAPE_TABLE['#'] = "\\#";
 | 
			
		||||
        NAME_ESCAPE_TABLE[','] = "\\,";
 | 
			
		||||
        NAME_ESCAPE_TABLE[';'] = "\\;";
 | 
			
		||||
        NAME_ESCAPE_TABLE['='] = "\\=";
 | 
			
		||||
        NAME_ESCAPE_TABLE['+'] = "\\+";
 | 
			
		||||
        NAME_ESCAPE_TABLE['<'] = "\\<";
 | 
			
		||||
        NAME_ESCAPE_TABLE['>'] = "\\>";
 | 
			
		||||
        NAME_ESCAPE_TABLE['\"'] = "\\\"";
 | 
			
		||||
        NAME_ESCAPE_TABLE['\\'] = "\\\\";
 | 
			
		||||
 | 
			
		||||
        // Filter encoding table -------------------------------------
 | 
			
		||||
 | 
			
		||||
        // fill with char itself
 | 
			
		||||
        for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
 | 
			
		||||
            FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // escapes (RFC2254)
 | 
			
		||||
        FILTER_ESCAPE_TABLE['*'] = "\\2a";
 | 
			
		||||
        FILTER_ESCAPE_TABLE['('] = "\\28";
 | 
			
		||||
        FILTER_ESCAPE_TABLE[')'] = "\\29";
 | 
			
		||||
        FILTER_ESCAPE_TABLE['\\'] = "\\5c";
 | 
			
		||||
        FILTER_ESCAPE_TABLE[0] = "\\00";
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * All static methods - not to be instantiated.
 | 
			
		||||
     */
 | 
			
		||||
    private LdapEncoder() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static String toTwoCharHex(char c) {
 | 
			
		||||
 | 
			
		||||
        String raw = Integer.toHexString(c).toUpperCase();
 | 
			
		||||
 | 
			
		||||
        if (raw.length() > 1) {
 | 
			
		||||
            return raw;
 | 
			
		||||
        } else {
 | 
			
		||||
            return "0" + raw;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Escape a value for use in a filter.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the value to escape.
 | 
			
		||||
     * @return a properly escaped representation of the supplied value.
 | 
			
		||||
     */
 | 
			
		||||
    public static String filterEncode(String value) {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer roomy
 | 
			
		||||
        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
 | 
			
		||||
 | 
			
		||||
        int length = value.length();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
 | 
			
		||||
            char c = value.charAt(i);
 | 
			
		||||
 | 
			
		||||
            if (c < FILTER_ESCAPE_TABLE.length) {
 | 
			
		||||
                encodedValue.append(FILTER_ESCAPE_TABLE[c]);
 | 
			
		||||
            } else {
 | 
			
		||||
                // default: add the char
 | 
			
		||||
                encodedValue.append(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return encodedValue.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LDAP Encodes a value for use with a DN. Escapes for LDAP, not JNDI!
 | 
			
		||||
     * 
 | 
			
		||||
     * <br/>Escapes:<br/> ' ' [space] - "\ " [if first or last] <br/> '#'
 | 
			
		||||
     * [hash] - "\#" <br/> ',' [comma] - "\," <br/> ';' [semicolon] - "\;" <br/> '=
 | 
			
		||||
     * [equals] - "\=" <br/> '+' [plus] - "\+" <br/> '<' [less than] -
 | 
			
		||||
     * "\<" <br/> '>' [greater than] - "\>" <br/> '"' [double quote] -
 | 
			
		||||
     * "\"" <br/> '\' [backslash] - "\\" <br/>
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the value to escape.
 | 
			
		||||
     * @return The escaped value.
 | 
			
		||||
     */
 | 
			
		||||
    public static String nameEncode(String value) {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer roomy
 | 
			
		||||
        StringBuilder encodedValue = new StringBuilder(value.length() * 2);
 | 
			
		||||
 | 
			
		||||
        int length = value.length();
 | 
			
		||||
        int last = length - 1;
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
 | 
			
		||||
            char c = value.charAt(i);
 | 
			
		||||
 | 
			
		||||
            // space first or last
 | 
			
		||||
            if (c == ' ' && (i == 0 || i == last)) {
 | 
			
		||||
                encodedValue.append("\\ ");
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (c < NAME_ESCAPE_TABLE.length) {
 | 
			
		||||
                // check in table for escapes
 | 
			
		||||
                String esc = NAME_ESCAPE_TABLE[c];
 | 
			
		||||
 | 
			
		||||
                if (esc != null) {
 | 
			
		||||
                    encodedValue.append(esc);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // default: add the char
 | 
			
		||||
            encodedValue.append(c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return encodedValue.toString();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Decodes a value. Converts escaped chars to ordinary chars.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            Trimmed value, so no leading an trailing blanks, except an
 | 
			
		||||
     *            escaped space last.
 | 
			
		||||
     * @return The decoded value as a string.
 | 
			
		||||
     * @throws BadLdapGrammarException
 | 
			
		||||
     */
 | 
			
		||||
    static public String nameDecode(String value)
 | 
			
		||||
            throws BadLdapGrammarException {
 | 
			
		||||
 | 
			
		||||
        if (value == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        // make buffer same size
 | 
			
		||||
        StringBuilder decoded = new StringBuilder(value.length());
 | 
			
		||||
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        while (i < value.length()) {
 | 
			
		||||
            char currentChar = value.charAt(i);
 | 
			
		||||
            if (currentChar == '\\') {
 | 
			
		||||
                if (value.length() <= i + 1) {
 | 
			
		||||
                    // Ending with a single backslash is not allowed
 | 
			
		||||
                    throw new BadLdapGrammarException(
 | 
			
		||||
                            "Unexpected end of value " + "unterminated '\\'");
 | 
			
		||||
                } else {
 | 
			
		||||
                    char nextChar = value.charAt(i + 1);
 | 
			
		||||
                    if (nextChar == ',' || nextChar == '=' || nextChar == '+'
 | 
			
		||||
                            || nextChar == '<' || nextChar == '>'
 | 
			
		||||
                            || nextChar == '#' || nextChar == ';'
 | 
			
		||||
                            || nextChar == '\\' || nextChar == '\"'
 | 
			
		||||
                            || nextChar == ' ') {
 | 
			
		||||
                        // Normal backslash escape
 | 
			
		||||
                        decoded.append(nextChar);
 | 
			
		||||
                        i += 2;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (value.length() <= i + 2) {
 | 
			
		||||
                            throw new BadLdapGrammarException(
 | 
			
		||||
                                    "Unexpected end of value "
 | 
			
		||||
                                            + "expected special or hex, found '"
 | 
			
		||||
                                            + nextChar + "'");
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // This should be a hex value
 | 
			
		||||
                            String hexString = "" + nextChar
 | 
			
		||||
                                    + value.charAt(i + 2);
 | 
			
		||||
                            decoded.append((char) Integer.parseInt(hexString,
 | 
			
		||||
                                    HEX));
 | 
			
		||||
                            i += 3;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // This character wasn't escaped - just append it
 | 
			
		||||
                decoded.append(currentChar);
 | 
			
		||||
                i++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return decoded.toString();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue