You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/08/06 17:58:38 UTC
svn commit: r429140 - in /directory/branches/shared/0.9.5/ldap/src:
main/java/org/apache/directory/shared/ldap/name/
main/java/org/apache/directory/shared/ldap/util/
test/java/org/apache/directory/shared/ldap/util/
Author: akarasulu
Date: Sun Aug 6 08:58:38 2006
New Revision: 429140
URL: http://svn.apache.org/viewvc?rev=429140&view=rev
Log:
fix for DIRSERVER-638: escaped hex and BER encoded hex in DN values
Added:
directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/DefaultStringNormalizer.java
directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ByteBuffer.java
directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/ByteBufferTest.java
Modified:
directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java
Added: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/DefaultStringNormalizer.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/DefaultStringNormalizer.java?rev=429140&view=auto
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/DefaultStringNormalizer.java (added)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/DefaultStringNormalizer.java Sun Aug 6 08:58:38 2006
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2006 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.directory.shared.ldap.name;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.schema.Normalizer;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+
+/**
+ * A normalizer which transforms an escape sequence into an internal
+ * canonical form: into UTF-8 characters presuming the escape sequence
+ * fits that range. This is used explicity for non-binary attribute
+ * types only.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class DefaultStringNormalizer implements Normalizer
+{
+ private static final DefaultStringNormalizer NORMALIZER = new DefaultStringNormalizer();
+
+ public Object normalize( Object value ) throws NamingException
+ {
+ String str = ( String ) value;
+
+ if ( str == null || str.length() == 0 )
+ {
+ return str;
+ }
+
+ if ( str.charAt( 0 ) == '#' )
+ {
+ return StringTools.decodeHexString( str );
+ }
+
+ if ( str.indexOf( '\\' ) != -1 )
+ {
+ return StringTools.decodeEscapedHex( str );
+ }
+
+ return str;
+ }
+
+ public static Object normalizeString( String string ) throws NamingException
+ {
+ return NORMALIZER.normalize( string );
+ }
+}
Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java?rev=429140&r1=429139&r2=429140&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java Sun Aug 6 08:58:38 2006
@@ -1315,11 +1315,15 @@
if ( oidNormalizer != null )
{
+ // Alex asks: Why clone here when we do not use the cloned copy?
Rdn rdnCopy = ( Rdn ) rdn.clone();
rdn.clear();
+ Object value = rdnCopy.getValue();
+ value = DefaultStringNormalizer.normalizeString( ( String ) value );
- rdn.addAttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(), ( String ) oidNormalizer.getNormalizer()
- .normalize( rdnCopy.getValue() ) );
+ rdn.addAttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(),
+ ( String ) oidNormalizer.getNormalizer()
+ .normalize( value ) );
}
else
Added: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ByteBuffer.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ByteBuffer.java?rev=429140&view=auto
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ByteBuffer.java (added)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/ByteBuffer.java Sun Aug 6 08:58:38 2006
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2002-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.directory.shared.ldap.util;
+
+
+/**
+ * A dynamically growing byte[].
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ByteBuffer
+{
+ /** the default initial buffer size */
+ private static final int DEFAULT_INITIAL_SIZE = 10;
+
+ /** the initial size of the buffer in number of bytes: also increment for allocations */
+ private final int initialSize;
+ /** the position into the buffer */
+ private int pos = 0;
+ /** the bytes of the buffer */
+ private byte[] buf;
+
+
+ public ByteBuffer()
+ {
+ this ( DEFAULT_INITIAL_SIZE );
+ }
+
+
+ public ByteBuffer( int initialSize )
+ {
+ if ( initialSize <= 0 )
+ {
+ throw new IllegalArgumentException( "initialSize must be greater than zero" );
+ }
+ this.initialSize = initialSize;
+ this.buf = new byte[initialSize];
+ }
+
+
+ public final void clear()
+ {
+ pos = 0;
+ }
+
+
+ public final int position()
+ {
+ return pos;
+ }
+
+
+ public final int capacity()
+ {
+ return buf.length;
+ }
+
+
+ public final byte get( int ii )
+ {
+ return buf[ii];
+ }
+
+
+ /**
+ * Get's the bytes, the backing store for this buffer. Note
+ * that you need to use the position index to determine where
+ * to stop reading from this buffer.
+ */
+ public final byte[] buffer()
+ {
+ return buf;
+ }
+
+
+ /**
+ * Get's a copy of the bytes used.
+ */
+ public final byte[] copyOfUsedBytes()
+ {
+ byte[] copy = new byte[pos];
+ System.arraycopy( buf, 0, copy, 0, pos+1 );
+ return copy;
+ }
+
+
+ /**
+ * Appends a byte to this buffer.
+ */
+ public final void append( byte bite )
+ {
+ if ( pos >= buf.length )
+ {
+ growBuffer();
+ }
+
+ buf[pos] = bite;
+ pos++;
+ }
+
+
+ /**
+ * Appends an int to this buffer. WARNING: the int is truncated to
+ * a byte value.
+ */
+ public final void append( int val )
+ {
+ if ( pos >= buf.length )
+ {
+ growBuffer();
+ }
+
+ buf[pos] = ( byte ) val;
+ pos++;
+ }
+
+
+ private final void growBuffer()
+ {
+ byte[] copy = new byte[buf.length+initialSize];
+ System.arraycopy( buf, 0, copy, 0, pos );
+ this.buf = copy;
+ }
+}
Modified: directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java?rev=429140&r1=429139&r2=429140&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/main/java/org/apache/directory/shared/ldap/util/StringTools.java Sun Aug 6 08:58:38 2006
@@ -30,6 +30,8 @@
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import javax.naming.InvalidNameException;
+
/**
* Various string manipulation methods that are more efficient then chaining
@@ -53,27 +55,27 @@
private static final byte[] HEX_CHAR = new byte[]
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- private static int UTF8_MULTI_BYTES_MASK = 0x0080;
+ private static final int UTF8_MULTI_BYTES_MASK = 0x0080;
- private static int UTF8_TWO_BYTES_MASK = 0x00E0;
+ private static final int UTF8_TWO_BYTES_MASK = 0x00E0;
- private static int UTF8_TWO_BYTES = 0x00C0;
+ private static final int UTF8_TWO_BYTES = 0x00C0;
- private static int UTF8_THREE_BYTES_MASK = 0x00F0;
+ private static final int UTF8_THREE_BYTES_MASK = 0x00F0;
- private static int UTF8_THREE_BYTES = 0x00E0;
+ private static final int UTF8_THREE_BYTES = 0x00E0;
- private static int UTF8_FOUR_BYTES_MASK = 0x00F8;
+ private static final int UTF8_FOUR_BYTES_MASK = 0x00F8;
- private static int UTF8_FOUR_BYTES = 0x00F0;
+ private static final int UTF8_FOUR_BYTES = 0x00F0;
- private static int UTF8_FIVE_BYTES_MASK = 0x00FC;
+ private static final int UTF8_FIVE_BYTES_MASK = 0x00FC;
- private static int UTF8_FIVE_BYTES = 0x00F8;
+ private static final int UTF8_FIVE_BYTES = 0x00F8;
- private static int UTF8_SIX_BYTES_MASK = 0x00FE;
+ private static final int UTF8_SIX_BYTES_MASK = 0x00FE;
- private static int UTF8_SIX_BYTES = 0x00FC;
+ private static final int UTF8_SIX_BYTES = 0x00FC;
/** <alpha> ::= [0x41-0x5A] | [0x61-0x7A] */
public static final boolean[] ALPHA =
@@ -199,17 +201,17 @@
0, 0, 0, 0, 0, 0, 0, 0
};
- private static int CHAR_ONE_BYTE_MASK = 0xFFFFFF80;
+ private static final int CHAR_ONE_BYTE_MASK = 0xFFFFFF80;
- private static int CHAR_TWO_BYTES_MASK = 0xFFFFF800;
+ private static final int CHAR_TWO_BYTES_MASK = 0xFFFFF800;
- private static int CHAR_THREE_BYTES_MASK = 0xFFFF0000;
+ private static final int CHAR_THREE_BYTES_MASK = 0xFFFF0000;
- private static int CHAR_FOUR_BYTES_MASK = 0xFFE00000;
+ private static final int CHAR_FOUR_BYTES_MASK = 0xFFE00000;
- private static int CHAR_FIVE_BYTES_MASK = 0xFC000000;
+ private static final int CHAR_FIVE_BYTES_MASK = 0xFC000000;
- private static int CHAR_SIX_BYTES_MASK = 0x80000000;
+ private static final int CHAR_SIX_BYTES_MASK = 0x80000000;
public static final int NOT_EQUAL = -1;
@@ -237,7 +239,7 @@
* the character to trim down
* @return the newly trimmed down string
*/
- public static String trimConsecutiveToOne( String str, char ch )
+ public static final String trimConsecutiveToOne( String str, char ch )
{
if ( ( null == str ) || ( str.length() == 0 ) )
{
@@ -287,7 +289,7 @@
* the string to deep trim.
* @return the trimmed string.
*/
- public static String deepTrim( String string )
+ public static final String deepTrim( String string )
{
return deepTrim( string, false );
}
@@ -301,7 +303,7 @@
*
* @see StringTools#deepTrim( String )
*/
- public static String deepTrimToLower( String string )
+ public static final String deepTrimToLower( String string )
{
return deepTrim( string, true );
}
@@ -319,7 +321,7 @@
*
* @TODO Replace the toCharArray() by substrig manipulations
*/
- public static String deepTrim( String str, boolean toLowerCase )
+ public static final String deepTrim( String str, boolean toLowerCase )
{
if ( ( null == str ) || ( str.length() == 0 ) )
{
@@ -396,7 +398,7 @@
* the amount of the tail to display
* @return the center truncated string
*/
- public static String centerTrunc( String str, int head, int tail )
+ public static final String centerTrunc( String str, int head, int tail )
{
StringBuffer buf = null;
@@ -424,7 +426,7 @@
* the byte array
* @return the hex string representing the binary values in the array
*/
- public static String toHexString( byte[] res )
+ public static final String toHexString( byte[] res )
{
StringBuffer buf = new StringBuffer( res.length << 1 );
@@ -450,7 +452,7 @@
* @param value The String to lowercase
* @return The lowercase string
*/
- public static String toLowerCase( String value )
+ public static final String toLowerCase( String value )
{
char[] chars = value.toCharArray();
@@ -469,7 +471,7 @@
* the hex string to convert to a byte array
* @return the byte form of the hex string.
*/
- public static byte[] toByteArray( String hexString )
+ public static final byte[] toByteArray( String hexString )
{
int arrLength = hexString.length() >> 1;
byte buf[] = new byte[arrLength];
@@ -500,7 +502,7 @@
* if true '\"' will be replaced by "
* @return the formated html block
*/
- public static String formatHtml( String source, boolean replaceNl, boolean replaceTag,
+ public static final String formatHtml( String source, boolean replaceNl, boolean replaceTag,
boolean replaceQuote )
{
StringBuffer buf = new StringBuffer();
@@ -595,7 +597,7 @@
* if a syntactically correct regular expression cannot be
* compiled
*/
- public static Pattern getRegex( String initialPattern, String[] anyPattern, String finalPattern )
+ public static final Pattern getRegex( String initialPattern, String[] anyPattern, String finalPattern )
throws PatternSyntaxException
{
StringBuffer buf = new StringBuffer();
@@ -637,7 +639,7 @@
* if a syntactically correct regular expression cannot be
* compiled
*/
- public static Pattern getRegex( String ldapRegex ) throws PatternSyntaxException
+ public static final Pattern getRegex( String ldapRegex ) throws PatternSyntaxException
{
if ( ldapRegex == null )
{
@@ -705,7 +707,7 @@
* @return the filter accepted path component Strings in the order
* encountered
*/
- public static List getPaths( String paths, FileFilter filter )
+ public static final List getPaths( String paths, FileFilter filter )
{
final int max = paths.length() - 1;
int start = 0;
@@ -783,7 +785,7 @@
* The byte to dump
* @return A string representation of the byte
*/
- public static String dumpByte( byte octet )
+ public static final String dumpByte( byte octet )
{
return new String( new byte[]
{ '0', 'x', HEX_CHAR[( octet & 0x00F0 ) >> 4], HEX_CHAR[octet & 0x000F] } );
@@ -797,7 +799,7 @@
* The hex to dump
* @return A char representation of the hex
*/
- public static char dumpHex( byte hex )
+ public static final char dumpHex( byte hex )
{
return ( char ) HEX_CHAR[hex & 0x000F];
}
@@ -810,7 +812,7 @@
* The bytes array to dump
* @return A string representation of the array of bytes
*/
- public static String dumpBytes( byte[] buffer )
+ public static final String dumpBytes( byte[] buffer )
{
if ( buffer == null )
{
@@ -836,7 +838,7 @@
* The byte[] represntation of an Unicode string.
* @return The first char found.
*/
- public static char bytesToChar( byte[] bytes )
+ public static final char bytesToChar( byte[] bytes )
{
return bytesToChar( bytes, 0 );
}
@@ -855,7 +857,7 @@
* wrong. TODO : Should stop after the third byte, as a char is only
* 2 bytes long.
*/
- public static int countBytesPerChar( byte[] bytes, int pos )
+ public static final int countBytesPerChar( byte[] bytes, int pos )
{
if ( bytes == null )
{
@@ -901,7 +903,7 @@
* @return The number of bytes to hold the char. TODO : Should stop after
* the third byte, as a char is only 2 bytes long.
*/
- public static int countNbBytesPerChar( char car )
+ public static final int countNbBytesPerChar( char car )
{
if ( ( car & CHAR_ONE_BYTE_MASK ) == 0 )
{
@@ -941,7 +943,7 @@
* The char array to decode
* @return The number of bytes in the char array
*/
- public static int countBytes( char[] chars )
+ public static final int countBytes( char[] chars )
{
if ( chars == null )
{
@@ -976,7 +978,7 @@
* @return The decoded char, or -1 if no char can be decoded TODO : Should
* stop after the third byte, as a char is only 2 bytes long.
*/
- public static char bytesToChar( byte[] bytes, int pos )
+ public static final char bytesToChar( byte[] bytes, int pos )
{
if ( bytes == null )
{
@@ -1130,7 +1132,7 @@
* @return The decoded char, or -1 if no char can be decoded TODO : Should
* stop after the third byte, as a char is only 2 bytes long.
*/
- public static byte[] charToBytes( char car )
+ public static final byte[] charToBytes( char car )
{
byte[] bytes = new byte[countNbBytesPerChar( car )];
@@ -1165,7 +1167,7 @@
* The byte array to decode
* @return The number of char in the byte array
*/
- public static int countChars( byte[] bytes )
+ public static final int countChars( byte[] bytes )
{
if ( bytes == null )
{
@@ -1196,7 +1198,7 @@
* The text we want to check
* @return <code>true</code> if the buffer contains the text.
*/
- public static int areEquals( byte[] byteArray, int index, String text )
+ public static final int areEquals( byte[] byteArray, int index, String text )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( byteArray.length <= index ) || ( index < 0 )
|| ( text == null ) )
@@ -1230,7 +1232,7 @@
* The text we want to check
* @return <code>true</code> if the buffer contains the text.
*/
- public static int areEquals( char[] charArray, int index, String text )
+ public static final int areEquals( char[] charArray, int index, String text )
{
if ( ( charArray == null ) || ( charArray.length == 0 ) || ( charArray.length <= index ) || ( index < 0 )
|| ( text == null ) )
@@ -1257,7 +1259,7 @@
* The text we want to check
* @return <code>true</code> if the buffer contains the text.
*/
- public static int areEquals( char[] charArray, int index, char[] charArray2 )
+ public static final int areEquals( char[] charArray, int index, char[] charArray2 )
{
if ( ( charArray == null ) || ( charArray.length == 0 ) || ( charArray.length <= index ) || ( index < 0 )
@@ -1291,7 +1293,7 @@
* The text we want to check
* @return <code>true</code> if the string contains the text.
*/
- public static boolean areEquals( String string1, int index, String text )
+ public static final boolean areEquals( String string1, int index, String text )
{
int length1 = string1.length();
int length2 = text.length();
@@ -1320,7 +1322,7 @@
* The text we want to check
* @return <code>true</code> if the buffer contains the text.
*/
- public static int areEquals( byte[] byteArray, int index, byte[] byteArray2 )
+ public static final int areEquals( byte[] byteArray, int index, byte[] byteArray2 )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( byteArray.length <= index ) || ( index < 0 )
@@ -1359,7 +1361,7 @@
* @return <code>true</code> if the current character equals the given
* character.
*/
- public static boolean isCharASCII( byte[] byteArray, int index, char car )
+ public static final boolean isCharASCII( byte[] byteArray, int index, char car )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) || ( index >= byteArray.length ) )
{
@@ -1385,7 +1387,7 @@
* @return <code>true</code> if the current character equals the given
* character.
*/
- public static boolean isCharASCII( char[] chars, int index, char car )
+ public static final boolean isCharASCII( char[] chars, int index, char car )
{
if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
{
@@ -1410,7 +1412,7 @@
* @return <code>true</code> if the current character equals the given
* character.
*/
- public static boolean isCharASCII( String string, int index, char car )
+ public static final boolean isCharASCII( String string, int index, char car )
{
int length = string.length();
@@ -1433,7 +1435,7 @@
* Current position in the string
* @return The character ar the given position, or '\0' if something went wrong
*/
- public static char charAt( String string, int index )
+ public static final char charAt( String string, int index )
{
int length = string.length();
@@ -1458,7 +1460,7 @@
* Current position in the buffer
* @return <code>true</code> if the current character is a Hex Char
*/
- public static boolean isHex( byte[] byteArray, int index )
+ public static final boolean isHex( byte[] byteArray, int index )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) || ( index >= byteArray.length ) )
{
@@ -1490,7 +1492,7 @@
* Current position in the buffer
* @return <code>true</code> if the current character is a Hex Char
*/
- public static boolean isHex( char[] chars, int index )
+ public static final boolean isHex( char[] chars, int index )
{
if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
{
@@ -1521,7 +1523,7 @@
* Current position in the string
* @return <code>true</code> if the current character is a Hex Char
*/
- public static boolean isHex( String string, int index )
+ public static final boolean isHex( String string, int index )
{
int length = string.length();
@@ -1553,7 +1555,7 @@
* The buffer which contains the data
* @return <code>true</code> if the current character is a Digit
*/
- public static boolean isDigit( byte[] byteArray )
+ public static final boolean isDigit( byte[] byteArray )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) )
{
@@ -1573,7 +1575,7 @@
*
* @return <code>true</code> if the character is a Digit
*/
- public static boolean isDigit( char car )
+ public static final boolean isDigit( char car )
{
return ( car >= '0' ) && ( car <= '9' );
}
@@ -1590,7 +1592,7 @@
* @return <code>true</code> if the current character is an Alpha
* character
*/
- public static boolean isAlphaASCII( byte[] byteArray, int index )
+ public static final boolean isAlphaASCII( byte[] byteArray, int index )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) || ( index >= byteArray.length ) )
{
@@ -1623,7 +1625,7 @@
* @return <code>true</code> if the current character is an Alpha
* character
*/
- public static boolean isAlphaASCII( char[] chars, int index )
+ public static final boolean isAlphaASCII( char[] chars, int index )
{
if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
{
@@ -1655,7 +1657,7 @@
* @return <code>true</code> if the current character is an Alpha
* character
*/
- public static boolean isAlphaASCII( String string, int index )
+ public static final boolean isAlphaASCII( String string, int index )
{
int length = string.length();
@@ -1689,7 +1691,7 @@
* Current position in the buffer
* @return <code>true</code> if the current character is a Digit
*/
- public static boolean isDigit( byte[] byteArray, int index )
+ public static final boolean isDigit( byte[] byteArray, int index )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) || ( index >= byteArray.length ) )
{
@@ -1712,7 +1714,7 @@
* Current position in the buffer
* @return <code>true</code> if the current character is a Digit
*/
- public static boolean isDigit( char[] chars, int index )
+ public static final boolean isDigit( char[] chars, int index )
{
if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
{
@@ -1734,7 +1736,7 @@
* Current position in the string
* @return <code>true</code> if the current character is a Digit
*/
- public static boolean isDigit( String string, int index )
+ public static final boolean isDigit( String string, int index )
{
int length = string.length();
@@ -1757,7 +1759,7 @@
* The buffer which contains the data
* @return <code>true</code> if the current character is a Digit
*/
- public static boolean isDigit( char[] chars )
+ public static final boolean isDigit( char[] chars )
{
if ( ( chars == null ) || ( chars.length == 0 ) )
{
@@ -1780,7 +1782,7 @@
* Current position in the buffer
* @return The position of the next character, if the current one is a CHAR.
*/
- public static boolean isAlphaDigitMinus( byte[] byteArray, int index )
+ public static final boolean isAlphaDigitMinus( byte[] byteArray, int index )
{
if ( ( byteArray == null ) || ( byteArray.length == 0 ) || ( index < 0 ) || ( index >= byteArray.length ) )
{
@@ -1812,7 +1814,7 @@
* Current position in the buffer
* @return The position of the next character, if the current one is a CHAR.
*/
- public static boolean isAlphaDigitMinus( char[] chars, int index )
+ public static final boolean isAlphaDigitMinus( char[] chars, int index )
{
if ( ( chars == null ) || ( chars.length == 0 ) || ( index < 0 ) || ( index >= chars.length ) )
{
@@ -1843,7 +1845,7 @@
* Current position in the string
* @return The position of the next character, if the current one is a CHAR.
*/
- public static boolean isAlphaDigitMinus( String string, int index )
+ public static final boolean isAlphaDigitMinus( String string, int index )
{
int length = string.length();
@@ -1890,7 +1892,7 @@
* the String to check, may be null
* @return <code>true</code> if the String is empty or null
*/
- public static boolean isEmpty( String str )
+ public static final boolean isEmpty( String str )
{
return str == null || str.length() == 0;
}
@@ -1903,7 +1905,7 @@
* The bytes array to check, may be null
* @return <code>true</code> if the bytes array is empty or null
*/
- public static boolean isEmpty( byte[] bytes )
+ public static final boolean isEmpty( byte[] bytes )
{
return bytes == null || bytes.length == 0;
}
@@ -1926,7 +1928,7 @@
* the String to check, may be null
* @return <code>true</code> if the String is not empty and not null
*/
- public static boolean isNotEmpty( String str )
+ public static final boolean isNotEmpty( String str )
{
return str != null && str.length() > 0;
}
@@ -1951,7 +1953,7 @@
* the String to be trimmed, may be null
* @return the trimmed string, <code>null</code> if null String input
*/
- public static String trim( String str )
+ public static final String trim( String str )
{
return ( isEmpty( str ) ? "" : str.trim() );
}
@@ -1976,7 +1978,7 @@
* the String to be trimmed, may be null
* @return the trimmed string, <code>null</code> if null String input
*/
- public static byte[] trim( byte[] bytes )
+ public static final byte[] trim( byte[] bytes )
{
if ( isEmpty( bytes ) )
{
@@ -2022,7 +2024,7 @@
* the String to be trimmed, may be null
* @return the trimmed string, <code>null</code> if null String input
*/
- public static String trimLeft( String str )
+ public static final String trimLeft( String str )
{
if ( isEmpty( str ) )
{
@@ -2061,7 +2063,7 @@
* @return the position of the first char which is not a space, or the last
* position of the array.
*/
- public static int trimLeft( char[] chars, int pos )
+ public static final int trimLeft( char[] chars, int pos )
{
if ( chars == null )
{
@@ -2096,7 +2098,7 @@
* @return the position of the first char which is not a space, or the last
* position of the array.
*/
- public static void trimLeft( String string, Position pos )
+ public static final void trimLeft( String string, Position pos )
{
if ( string == null )
{
@@ -2136,7 +2138,7 @@
* @return the position of the first byte which is not a space, or the last
* position of the array.
*/
- public static int trimLeft( byte[] bytes, int pos )
+ public static final int trimLeft( byte[] bytes, int pos )
{
if ( bytes == null )
{
@@ -2171,7 +2173,7 @@
* the String to be trimmed, may be null
* @return the trimmed string, <code>null</code> if null String input
*/
- public static String trimRight( String str )
+ public static final String trimRight( String str )
{
if ( isEmpty( str ) )
{
@@ -2215,7 +2217,7 @@
* @return the position of the first char which is not a space, or the last
* position of the array.
*/
- public static int trimRight( char[] chars, int pos )
+ public static final int trimRight( char[] chars, int pos )
{
if ( chars == null )
{
@@ -2250,7 +2252,7 @@
* @return the position of the first char which is not a space, or the last
* position of the string.
*/
- public static String trimRight( String string, Position pos )
+ public static final String trimRight( String string, Position pos )
{
if ( string == null )
{
@@ -2290,7 +2292,7 @@
* @return the position of the first char which is not a space, or the last
* position of the array.
*/
- public static int trimRight( byte[] bytes, int pos )
+ public static final int trimRight( byte[] bytes, int pos )
{
if ( bytes == null )
{
@@ -2326,7 +2328,7 @@
* the String to upper case, may be null
* @return the upper cased String, <code>null</code> if null String input
*/
- public static String upperCase( String str )
+ public static final String upperCase( String str )
{
if ( str == null )
{
@@ -2354,7 +2356,7 @@
* the String to lower case, may be null
* @return the lower cased String, <code>null</code> if null String input
*/
- public static String lowerCase( String str )
+ public static final String lowerCase( String str )
{
if ( str == null )
{
@@ -2392,7 +2394,7 @@
* @return <code>true</code> if the Strings are equal, case sensitive, or
* both <code>null</code>
*/
- public static boolean equals( String str1, String str2 )
+ public static final boolean equals( String str1, String str2 )
{
return str1 == null ? str2 == null : str1.equals( str2 );
}
@@ -2405,7 +2407,7 @@
* The byte array to be transformed to a String
* @return A String.
*/
- public static String utf8ToString( byte[] bytes )
+ public static final String utf8ToString( byte[] bytes )
{
if ( bytes == null )
{
@@ -2432,7 +2434,7 @@
* The length of the byte array to be converted
* @return A String.
*/
- public static String utf8ToString( byte[] bytes, int length )
+ public static final String utf8ToString( byte[] bytes, int length )
{
if ( bytes == null )
{
@@ -2457,7 +2459,7 @@
* The string to be transformed to a byte array
* @return The transformed byte array
*/
- public static byte[] getBytesUtf8( String string )
+ public static final byte[] getBytesUtf8( String string )
{
if ( string == null )
{
@@ -2483,7 +2485,7 @@
* The list to transform to a string
* @return A csv string
*/
- public static String listToString( List list )
+ public static final String listToString( List list )
{
if ( ( list == null ) || ( list.size() == 0 ) )
{
@@ -2520,7 +2522,7 @@
* The list to transform to a string
* @return A csv string
*/
- public static String listToString( List list, String tabs )
+ public static final String listToString( List list, String tabs )
{
if ( ( list == null ) || ( list.size() == 0 ) )
{
@@ -2550,7 +2552,7 @@
* The map to transform to a string
* @return A csv string
*/
- public static String mapToString( Map map )
+ public static final String mapToString( Map map )
{
if ( ( map == null ) || ( map.size() == 0 ) )
{
@@ -2590,7 +2592,7 @@
* The map to transform to a string
* @return A csv string
*/
- public static String mapToString( Map map, String tabs )
+ public static final String mapToString( Map map, String tabs )
{
if ( ( map == null ) || ( map.size() == 0 ) )
{
@@ -2617,7 +2619,7 @@
/**
* @return The default charset
*/
- public static String getDefaultCharsetName()
+ public static final String getDefaultCharsetName()
{
if ( JAVA_VERSION.startsWith( "1.4" ) )
{
@@ -2627,5 +2629,113 @@
{
return DEFAULT_CHARSET_JDK_1_5;
}
+ }
+
+
+ /**
+ * Decodes values of attributes in the DN encoded in hex into a UTF-8
+ * String. RFC2253 allows a DN's attribute to be encoded in hex.
+ * The encoded value starts with a # then is followed by an even
+ * number of hex characters.
+ */
+ public static final String decodeHexString( String str ) throws InvalidNameException
+ {
+ if ( str == null || str.length() == 0 )
+ {
+ throw new InvalidNameException( "Expected string to start with a '#' character. " +
+ "Invalid hex encoded string for empty or null string." );
+ }
+
+ char[] chars = str.toCharArray();
+ if ( chars[0] != '#' )
+ {
+ throw new InvalidNameException( "Expected string to start with a '#' character. " +
+ "Invalid hex encoded string: " + str );
+ }
+
+ // the bytes representing the encoded string of hex
+ // this should be ( length - 1 )/2 in size
+ byte[] decoded = new byte[ ( chars.length - 1 ) >> 1 ];
+
+ for ( int ii = 1, jj = 0 ; ii < chars.length; ii+=2, jj++ )
+ {
+ int ch = ( StringTools.HEX_VALUE[chars[ii]] << 4 ) +
+ StringTools.HEX_VALUE[chars[ii+1]];
+ decoded[jj] = ( byte ) ch;
+ }
+
+ return StringTools.utf8ToString( decoded );
+ }
+
+
+ /**
+ * Decodes sequences of escaped hex within an attribute's value into
+ * a UTF-8 String. The hex is decoded inline and the complete decoded
+ * String is returned.
+ *
+ * @param str the string containing hex escapes
+ * @param index the index at which we start decoding
+ * @return decoded string
+ */
+ public static final String decodeEscapedHex( String str ) throws InvalidNameException
+ {
+ int length = str.length();
+ if ( str == null || length == 0 )
+ {
+ throw new InvalidNameException( "Expected string to be non-empty or non-null " +
+ "with valid index." );
+ }
+
+ // create buffer and add everything before start of scan
+ StringBuffer buf = new StringBuffer();
+ ByteBuffer bb = new ByteBuffer();
+
+ // start scaning until we find an escaped series of bytes
+ for ( int ii = 0; ii < length; ii++ )
+ {
+ if ( str.charAt( ii ) == '\\' )
+ {
+ // we have the start of a hex escape sequence
+ if ( isHex( str, ii+1 ) && isHex ( str, ii+2 ) )
+ {
+ bb.clear();
+ int advancedBy = collectEscapedHexBytes( bb, str, ii );
+ ii+=advancedBy-1;
+ buf.append( StringTools.utf8ToString( bb.buffer(), bb.position() ) );
+ continue;
+ }
+ else
+ {
+ buf.append( str.charAt( ii ) );
+ continue;
+ }
+ }
+
+ buf.append( str.charAt( ii ) );
+ }
+
+ return buf.toString();
+ }
+
+
+ private static int collectEscapedHexBytes( ByteBuffer bb, String str, int index )
+ {
+ int advanceBy = 0;
+ for ( int ii = index; ii < str.length(); ii += 3, advanceBy += 3 )
+ {
+ // we have the start of a hex escape sequence
+ if ( isHex( str, ii+1 ) && isHex ( str, ii+2 ) )
+ {
+ int bite = ( StringTools.HEX_VALUE[str.charAt( ii+1 )] << 4 ) +
+ StringTools.HEX_VALUE[str.charAt( ii+2 )];
+ bb.append( bite );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return advanceBy;
}
}
Added: directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/ByteBufferTest.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/ByteBufferTest.java?rev=429140&view=auto
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/ByteBufferTest.java (added)
+++ directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/ByteBufferTest.java Sun Aug 6 08:58:38 2006
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006 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.directory.shared.ldap.util;
+
+
+import junit.framework.TestCase;
+
+
+/**
+ * A test case for a dynamically growing byte[].
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ByteBufferTest extends TestCase
+{
+ public void testByteBufferGrowth()
+ {
+ ByteBuffer buf = new ByteBuffer();
+ assertEquals( 10, buf.capacity() );
+
+ for ( int ii = 0; ii < 20; ii++ )
+ {
+ buf.append( ii );
+ assertEquals( ii, buf.get( ii ) );
+ assertEquals( ii, buf.buffer()[ii] );
+ }
+
+ assertEquals( 20, buf.capacity() );
+ buf.append( 20 );
+ assertEquals( 30, buf.capacity() );
+
+ // -------------------------------------------------------------------
+
+ buf = new ByteBuffer( 5 );
+ assertEquals( 5, buf.capacity() );
+
+ for ( int ii = 0; ii < 5; ii++ )
+ {
+ buf.append( ii );
+ assertEquals( ii, buf.get( ii ) );
+ assertEquals( ii, buf.buffer()[ii] );
+ }
+
+ assertEquals( 5, buf.capacity() );
+ buf.append( 5 );
+ assertEquals( 10, buf.capacity() );
+ }
+}
Modified: directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java
URL: http://svn.apache.org/viewvc/directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java?rev=429140&r1=429139&r2=429140&view=diff
==============================================================================
--- directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java (original)
+++ directory/branches/shared/0.9.5/ldap/src/test/java/org/apache/directory/shared/ldap/util/StringToolsTest.java Sun Aug 6 08:58:38 2006
@@ -23,6 +23,8 @@
import java.util.Map;
import java.util.regex.Pattern;
+import javax.naming.NamingException;
+
import org.apache.directory.shared.ldap.util.StringTools;
import junit.framework.Assert;
@@ -37,6 +39,26 @@
*/
public class StringToolsTest extends TestCase
{
+ public void testDecodeEscapedHex() throws Exception
+ {
+ assertEquals( "Ferry", StringTools.decodeEscapedHex( "\\46\\65\\72\\72\\79" ) );
+ assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72\\72\\79" ) );
+ assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72\\72y" ) );
+ assertEquals( "Ferry", StringTools.decodeEscapedHex( "Fe\\72ry" ) );
+ }
+
+ public void testDecodeHexString() throws Exception
+ {
+ // weird stuff - corner cases
+ try{assertEquals( "", StringTools.decodeHexString( "" ) ); fail("should not get here");} catch( NamingException e ){};
+ assertEquals( "", StringTools.decodeHexString( "#" ) );
+ assertEquals( "F", StringTools.decodeHexString( "#46" ) );
+ try{assertEquals( "F", StringTools.decodeHexString( "46" ) ); fail("should not get here");} catch( NamingException e ){};
+
+ assertEquals( "Ferry", StringTools.decodeHexString( "#4665727279" ) );
+ }
+
+
public void testTrimConsecutiveToOne()
{
String input = null;