[
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.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. 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 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.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 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.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. 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: [email protected]
For additional commands, e-mail: [email protected]