[ 
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 parsing another, 
valid XML message, the same exception is thrown again. However, this only 
happens when using the default XMLReader {{Piccolo}}, since 
{{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.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.out.println("2. Billion Laughs XML could not be parsed: " + 
e.getMessage());
    }

    try {
      Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
    } catch (XmlException e) {
      System.out.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. Using the JDK parser, everything's fine");
  }
}
{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}

  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 parsing another, valid 
XML message, the same exception is thrown again. However, this only happens 
when using the default XMLReader {{Piccolo}}, since {{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.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.out.println("2. Billion Laughs XML could not be parsed: " + 
e.getMessage());
    }

    try {
      Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
    } catch (XmlException e) {
      System.out.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. Using the JDK parser, everything's fine");
  }
}
{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 parsing 
> another, valid XML message, the same exception is thrown again. However, this 
> only happens when using the default XMLReader {{Piccolo}}, since 
> {{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.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.out.println("2. Billion Laughs XML could not be parsed: " + 
> e.getMessage());
>     }
>     try {
>       Locale.parseToXmlObject(null, VALID_XML, null, new XmlOptions());
>     } catch (XmlException e) {
>       System.out.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. Using the JDK parser, everything's fine");
>   }
> }
> {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}



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

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

Reply via email to