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

com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput$NewLineEscapeHandler can't call into XMLStreamWriter if text length is 0

    Details

    • Subcomponent:
    • Introduced In Build:
      b175
    • Introduced In Version:
      9
    • CPU:
      x86_64
    • OS:
      os_x

      Description

      FULL PRODUCT VERSION :
      java version "9"
      Java(TM) SE Runtime Environment (build 9+181)
      Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

      A DESCRIPTION OF THE PROBLEM :
      The new introduced com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput$NewLineEscapeHandler can't call into XMLStreamWriter if text length is 0.

      Previousely(at least in jdk-9-ea+174), the com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput.text(String value, boolean needsSeparatingWhitespace) method is like
      public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
              if(needsSeparatingWhitespace)
                  out.writeCharacters(" ");
              out.writeCharacters(value);
          }
      So even the String value length is 0, out.writeCharacters(value) is still invoked, so that the underlying XMLStreamWriter get chance to handle this case, like put specify text meaningful in the output payload.

      But in JDK9 GA it becomes
      public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
              if(needsSeparatingWhitespace)
                  out.writeCharacters(" ");
              escapeHandler.escape(value.toCharArray(), 0, value.length(), false, writerWrapper);
          }
      And this new introduced XMLStreamWriterOutput$NewLineEscapeHandler is

      public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
                  int limit = start+length;
                  int lastEscaped = start;
                  for (int i = start; i < limit; i++) {
                      char c = ch[i];
                      if (c == '\r' || c == '\n') {
                          if (i != lastEscaped) {
                              out.write(ch, lastEscaped, i - lastEscaped);
                          }
                          lastEscaped = i + 1;
                          if (out instanceof XmlStreamOutWriterAdapter) {
                              try {
                                  ((XmlStreamOutWriterAdapter)out).writeEntityRef("#x" + Integer.toHexString(c));
                              } catch (XMLStreamException e) {
                                  throw new IOException("Error writing xml stream", e);
                              }
                          } else {
                              out.write("&#x");
                              out.write(Integer.toHexString(c));
                              out.write(';');
                          }
                      }
                  }

                  if (lastEscaped != limit) { //here if char[] ch lenght is 0, then there's no way to run into the out.write
                      out.write(ch, lastEscaped, length - lastEscaped);
                  }
              }
      So if the String value length is 0, it would skip the out.write(...) so that the XMLStreamWriter never get called.

      This different behavior cause that the underlying XMLStreamWriter lost chance to put any meaningful text into the output payload when the String value is empty.
      For example, with previous expected behavior, we can get a payload like
       {"Book":{"id":123,"name":"MyName","state":"state length is actually 0"}}
      if state is an empty string actually as we can override the XMLStreamWriter.writeCharacters(text) method and detect if the text is empty and output anything meaningful for us.
      However, with the JDK9 GA the output payload is
       {"Book":{"id":123,"name":"MyName","state":""}}
      as underlying XMLStreamWriter lost chance to handle when text is empty



      REGRESSION. Last worked in version 8u144

      ADDITIONAL REGRESSION INFORMATION:
      It worked in
      jdk-9-ea+174


      REPRODUCIBILITY :
      This bug can be reproduced always.

        Attachments

          Activity

            People

            • Assignee:
              hwu Hong Jie Wu (Inactive)
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: