[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