Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8055692

Call to Document.adoptNode corrupts original Document

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 8
    • Fix Version/s: tbd
    • Component/s: xml
    • Labels:

      Description

      FULL PRODUCT VERSION :
      Java(TM) SE Runtime Environment (build 1.8.0-b129)
      Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69

      also with Java 7.

      ADDITIONAL OS VERSION INFORMATION :
      3.13.0-30-generic #55-Ubuntu SMP

      A DESCRIPTION OF THE PROBLEM :
      See the

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the attached test case.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      adoptNode shouldn't modify the original Document at all, but it does - setting the value of one of the Text nodes to null for no apparent reason. This is invalid, as you can see in the error from verify().

      Seems to be some particular combination of these inputs that cause it - even reformatting the input can prevent the error being reproduced. In particular my suspicion rests on the comments in the "CONFIG" xml.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.*;
      import java.text.*;
      import java.util.*;
      import org.w3c.dom.*;
      import org.xml.sax.SAXException;
      import org.xml.sax.InputSource;
      import javax.xml.transform.stream.*;
      import javax.xml.transform.dom.*;
      import javax.xml.transform.*;
      import javax.xml.parsers.*;

      public class Test {

          public static void main(String[] args) throws Exception {
              DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
              dbf.setNamespaceAware(true);
              DocumentBuilder db = dbf.newDocumentBuilder();
              Document doc1 = db.parse(new ByteArrayInputStream(CONFIG.getBytes("ISO-8859-1")));
              Document doc2 = db.parse(new ByteArrayInputStream(IMPORT.getBytes("ISO-8859-1")));
              // Both documents have parsed at this point, so are valid XML
              doc1.adoptNode(doc2.getDocumentElement());
              verify(doc1, "");
          }

          private static void verify(Node node, String indent) {
              int type = node.getNodeType();
              System.out.println(indent + "-> "+node.getNodeName()+"="+node.getNodeValue());
              if (node.getNodeValue() == null && node instanceof Text) {
                  throw new Error("Text is null");
              }
              for (Node kid = node.getFirstChild();kid != null;kid = kid.getNextSibling()) {
                  verify(kid, indent+' ');
              }
              System.out.println(indent + "<- "+node.getNodeName());
          }

          static String CONFIG = "<config xmlns=\"http://www.xfa.org/schema/xci/1.0/\" xmlns:xfa=\"http://www.xfa.org/schema/xci/1.0/\"><trace><area level=\"1\" name=\"font\"></area></trace><agent name=\"designer\"><!-- abc --><destination>pdf</destination><pdf><!-- [0..n] --><fontInfo></fontInfo></pdf></agent><present><!-- [0..n] --><pdf><!-- [0..n] --><fontInfo><embed>1</embed></fontInfo><version>1.65</version><creator>Adobe Designer 7.1</creator><producer>Adobe Designer 7.1</producer><scriptModel>XFA</scriptModel><interactive>1</interactive><tagged>1</tagged><encryption><permissions><accessibleContent>1</accessibleContent><contentCopy>1</contentCopy><documentAssembly>1</documentAssembly><formFieldFilling>1</formFieldFilling><modifyAnnots>1</modifyAnnots><print>1</print><printHighQuality>1</printHighQuality><change>1</change><plaintextMetadata>1</plaintextMetadata></permissions></encryption><compression><level>6</level><compressLogicalStructure>1</compressLogicalStructure></compression></pdf><common><data><xsl><uri></uri></xsl><outputXSL><uri></uri></outputXSL></data><log><to>memory</to><mode>overwrite</mode></log><template><base>C:\\Documents and Settings\\a343636.000\\Desktop\\</base></template></common><xdp><packets>*</packets></xdp><cache><macroCache></macroCache></cache><destination>pdf</destination><output><to>uri</to><uri>C:\\Documents and Settings\\a343636.000\\Desktop\\submitSample.pdf</uri></output></present><acrobat><acrobat7><dynamicRender>required</dynamicRender></acrobat7><common><locale></locale><data><xsl><uri></uri></xsl><outputXSL><uri></uri></outputXSL><adjustData></adjustData></data><template><base>C:\\Documents and Settings\\a343636.000\\Desktop\\</base><relevant></relevant><uri></uri></template></common></acrobat><coolType><additionalFontsDirectory>C:\\Program Files\\Adobe\\Designer 7.1\\fonts</additionalFontsDirectory><commonFontsDirectory>C:\\Program Files\\Adobe\\Designer 7.1\\fonts</commonFontsDirectory><unicodeDirectory>C:\\Program Files\\Adobe\\Designer 7.1\\fonts\\typeSpt\\Unicode</unicodeDirectory><fntNamesDBFile>C:\\Program Files\\Adobe\\Designer 7.1\\fonts\\typeSpt\\FntNames.db</fntNamesDBFile></coolType></config>";

          static String IMPORT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xfa:datasets xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\">\n <xfa:data>\n <SampleForm>\n <address>\n <Address/>\n <ZipCode/>\n <Country/>\n </address>\n <SubmitURL/>\n </SampleForm>\n </xfa:data>\n <dd:dataDescription xmlns:dd=\"http://ns.adobe.com/data-description/\" dd:name=\"SampleForm\">\n </dd:dataDescription>\n</xfa:datasets>\n";

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use importNode instead of adoptNode. Also, in this example, running verify() before the import works, which makes me think it's some aspect of the deferral in the "DeferredNode" idea from Xerces.

        Attachments

          Activity

            People

            Assignee:
            joehw Joe Wang
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated: