United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6311448 XML transformer failed to output surrorates pair.
JDK-6311448 : XML transformer failed to output surrorates pair.

Details
Type:
Bug
Submit Date:
2005-08-16
Status:
Resolved
Updated Date:
2012-04-25
Project Name:
JDK
Resolved Date:
2006-12-12
Component:
xml
OS:
solaris_2.5.1
Sub-Component:
javax.xml.parsers
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
5.0u4
Fixed Versions:
1.4.0 (1.4)

Related Reports
Backport:
Backport:

Sub Tasks

Description
OPERATING SYSTEM(S):
SLES9 SP1 with zh_CN.GB18030 locale
RHEL4 with zh_CN.GB18030 locale

FULL JDK VERSION(S):
$java -version
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode)

DESCRIPTION:
- Exact steps to reproduce
 1. Compile and run testcase "java PrefTest"
 2. Query saved name by issue "java PrefTest -q"
 3. Terminal print out the following message:
    WARNING: Invalid preferences format in $HOME/.java/.userPrefs/mynode/myKey/prefs.xml
    You name is NOT DEFINED.
    2005-8-5 2:42:58 java.util.prefs.FileSystemPreferences$7 run
    WARNING: Prefs file removed in background $HOME/.java/.userPrefs/mynode/myKey/prefs.xml

- Minimal source code that demonstrates the problem
/*
 * PrefTest.java
 * - A sample program for Preferences class
 */
import java.util.prefs.*;
import java.awt.event.*;
public class PrefTest {
    static private String ourNodeName = "/mynode/myKey";
    static private String key = "myName";
    
    static void setName(String name) {
        Preferences prefs = Preferences.userRoot().node(ourNodeName);
        
        prefs.put(key, name);
    }
    
    static void getName() {
        Preferences prefs = Preferences.userRoot().node(ourNodeName);
        
        String myName = prefs.get(key, "");
        if (myName.equals("")) {
            System.out.println("You name is NOT DEFINED.");
        } else {
            System.out.println("Your name is " + myName + ".");
        }
    }
    
    static void removeName() {
        Preferences prefs = Preferences.userRoot().node(ourNodeName);
        
        prefs.remove(key);
    }
    
    public static void main(String[] args) {
        if (args.length > 0) {
	        if (args[0].equals("-q")) {
	            PrefTest.getName();
	        } else if (args[0].equals("-r")) {
	            PrefTest.removeName();
	        }
	    } else {
	        PrefTest.setName("\ud840\udc00");
	    }
    }
    
}

- Exact text of any error messages
WARNING: Invalid preferences format in $HOME/.java/.userPrefs/mynode/myKey/prefs.xml
    You name is NOT DEFINED.
    2005-8-5 2:42:58 java.util.prefs.FileSystemPreferences$7 run
    WARNING: Prefs file removed in background $HOME/.java/.userPrefs/mynode/myKey/prefs.xml

                                    

Comments
EVALUATION

src/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.writeAttrString()
deos not write out surrogates correctly. accumDefaultEscape()returns i+2 if a pair of
surrogates have been written out successfully, but iteration loop in writeAttrString
always step 1, the result is the low-half of the surrogates is always being incorrectly
attached for each pair of surrogates output.

attached is the test case.
	String attrKey = "key";
	String attrValue = "\ud800\udc00";

	Document doc = 
	    DocumentBuilderFactory.newInstance()
	                          .newDocumentBuilder()
	                          .getDOMImplementation()
	                          .createDocument(null, null, null);
	
        Element xmlRoot =  doc.createElement("root");
        xmlRoot.setAttribute(attrKey, attrValue);
	doc.appendChild(xmlRoot);

	Transformer t = TransformerFactory.newInstance()
	                                  .newTransformer();

	BufferedWriter bw =  new BufferedWriter(new OutputStreamWriter(
			       new FileOutputStream("foo.xml"), "UTF-8"));

	t.transform(new DOMSource(doc), new StreamResult(bw));
	bw.close();
                                     
2006-12-07
SUGGESTED FIX

*** /tmp/geta27253	Wed Dec  6 15:46:51 2006
--- ToStream.java	Wed Dec  6 15:45:53 2006
***************
*** 1642,1648 ****
      {
  
          int pos = accumDefaultEntity(writer, ch, i, chars, len, fromTextNode, escLF);
- 
          if (i == pos)
          {
              if (Encodings.isHighUTF16Surrogate(ch))
--- 1642,1647 ----
***************
*** 1967,1978 ****
          string.getChars(0,len, m_attrBuff, 0);   
          final char[] stringChars = m_attrBuff;
  
!         for (int i = 0; i < len; i++)
          {
              char ch = stringChars[i];
              if (escapingNotNeeded(ch) && (!m_charInfo.isSpecialAttrChar(ch)))
              {
                  writer.write(ch);
              }
              else
              { // I guess the parser doesn't normalize cr/lf in attributes. -sb
--- 1966,1980 ----
          string.getChars(0,len, m_attrBuff, 0);   
          final char[] stringChars = m_attrBuff;
  
! 	int i = 0;
! 	while (i < len)
! 	//        for (int i = 0; i < len; i++)
          {
              char ch = stringChars[i];
              if (escapingNotNeeded(ch) && (!m_charInfo.isSpecialAttrChar(ch)))
              {
                  writer.write(ch);
+ 		i++;
              }
              else
              { // I guess the parser doesn't normalize cr/lf in attributes. -sb
***************
*** 1984,1990 ****
  //                    ch = CharInfo.S_LINEFEED;
  //                }
  
!                 accumDefaultEscape(writer, ch, i, stringChars, len, false, true);
              }
          }
  
--- 1986,1992 ----
  //                    ch = CharInfo.S_LINEFEED;
  //                }
  
!                 i = accumDefaultEscape(writer, ch, i, stringChars, len, false, true);
              }
          }
                                     
2006-12-07
EVALUATION

Proposed fix is correct. The fix has now been integrated into JAXP 1.4 RI (will be part of weekly build available from Java.net).
                                     
2006-12-12



Hardware and Software, Engineered to Work Together