[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmlbeans-dev
Subject:    [jira] [Updated] (XMLBEANS-512) SaxHandler should be reset on exception
From:       "Michel Jung (JIRA)" <xmlbeans-dev () xml ! apache ! org>
Date:       2014-06-23 7:48:24
Message-ID: JIRA.12722797.1403277554070.27254.1403509704801 () arcas
[Download RAW message or body]


     [ https://issues.apache.org/jira/browse/XMLBEANS-512?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel \
]

Michel Jung updated XMLBEANS-512:
---------------------------------

    Description: 
In {{SaxHandler}}, if an XML entity exceeds the entity byte limit, an exception is \
thrown. Too bad the counter is not being reset, so when the same {{SaxHandler}} \
parses another, valid XML message, the same exception is thrown again. This only \
happens when using the default XMLReader {{Piccolo}}, since its {{PiccoloSaxHandler}} \
is cached:

{code}
    private static SaxLoader getPiccoloSaxLoader()
    {
        SaxLoader piccoloLoader = (SaxLoader) SystemCache.get().getSaxLoader();
        if (piccoloLoader == null)
        {
            piccoloLoader = PiccoloSaxLoader.newInstance();
            SystemCache.get().setSaxLoader(piccoloLoader);
        }
        return piccoloLoader;
    }
{code}

When using a differend XMLReader, everything is fine since the XMLReader is never \
cached:

{code}
        if (options.hasOption(XmlOptions.LOAD_USE_XMLREADER))
        {
            XMLReader xr = (XMLReader) options.get(
                XmlOptions.LOAD_USE_XMLREADER);

            if (xr == null)
                throw new IllegalArgumentException("XMLReader is null");

            sl = new XmlReaderSaxLoader(xr);

            // I've noticed that most XMLReaders don't like a null EntityResolver...

            if (er != null)
                xr.setEntityResolver(er);
        }
{code}

The following example reproduces the problem:

{code}
package xmlbeansbug;

import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.common.SystemCache;
import org.apache.xmlbeans.impl.store.Locale;
import org.xml.sax.SAXException;


public class Bug {

  private static final String BILLION_LAUGHS = "<?xml version=\"1.0\"?>\n" +
      "<!DOCTYPE lolz [\n" +
      "    <!ENTITY lol \"lol\">\n" +
      "    <!ELEMENT lolz (#PCDATA)>\n" +
      "    <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
      "    <!ENTITY lol2 \
                \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" \
                +
      "    <!ENTITY lol3 \
                \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" \
                +
      "    <!ENTITY lol4 \
                \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" \
                +
      "    <!ENTITY lol5 \
                \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" \
                +
      "    <!ENTITY lol6 \
                \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" \
                +
      "    <!ENTITY lol7 \
                \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" \
                +
      "    <!ENTITY lol8 \
                \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" \
                +
      "    <!ENTITY lol9 \
\"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +  "]>\n" +
      "<lolz>&lol9;</lolz>";

  private static final String VALID_XML = "<?xml version=\"1.0\"?>\n" +
      "<root>foobar</root>";

  public static void main(String[] args) throws IOException, SAXException, \
XmlException, ParserConfigurationException {  new Bug().demonstrate();
  }

  private void demonstrate() throws IOException, SAXException, XmlException, \
ParserConfigurationException {  Locale.parseToXmlObject(null, VALID_XML, null, new \
XmlOptions());  System.out.println("1. Valid XML message was parsed successfully");

    try {
      Locale.parseToXmlObject(null, BILLION_LAUGHS, null, new XmlOptions());
    } catch (XmlException e) {
      System.err.println("2. Billion Laughs XML could not be parsed: " + \
e.getMessage());  }

    try {
      Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
    } catch (XmlException e) {
      System.err.println("3. Now, parsing a valid XML message also throws an \
exception");  }

    XmlOptions xmlOptions = new XmlOptions();
    xmlOptions.setLoadUseXMLReader(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
  Locale.parseToXmlObject(null, VALID_XML, null, xmlOptions);

    System.out.println("4. When using a different parser, everything's fine");

    SystemCache.get().setSaxLoader(null);
    Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());

    System.out.println("5. After resetting the cached SaxLoader, Piccolo works \
again");  }
}
{code}

  was:
In {{SaxHandler}}, if an XML entity exceeds the entity byte limit, an exception is \
thrown. Too bad the counter is not being reset, so when the same {{SaxHandler}} \
parses another, valid XML message, the same exception is thrown again. This only \
happens when using the default XMLReader {{Piccolo}}, since its {{PiccoloSaxHandler}} \
is cached:

{code}
    private static SaxLoader getPiccoloSaxLoader()
    {
        SaxLoader piccoloLoader = (SaxLoader) SystemCache.get().getSaxLoader();
        if (piccoloLoader == null)
        {
            piccoloLoader = PiccoloSaxLoader.newInstance();
            SystemCache.get().setSaxLoader(piccoloLoader);
        }
        return piccoloLoader;
    }
{code}

When using a differend XMLReader, everything is fine since the XMLReader is never \
cached:

{code}
        if (options.hasOption(XmlOptions.LOAD_USE_XMLREADER))
        {
            XMLReader xr = (XMLReader) options.get(
                XmlOptions.LOAD_USE_XMLREADER);

            if (xr == null)
                throw new IllegalArgumentException("XMLReader is null");

            sl = new XmlReaderSaxLoader(xr);

            // I've noticed that most XMLReaders don't like a null EntityResolver...

            if (er != null)
                xr.setEntityResolver(er);
        }
{code}

The following example reproduces the problem:

{code}
package xmlbeansbug;

import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.common.SystemCache;
import org.apache.xmlbeans.impl.store.Locale;
import org.xml.sax.SAXException;


public class Bug {

  private static final String BILLION_LAUGHS = "<?xml version=\"1.0\"?>\n" +
      "<!DOCTYPE lolz [\n" +
      "    <!ENTITY lol \"lol\">\n" +
      "    <!ELEMENT lolz (#PCDATA)>\n" +
      "    <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
      "    <!ENTITY lol2 \
                \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" \
                +
      "    <!ENTITY lol3 \
                \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" \
                +
      "    <!ENTITY lol4 \
                \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" \
                +
      "    <!ENTITY lol5 \
                \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" \
                +
      "    <!ENTITY lol6 \
                \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" \
                +
      "    <!ENTITY lol7 \
                \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" \
                +
      "    <!ENTITY lol8 \
                \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" \
                +
      "    <!ENTITY lol9 \
\"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +  "]>\n" +
      "<lolz>&lol9;</lolz>";

  private static final String VALID_XML = "<?xml version=\"1.0\"?>\n" +
      "<root>foobar</root>";

  public static void main(String[] args) throws IOException, SAXException, \
XmlException, ParserConfigurationException {  new Bug().demonstrate();
  }

  private void demonstrate() throws IOException, SAXException, XmlException, \
ParserConfigurationException {  Locale.parseToXmlObject(null, VALID_XML, null, new \
XmlOptions());  System.out.println("1. Valid XML message was parsed successfully");

    try {
      Locale.parseToXmlObject(null, BILLION_LAUGHS, null, new XmlOptions());
    } catch (XmlException e) {
      System.err.println("2. Billion Laughs XML could not be parsed: " + \
e.getMessage());  }

    try {
      Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
    } catch (XmlException e) {
      System.err.println("3. Now, parsing a valid XML message also throws an \
exception");  }

    XmlOptions xmlOptions = new XmlOptions();
    xmlOptions.setLoadUseXMLReader(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
  Locale.parseToXmlObject(null, VALID_XML, null, xmlOptions);

    System.out.println("4. When using a different parser, everything's fine");

    SystemCache.get().setSaxLoader(null);
    Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());

    System.out.println("5. After resetting the cached SaxLoader, Piccolo works \
again");  }
}
{code}

The problem's here (Locale.java:3296):

{code}
            if (_insideEntity!=0)
            {
                if ((_entityBytes += length) > _entityBytesLimit)
                {
                    XmlError err = \
                XmlError.forMessage(XmlErrorCodes.EXCEPTION_EXCEEDED_ENTITY_BYTES,
                            new Integer[]{ new Integer(_entityBytesLimit) });

                    throw new SAXException(err.getMessage());
                }
            }
{code}


> SaxHandler should be reset on exception
> ---------------------------------------
> 
> Key: XMLBEANS-512
> URL: https://issues.apache.org/jira/browse/XMLBEANS-512
> Project: XMLBeans
> Issue Type: Bug
> Affects Versions: Version 2.6
> Reporter: Michel Jung
> 
> In {{SaxHandler}}, if an XML entity exceeds the entity byte limit, an exception is \
> thrown. Too bad the counter is not being reset, so when the same {{SaxHandler}} \
> parses another, valid XML message, the same exception is thrown again. This only \
> happens when using the default XMLReader {{Piccolo}}, since its \
> {{PiccoloSaxHandler}} is cached: {code}
> private static SaxLoader getPiccoloSaxLoader()
> {
> SaxLoader piccoloLoader = (SaxLoader) SystemCache.get().getSaxLoader();
> if (piccoloLoader == null)
> {
> piccoloLoader = PiccoloSaxLoader.newInstance();
> SystemCache.get().setSaxLoader(piccoloLoader);
> }
> return piccoloLoader;
> }
> {code}
> When using a differend XMLReader, everything is fine since the XMLReader is never \
> cached: {code}
> if (options.hasOption(XmlOptions.LOAD_USE_XMLREADER))
> {
> XMLReader xr = (XMLReader) options.get(
> XmlOptions.LOAD_USE_XMLREADER);
> if (xr == null)
> throw new IllegalArgumentException("XMLReader is null");
> sl = new XmlReaderSaxLoader(xr);
> // I've noticed that most XMLReaders don't like a null EntityResolver...
> if (er != null)
> xr.setEntityResolver(er);
> }
> {code}
> The following example reproduces the problem:
> {code}
> package xmlbeansbug;
> import java.io.IOException;
> import javax.xml.parsers.ParserConfigurationException;
> import javax.xml.parsers.SAXParserFactory;
> import org.apache.xmlbeans.XmlException;
> import org.apache.xmlbeans.XmlOptions;
> import org.apache.xmlbeans.impl.common.SystemCache;
> import org.apache.xmlbeans.impl.store.Locale;
> import org.xml.sax.SAXException;
> public class Bug {
> private static final String BILLION_LAUGHS = "<?xml version=\"1.0\"?>\n" +
> "<!DOCTYPE lolz [\n" +
> "    <!ENTITY lol \"lol\">\n" +
> "    <!ELEMENT lolz (#PCDATA)>\n" +
> "    <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
> "    <!ENTITY lol2 \
> \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" + "    \
> <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" \
> + "    <!ENTITY lol4 \
> \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" + "    \
> <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" \
> + "    <!ENTITY lol6 \
> \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" + "    \
> <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" \
> + "    <!ENTITY lol8 \
> \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" + "    \
> <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" \
> + "]>\n" +
> "<lolz>&lol9;</lolz>";
> private static final String VALID_XML = "<?xml version=\"1.0\"?>\n" +
> "<root>foobar</root>";
> public static void main(String[] args) throws IOException, SAXException, \
> XmlException, ParserConfigurationException { new Bug().demonstrate();
> }
> private void demonstrate() throws IOException, SAXException, XmlException, \
> ParserConfigurationException { Locale.parseToXmlObject(null, VALID_XML, null, new \
> XmlOptions()); System.out.println("1. Valid XML message was parsed successfully");
> try {
> Locale.parseToXmlObject(null, BILLION_LAUGHS, null, new XmlOptions());
> } catch (XmlException e) {
> System.err.println("2. Billion Laughs XML could not be parsed: " + e.getMessage());
> }
> try {
> Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
> } catch (XmlException e) {
> System.err.println("3. Now, parsing a valid XML message also throws an exception");
> }
> XmlOptions xmlOptions = new XmlOptions();
> xmlOptions.setLoadUseXMLReader(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
>  Locale.parseToXmlObject(null, VALID_XML, null, xmlOptions);
> System.out.println("4. When using a different parser, everything's fine");
> SystemCache.get().setSaxLoader(null);
> Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
> System.out.println("5. After resetting the cached SaxLoader, Piccolo works again");
> }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.2#6252)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: dev-help@xmlbeans.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic