Introducing a default maximum entity replacement limit of 10kb, it can be controled by using the option XmlOptions.setLoadEntityBytesLimit.
Contribution by Jerry Sy.
git-svn-id: https://svn.apache.org/repos/asf/xmlbeans/trunk@1241680 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/store/org/apache/xmlbeans/impl/store/Locale.java b/src/store/org/apache/xmlbeans/impl/store/Locale.java
index ebf96a2..1f02a16 100755
--- a/src/store/org/apache/xmlbeans/impl/store/Locale.java
+++ b/src/store/org/apache/xmlbeans/impl/store/Locale.java
@@ -15,6 +15,7 @@
package org.apache.xmlbeans.impl.store;
+import org.apache.xmlbeans.XmlErrorCodes;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@@ -95,10 +96,8 @@
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlTokenSource;
-import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.QNameCache;
-import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlRuntimeException;
import org.apache.xmlbeans.XmlDocumentProperties;
@@ -3173,6 +3172,9 @@
_wantCdataBookmarks =
_startLocator != null &&
options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS);
+
+ if (options.hasOption(XmlOptions.LOAD_ENTITY_BYTES_LIMIT))
+ _entityBytesLimit = ((Integer)(options.get(XmlOptions.LOAD_ENTITY_BYTES_LIMIT))).intValue();
}
public void startDocument()
@@ -3287,8 +3289,20 @@
throws SAXException
{
_context.text(ch, start, length);
+
if (_wantCdataBookmarks && _insideCDATA)
_context.bookmarkLastNonAttr(CDataBookmark.CDATA_BOOKMARK);
+
+ 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());
+ }
+ }
}
public void ignorableWhitespace(char ch[], int start, int length)
@@ -3361,13 +3375,19 @@
public void startEntity(String name)
throws SAXException
{
-// throw new RuntimeException( "Not impl: startEntity" );
+ _insideEntity++;
}
public void endEntity(String name)
throws SAXException
{
-// throw new RuntimeException( "Not impl: endEntity" );
+ _insideEntity--;
+ assert _insideEntity>=0;
+
+ if (_insideEntity==0)
+ {
+ _entityBytes=0;
+ }
}
public void setDocumentLocator(Locator locator)
@@ -3401,6 +3421,9 @@
private boolean _wantCdataBookmarks;
private Locator _startLocator;
private boolean _insideCDATA = false;
+ private int _entityBytesLimit = 10240;
+ private int _entityBytes = 0;
+ private int _insideEntity = 0;
}
private static abstract class SaxLoader
diff --git a/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java b/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java
index b896b9f..0a3c924 100644
--- a/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java
+++ b/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java
@@ -65,6 +65,7 @@
public static final String INVALID_DOCUMENT_TYPE = "invalid.document.type";
public static final String CANNOT_LOAD_FILE = "cannot.load.file";
+ public static final String EXCEPTION_EXCEEDED_ENTITY_BYTES = "exceeded-entity-bytes";
public static final String EXCEPTION_LOADING_URL = "exception.loading.url";
public static final String EXCEPTION_VALUE_NOT_SUPPORTED_J2S = "exception.value.not.supported.j2s";
public static final String EXCEPTION_VALUE_NOT_SUPPORTED_S2J = "exception.value.not.supported.s2j";
diff --git a/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java b/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
index 135a4f8..6af8ceb 100644
--- a/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
+++ b/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
@@ -861,6 +861,17 @@
return set(COPY_USE_NEW_SYNC_DOMAIN, useNewSyncDomain ? Boolean.TRUE : Boolean.FALSE );
}
+ /**
+ * Sets the maximum number of bytes allowed when an Entity is expanded during parsing.
+ * The default value is 10240 bytes.
+ * @param entityBytesLimit
+ * @return
+ */
+ public XmlOptions setLoadEntityBytesLimit (int entityBytesLimit)
+ {
+ return set(LOAD_ENTITY_BYTES_LIMIT,entityBytesLimit);
+ }
+
public static final String GENERATE_JAVA_14 = "1.4";
public static final String GENERATE_JAVA_15 = "1.5";
@@ -983,6 +994,8 @@
public static final String GENERATE_JAVA_VERSION = "GENERATE_JAVA_VERSION";
/** @exclude */
public static final String COPY_USE_NEW_SYNC_DOMAIN = "COPY_USE_NEW_LOCALE";
+ /** @exclude */
+ public static final String LOAD_ENTITY_BYTES_LIMIT = "LOAD_ENTITY_BYTES_LIMIT";
private static final XmlOptions EMPTY_OPTIONS;
static {
diff --git a/src/xmlpublic/org/apache/xmlbeans/message.properties b/src/xmlpublic/org/apache/xmlbeans/message.properties
index 1c53e5b..80d970b 100644
--- a/src/xmlpublic/org/apache/xmlbeans/message.properties
+++ b/src/xmlpublic/org/apache/xmlbeans/message.properties
@@ -970,3 +970,5 @@
invalid-xpath = \
Invalid xpath in identity constraint: {0}
+exceeded-entity-bytes = \
+Exceeded Entity dereference bytes limit, limit is {0} bytes.
\ No newline at end of file