neeraj 2003/01/16 10:40:31
Modified: java/src/org/apache/xerces/util SecurityManager.java
java/src/org/apache/xerces/impl/xs/models CMBuilder.java
java/src/org/apache/xerces/impl/xs XMLSchemaValidator.java
XMLSchemaLoader.java
Log:
Fixing another security problem. High value of maxOccur attirbute causes
stackoverflow error. When application switches the mode of parser to behave in
security conscious way using SecurityConfiguration. It sets the maximum number of
nodes that should be created when building
content model from maxOccurs attribute value specified in schema document, number of
nodes created depneds upon the type of content model and value of maxOccurs
attribute.Current limit of maximum number ofnodes has been set to 3000. However, it
can be set to higher value if required by the application using SecurityManager Object.
Revision Changes Path
1.2 +23 -1 xml-xerces/java/src/org/apache/xerces/util/SecurityManager.java
Index: SecurityManager.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/util/SecurityManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SecurityManager.java 8 Jan 2003 23:03:12 -0000 1.1
+++ SecurityManager.java 16 Jan 2003 18:40:29 -0000 1.2
@@ -83,6 +83,9 @@
// default value for entity expansion limit
private final static int DEFAULT_ENTITY_EXPANSION_LIMIT = 100000;
+
+ //default value of number of nodes created
+ private final static int DEFAULT_MAX_OCCUR_NODE_LIMIT = 3000;
//
// Data
@@ -90,11 +93,13 @@
/** entity expansion limit */
private int entityExpansionLimit;
+ private int maxOccurLimit;
// default constructor. Establishes default values for
// all known security holes.
public SecurityManager() {
entityExpansionLimit = DEFAULT_ENTITY_EXPANSION_LIMIT;
+ maxOccurLimit = DEFAULT_MAX_OCCUR_NODE_LIMIT ;
}
// set the number of entity expansions that the
@@ -108,5 +113,22 @@
public int getEntityExpansionLimit() {
return entityExpansionLimit;
}
+
+ //sets the limit of the number of nodes that should be allowed to create when
building
+ //content model from maxOccurs attribute value specified in schema document,
number of nodes
+ //created depneds upon the type of content model and value of maxOccurs
attribute.
+ public void setMaxOccurNodeLimit(int limit){
+ maxOccurLimit = limit ;
+ }
+
+
+ //get the limit of the number of nodes that should be allowed to create when
building
+ //content model from maxOccurs attribute value specified in schema document,
number of nodes
+ //created depneds upon the type of content model and value of maxOccurs
attribute.
+
+ public int getMaxOccurNodeLimit(){
+ return maxOccurLimit ;
+ }
+
} // class SecurityManager
1.15 +28 -20
xml-xerces/java/src/org/apache/xerces/impl/xs/models/CMBuilder.java
Index: CMBuilder.java
===================================================================
RCS file:
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/CMBuilder.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- CMBuilder.java 8 Nov 2002 15:55:31 -0000 1.14
+++ CMBuilder.java 16 Jan 2003 18:40:29 -0000 1.15
@@ -87,14 +87,22 @@
private int fLeafCount;
// needed for UPA
private int fParticleCount;
+ //Factory to create Bin, Uni, Leaf nodes
+ private CMNodeFactory fNodeFactory ;
- public CMBuilder() {
+ public CMBuilder(CMNodeFactory nodeFactory) {
fDeclPool = null;
+ fNodeFactory = nodeFactory ;
}
public CMBuilder(XSDeclarationPool pool) {
fDeclPool = pool;
- }
+ //xxx is this constructor used ? but there would be nothing wrong if
factory is created.. but we dont have security manager set.
+ if(fNodeFactory == null)
+ {
+ fNodeFactory = CMNodeFactory.newInstance();
+ }
+ }//CMBuilder
public void setDeclPool(XSDeclarationPool declPool) {
fDeclPool = declPool;
@@ -107,7 +115,7 @@
* @return a content model validator
*/
public XSCMValidator getContentModel(XSComplexTypeDecl typeDecl) {
-
+
// for complex type with empty or simple content,
// there is no content model validator
short contentType = typeDecl.getContentType();
@@ -117,7 +125,7 @@
}
XSParticleDecl particle = (XSParticleDecl)typeDecl.getParticle();
-
+
// if the content is element only or mixed, but no particle
// is defined, return the empty content model
if (particle == null)
@@ -194,7 +202,7 @@
// are two references to the same group, we have two different
// leaf particles for the same element or wildcard decl.
// This is useful for checking UPA.
- nodeRet = new XSCMLeaf(particle.fType, particle.fValue,
fParticleCount++, fLeafCount++);
+ nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue,
fParticleCount++, fLeafCount++);
// (task 2) expand occurrence values
nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs);
}
@@ -222,7 +230,7 @@
nodeRet = temp;
}
else {
- nodeRet = new XSCMBinOp(group.fCompositor, nodeRet, temp);
+ nodeRet = fNodeFactory.getCMBinOpNode(group.fCompositor,
nodeRet, temp);
// record the fact that there are at least 2 children
twoChildren = true;
}
@@ -236,7 +244,7 @@
// particle.
if (group.fCompositor == XSModelGroupImpl.MODELGROUP_CHOICE &&
!twoChildren && group.fParticleCount > 1) {
- nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_ONE,
nodeRet);
+ nodeRet =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, nodeRet);
}
nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs);
}
@@ -258,27 +266,27 @@
}
else if (minOccurs==0 && maxOccurs==1) {
//zero or one
- nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
+ nodeRet =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
}
else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//zero or more
- nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_MORE, node);
+ nodeRet =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_MORE, node);
}
else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//one or more
- nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
+ nodeRet =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
}
else if (maxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) {
// => a,a,..,a+
// create a+ node first, then put minOccurs-1 a's in front of it
// for the first time "node" is used, we don't need to make a copy
// and for other references to node, we make copies
- nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
+ nodeRet =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
for (int i=0; i < minOccurs-1; i++) {
// (task 4) we need to call copyNode here, so that we append
// an entire new copy of the node (a subtree). this is to ensure
// all leaf nodes have distinct position
- nodeRet = new XSCMBinOp(XSModelGroupImpl.MODELGROUP_SEQUENCE,
+ nodeRet =
fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE,
copyNode(node), nodeRet);
}
}
@@ -289,21 +297,21 @@
if (minOccurs > 0) {
nodeRet = node;
for (int i=0; i<minOccurs-1; i++) {
- nodeRet = new XSCMBinOp(XSModelGroupImpl.MODELGROUP_SEQUENCE,
+ nodeRet =
fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE,
nodeRet, copyNode(node));
}
}
if (maxOccurs > minOccurs) {
- node = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
+ node =
fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
if (nodeRet == null) {
nodeRet = node;
}
else {
- nodeRet = new XSCMBinOp(XSModelGroupImpl.MODELGROUP_SEQUENCE,
+ nodeRet =
fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE,
nodeRet, copyNode(node));
}
for (int i=minOccurs; i<maxOccurs-1; i++) {
- nodeRet = new XSCMBinOp(XSModelGroupImpl.MODELGROUP_SEQUENCE,
+ nodeRet =
fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE,
nodeRet, copyNode(node));
}
}
@@ -319,7 +327,7 @@
if (type == XSModelGroupImpl.MODELGROUP_CHOICE ||
type == XSModelGroupImpl.MODELGROUP_SEQUENCE) {
XSCMBinOp bin = (XSCMBinOp)node;
- node = new XSCMBinOp(type, copyNode(bin.getLeft()),
+ node = fNodeFactory.getCMBinOpNode(type, copyNode(bin.getLeft()),
copyNode(bin.getRight()));
}
// for ?+*, copy the subtree, and put it in a new ?+* node
@@ -327,14 +335,14 @@
type == XSParticleDecl.PARTICLE_ONE_OR_MORE ||
type == XSParticleDecl.PARTICLE_ZERO_OR_ONE) {
XSCMUniOp uni = (XSCMUniOp)node;
- node = new XSCMUniOp(type, copyNode(uni.getChild()));
+ node = fNodeFactory.getCMUniOpNode(type, copyNode(uni.getChild()));
}
// for element/wildcard (leaf), make a new leaf node,
// with a distinct position
else if (type == XSParticleDecl.PARTICLE_ELEMENT ||
type == XSParticleDecl.PARTICLE_WILDCARD) {
XSCMLeaf leaf = (XSCMLeaf)node;
- node = new XSCMLeaf(leaf.type(), leaf.getLeaf(), leaf.getParticleId(),
fLeafCount++);
+ node = fNodeFactory.getCMLeafNode(leaf.type(), leaf.getLeaf(),
leaf.getParticleId(), fLeafCount++);
}
return node;
1.129 +8 -3
xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
Index: XMLSchemaValidator.java
===================================================================
RCS file:
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -r1.128 -r1.129
--- XMLSchemaValidator.java 14 Jan 2003 20:21:45 -0000 1.128
+++ XMLSchemaValidator.java 16 Jan 2003 18:40:30 -0000 1.129
@@ -118,6 +118,7 @@
import java.util.Stack;
import java.util.Vector;
import java.io.IOException;
+import org.apache.xerces.impl.xs.models.CMNodeFactory;
/**
* The XML Schema validator. The validator implements a document
@@ -1070,10 +1071,11 @@
// REVISIT: in new simple type design, make things in DVs static,
// so that we can QNameDV.getCompiledForm()
final XSSimpleType fQNameDV =
(XSSimpleType)SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
-
+
+ final CMNodeFactory nodeFactory = CMNodeFactory.newInstance();
/** used to build content models */
// REVISIT: create decl pool, and pass it to each traversers
- final CMBuilder fCMBuilder = new CMBuilder();
+ final CMBuilder fCMBuilder = new CMBuilder(nodeFactory);
// state
@@ -1374,6 +1376,9 @@
catch (XMLConfigurationException e){
}
+ //pass the component manager to the factory..
+ nodeFactory.reset(componentManager);
+
// clear grammars, and put the one for schema namespace there
// logic for resetting grammar-related components moved
// to schema loader
1.13 +7 -2
xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaLoader.java
Index: XMLSchemaLoader.java
===================================================================
RCS file:
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaLoader.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- XMLSchemaLoader.java 11 Nov 2002 20:47:31 -0000 1.12
+++ XMLSchemaLoader.java 16 Jan 2003 18:40:31 -0000 1.13
@@ -88,6 +88,8 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Vector;
+import org.apache.xerces.impl.xs.models.CMNodeFactory;
+
/**
* This class implements XMLGrammarLoader. It is designed to interact
* either with a proxy for a user application which wants to preparse schemas,
@@ -238,8 +240,11 @@
sHandler = new SubstitutionGroupHandler(fGrammarBucket);
}
fSubGroupHandler = sHandler;
+ //get the factory instance.. this class is singleton
+ CMNodeFactory nodeFactory = CMNodeFactory.newInstance() ;
+ //REVISIT: shouldn't the SecurityManager be allowed to set, if an
application tries to load standalone schema - nb.
if(builder == null) {
- builder = new CMBuilder();
+ builder = new CMBuilder(nodeFactory);
}
fCMBuilder = builder;
fSchemaHandler = new XSDHandler(fGrammarBucket);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]