JDK-6201517 : javax.naming.CompositeName and javax.naming.CompoundName handle escape character ('\') incorrectly.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.naming
  • Affected Version: 1.4.2,5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_9
  • CPU: generic
  • Submitted: 2004-11-30
  • Updated: 2010-08-19
  • Resolved: 2005-07-08
Related Reports
Relates :  
Relates :  
Description
2004/11/30 11:00 ###@###.### --
There is discrepency between calls to get() and toString().  Given the following test program (also attached to this bug):

------------------------------------------------------------
//import com.sun.jndi.ldap.*;  // for v1.4.2 and v1.5.0
import java.util.*;
import javax.naming.*;
import javax.naming.ldap.*;  // for v1.5.0 only

public class NameTest {
    public static void main(String[] argumentList) throws NamingException {
        Name       cName1     = null;
        Name       cName2     = null;
        Name       cName3     = null;
        Name       cName4     = null;
        Name       lName1     = null;
        Properties properties = new Properties();
        String     dn         = "cn=A\\\\B, cn=testRoot";

        properties.setProperty("jndi.syntax.direction",  "left_to_right");
        properties.setProperty("jndi.syntax.separator",  "/");
        properties.setProperty("jndi.syntax.ignorecase", "true");
        properties.setProperty("jndi.syntax.escape",     "\\");

        cName1 = new CompositeName().add(dn);
        cName2 = new CompositeName(dn);
        cName3 = new CompoundName("", properties).add(dn);
        cName4 = new CompoundName(dn, properties);
        lName1 = new LdapName(dn);

        for (int i = 0; i < cName1.size(); i++) {
            System.out.println("cName1: " + cName1.get(i));
        }
        System.out.println("cName1: " + cName1.toString());

        for (int i = 0; i < cName2.size(); i++) {
            System.out.println("cName2: " + cName2.get(i));
        }
        System.out.println("cName2: " + cName2.toString());

        for (int i = 0; i < cName3.size(); i++) {
            System.out.println("cName3: " + cName3.get(i));
        }
        System.out.println("cName3: " + cName3.toString());

        for (int i = 0; i < cName4.size(); i++) {
            System.out.println("cName4: " + cName4.get(i));
        }
        System.out.println("cName4: " + cName4.toString());

        for (int i = 0; i < lName1.size(); i++) {
            System.out.println("lName1: " + lName1.get(i));
        }
        System.out.println("lName1: " + lName1.toString());
    }
}
------------------------------------------------------------

the results on JDK v1.4.2 and v1.5.0 are:

1. Using com.sun.jndi.ldap.LdapName (JDK v1.4.2 and JDK v1.5.0)

JDK v1.4.2_04 -
cName1: cn=A\\B, cn=testRoot
cName1: cn=A\\\B, cn=testRoot  *
cName2: cn=A\B, cn=testRoot    *
cName2: cn=A\B, cn=testRoot    *
cName3: cn=A\\B, cn=testRoot
cName3: cn=A\\\B, cn=testRoot  *
cName4: cn=A\B, cn=testRoot    *
cName4: cn=A\B, cn=testRoot    *
lName1: cn=testRoot
lName1: cn=A\\B
lName1: cn=A\\B, cn=testRoot

JDK v1.5.0_00 -
cName1: cn=A\\B, cn=testRoot
cName1: cn=A\\\B, cn=testRoot  *
cName2: cn=A\B, cn=testRoot    *
cName2: cn=A\B, cn=testRoot    *
cName3: cn=A\\B, cn=testRoot
cName3: cn=A\\\B, cn=testRoot  *
cName4: cn=A\B, cn=testRoot    *
cName4: cn=A\B, cn=testRoot    *
lName1: cn=testRoot
lName1: cn=A\\B
lName1: cn=A\\B, cn=testRoot

2. Using javax.naming.ldap.LdapName (JDK v1.5.0 only)

JDK v1.5.0_00 -
cName1: cn=A\\B, cn=testRoot
cName1: cn=A\\\B, cn=testRoot  *
cName2: cn=A\B, cn=testRoot    *
cName2: cn=A\B, cn=testRoot    *
cName3: cn=A\\B, cn=testRoot
cName3: cn=A\\\B, cn=testRoot  *
cName4: cn=A\B, cn=testRoot    *
cName4: cn=A\B, cn=testRoot    *
lName1: cn=testRoot
lName1: cn=A\\B
lName1: cn=A\\B, cn=testRoot

The only time it can produce the correct output is when we are using "cn=A\\B, cn=testRoot" as DN.


Comments
EVALUATION This is not a bug. The methods Name.get(index) and Name.toString() need not return the same strings. The get() method returns the Name Component. And the toSting() method returns a String representation of the name that contain special characters if present be escaped. The string returned by toString if is fed back to the constructor it returns the same Name. Please refer to the Javadoc for both of these methods. There is also a difference in creating a {Composite/Compound}Name by passing the String to the constructor versus using an empty constructor and adding the String using the add() method. The former expects the String to be formatted according to the composite name syntax (and the specified syntax for CompoundName) while the latter automatically takes care of the syntax. Please refer to the similar bugs JNDI tutorial track below: 6201615 4894089 http://java.sun.com/products/jndi/tutorial/beyond/names/syntax.html ###@###.### 2005-07-08 09:18:01 GMT
08-07-2005

WORK AROUND 2004/11/30 11:00 ###@###.### -- We can use LdapName instead since it is now a part of the documentated API in JDK v1.5.0. ###@###.### 2004-11-30 01:43:35 GMT
30-11-2004