diff --git a/docs/release-notes.html b/docs/release-notes.html index e131f91ea..cf00b5e76 100644 --- a/docs/release-notes.html +++ b/docs/release-notes.html @@ -13,6 +13,12 @@

Version 4.0.14

diff --git a/src/com/unboundid/ldap/sdk/LDAPURL.java b/src/com/unboundid/ldap/sdk/LDAPURL.java index 36b5936c3..0ab2a83a8 100644 --- a/src/com/unboundid/ldap/sdk/LDAPURL.java +++ b/src/com/unboundid/ldap/sdk/LDAPURL.java @@ -23,9 +23,9 @@ import java.io.Serializable; -import java.nio.ByteBuffer; import java.util.ArrayList; +import com.unboundid.util.ByteStringBuffer; import com.unboundid.util.Debug; import com.unboundid.util.NotMutable; import com.unboundid.util.StaticUtils; @@ -909,7 +909,7 @@ public static String percentDecode(final String s) } int pos = firstPercentPos; - final StringBuilder buffer = new StringBuilder(2 * length); + final ByteStringBuffer buffer = new ByteStringBuffer(2 * length); buffer.append(s.substring(0, firstPercentPos)); while (pos < length) @@ -923,152 +923,136 @@ public static String percentDecode(final String s) ERR_LDAPURL_HEX_STRING_TOO_SHORT.get(s)); } - - final ByteBuffer byteBuffer = ByteBuffer.allocate(length - pos); - while (pos < length) + final byte b; + switch (s.charAt(pos++)) { - final byte b; - switch (s.charAt(pos++)) - { - case '0': - b = 0x00; - break; - case '1': - b = 0x10; - break; - case '2': - b = 0x20; - break; - case '3': - b = 0x30; - break; - case '4': - b = 0x40; - break; - case '5': - b = 0x50; - break; - case '6': - b = 0x60; - break; - case '7': - b = 0x70; - break; - case '8': - b = (byte) 0x80; - break; - case '9': - b = (byte) 0x90; - break; - case 'a': - case 'A': - b = (byte) 0xA0; - break; - case 'b': - case 'B': - b = (byte) 0xB0; - break; - case 'c': - case 'C': - b = (byte) 0xC0; - break; - case 'd': - case 'D': - b = (byte) 0xD0; - break; - case 'e': - case 'E': - b = (byte) 0xE0; - break; - case 'f': - case 'F': - b = (byte) 0xF0; - break; - default: - throw new LDAPException(ResultCode.DECODING_ERROR, - ERR_LDAPURL_INVALID_HEX_CHAR.get( - s.charAt(pos-1))); - } - - if (pos >= length) - { + case '0': + b = 0x00; + break; + case '1': + b = 0x10; + break; + case '2': + b = 0x20; + break; + case '3': + b = 0x30; + break; + case '4': + b = 0x40; + break; + case '5': + b = 0x50; + break; + case '6': + b = 0x60; + break; + case '7': + b = 0x70; + break; + case '8': + b = (byte) 0x80; + break; + case '9': + b = (byte) 0x90; + break; + case 'a': + case 'A': + b = (byte) 0xA0; + break; + case 'b': + case 'B': + b = (byte) 0xB0; + break; + case 'c': + case 'C': + b = (byte) 0xC0; + break; + case 'd': + case 'D': + b = (byte) 0xD0; + break; + case 'e': + case 'E': + b = (byte) 0xE0; + break; + case 'f': + case 'F': + b = (byte) 0xF0; + break; + default: throw new LDAPException(ResultCode.DECODING_ERROR, - ERR_LDAPURL_HEX_STRING_TOO_SHORT.get(s)); - } + ERR_LDAPURL_INVALID_HEX_CHAR.get( + s.charAt(pos-1))); + } - switch (s.charAt(pos++)) - { - case '0': - byteBuffer.put(b); - break; - case '1': - byteBuffer.put((byte) (b | 0x01)); - break; - case '2': - byteBuffer.put((byte) (b | 0x02)); - break; - case '3': - byteBuffer.put((byte) (b | 0x03)); - break; - case '4': - byteBuffer.put((byte) (b | 0x04)); - break; - case '5': - byteBuffer.put((byte) (b | 0x05)); - break; - case '6': - byteBuffer.put((byte) (b | 0x06)); - break; - case '7': - byteBuffer.put((byte) (b | 0x07)); - break; - case '8': - byteBuffer.put((byte) (b | 0x08)); - break; - case '9': - byteBuffer.put((byte) (b | 0x09)); - break; - case 'a': - case 'A': - byteBuffer.put((byte) (b | 0x0A)); - break; - case 'b': - case 'B': - byteBuffer.put((byte) (b | 0x0B)); - break; - case 'c': - case 'C': - byteBuffer.put((byte) (b | 0x0C)); - break; - case 'd': - case 'D': - byteBuffer.put((byte) (b | 0x0D)); - break; - case 'e': - case 'E': - byteBuffer.put((byte) (b | 0x0E)); - break; - case 'f': - case 'F': - byteBuffer.put((byte) (b | 0x0F)); - break; - default: - throw new LDAPException(ResultCode.DECODING_ERROR, - ERR_LDAPURL_INVALID_HEX_CHAR.get( - s.charAt(pos-1))); - } + if (pos >= length) + { + throw new LDAPException(ResultCode.DECODING_ERROR, + ERR_LDAPURL_HEX_STRING_TOO_SHORT.get(s)); + } - if ((pos < length) && (s.charAt(pos) != '%')) - { + switch (s.charAt(pos++)) + { + case '0': + buffer.append(b); break; - } + case '1': + buffer.append((byte) (b | 0x01)); + break; + case '2': + buffer.append((byte) (b | 0x02)); + break; + case '3': + buffer.append((byte) (b | 0x03)); + break; + case '4': + buffer.append((byte) (b | 0x04)); + break; + case '5': + buffer.append((byte) (b | 0x05)); + break; + case '6': + buffer.append((byte) (b | 0x06)); + break; + case '7': + buffer.append((byte) (b | 0x07)); + break; + case '8': + buffer.append((byte) (b | 0x08)); + break; + case '9': + buffer.append((byte) (b | 0x09)); + break; + case 'a': + case 'A': + buffer.append((byte) (b | 0x0A)); + break; + case 'b': + case 'B': + buffer.append((byte) (b | 0x0B)); + break; + case 'c': + case 'C': + buffer.append((byte) (b | 0x0C)); + break; + case 'd': + case 'D': + buffer.append((byte) (b | 0x0D)); + break; + case 'e': + case 'E': + buffer.append((byte) (b | 0x0E)); + break; + case 'f': + case 'F': + buffer.append((byte) (b | 0x0F)); + break; + default: + throw new LDAPException(ResultCode.DECODING_ERROR, + ERR_LDAPURL_INVALID_HEX_CHAR.get( + s.charAt(pos-1))); } - - byteBuffer.flip(); - final byte[] byteArray = new byte[byteBuffer.limit()]; - byteBuffer.get(byteArray); - - buffer.append(StaticUtils.toUTF8String(byteArray)); } else { diff --git a/tests/unit/src/com/unboundid/ldap/sdk/LDAPURLTestCase.java b/tests/unit/src/com/unboundid/ldap/sdk/LDAPURLTestCase.java index 3c25d79da..1ec234c8e 100644 --- a/tests/unit/src/com/unboundid/ldap/sdk/LDAPURLTestCase.java +++ b/tests/unit/src/com/unboundid/ldap/sdk/LDAPURLTestCase.java @@ -1012,6 +1012,29 @@ public Object[][] getTestValidURLs() "ldap://server.example.com:389/a=b+c=d,dc=example,dc=com??sub?" + "(cn=foo%20bar)" }, + + new Object[] + { + "ldap://child.root.example.com/OU=%25%5E%25%5E%25%5E*,DC=child," + + "DC=root,DC=example,DC=com", + "ldap", + "child.root.example.com", + true, + 389, + false, + new DN(new RDN("OU", "%^%^%^*"), new RDN("DC", "child"), + new RDN("DC", "root"), new RDN("DC", "example"), + new RDN("dc", "com")), + true, + new String[0], + false, + SearchScope.BASE, + false, + Filter.create("(objectClass=*)"), + false, + "ldap://child.root.example.com:389/ou=%25%5e%25%5e%25%5e*,dc=child," + + "dc=root,dc=example,dc=com??base?(objectclass=*)" + } }; }