Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[bugfix] Check for potential overflow in symbol table before data is …

…stored to prevent corrupted documents. Give user a chance to remove the (probably bad) data.
  • Loading branch information...
commit 9e36f9130449265d87d8d7ad3c6113a0c30d7859 1 parent 1d6b029
Wolfgang Meier wolfgangmm authored
34 src/org/exist/Indexer.java
View
@@ -54,6 +54,7 @@
import org.exist.util.pool.NodePool;
import org.exist.xquery.Constants;
import org.exist.xquery.value.StringValue;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
@@ -573,11 +574,15 @@ public void startElement(String namespace, String name, String qname,
}
charBuf.reset();
}
- if (!usedElements.isEmpty()) {
- node = usedElements.pop();
- node.setNodeName(qn);
- } else {
- node = new ElementImpl(qn);
+ try {
+ if (!usedElements.isEmpty()) {
+ node = usedElements.pop();
+ node.setNodeName(qn, broker.getBrokerPool().getSymbols());
+ } else {
+ node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
+ }
+ } catch (DOMException e) {
+ throw new SAXException(e.getMessage(), e);
}
// copy xml:space setting
node.setPreserveSpace(last.preserveSpace());
@@ -601,10 +606,10 @@ public void startElement(String namespace, String name, String qname,
storeElement(node);
}
} else {
- if (validate) {
- node = new ElementImpl(qn);
- } else {
- node = new ElementImpl(qn);
+ try {
+ node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
+ } catch (DOMException e) {
+ throw new SAXException(e.getMessage(), e);
}
rootNode = node;
setPrevious(null);
@@ -643,10 +648,13 @@ public void startElement(String namespace, String name, String qname,
p = attrQName.indexOf(':');
attrPrefix = (p != Constants.STRING_NOT_FOUND) ?
attrQName.substring(0, p) : null;
- final AttrImpl attr = (AttrImpl) NodePool.getInstance()
- .borrowNode(Node.ATTRIBUTE_NODE);
- attr.setNodeName(broker.getBrokerPool().getSymbols()
- .getQName(Node.ATTRIBUTE_NODE, attrNS, attrLocalName, attrPrefix));
+ final AttrImpl attr = (AttrImpl) NodePool.getInstance().borrowNode(Node.ATTRIBUTE_NODE);
+ final QName attrQN = broker.getBrokerPool().getSymbols().getQName(Node.ATTRIBUTE_NODE, attrNS, attrLocalName, attrPrefix);
+ try {
+ attr.setNodeName(attrQN, broker.getBrokerPool().getSymbols());
+ } catch (DOMException e) {
+ throw new SAXException(e.getMessage(), e);
+ }
attr.setValue(attributes.getValue(i));
attr.setOwnerDocument(document);
if (attributes.getType(i).equals(ATTR_ID_TYPE)) {
15 src/org/exist/dom/AttrImpl.java
View
@@ -61,17 +61,16 @@ public AttrImpl() {
super(Node.ATTRIBUTE_NODE);
}
- public AttrImpl (QName name) {
+ public AttrImpl (QName name, SymbolTable symbols) throws DOMException {
super( Node.ATTRIBUTE_NODE, name);
+ if (symbols != null && symbols.getSymbol(nodeName.getLocalName()) < 0) {
+ throw new DOMException(DOMException.INVALID_ACCESS_ERR,
+ "Too many element/attribute names registered in the database. No of distinct names is limited to 16bit. Aborting store.");
+ }
}
- public AttrImpl( QName name, XMLString value ) {
- super( Node.ATTRIBUTE_NODE, name);
- this.value = value;
- }
-
- public AttrImpl (QName name, String str) {
- super( Node.ATTRIBUTE_NODE, name);
+ public AttrImpl (QName name, String str, SymbolTable symbols) throws DOMException {
+ this(name, symbols);
this.value = new XMLString( str.toCharArray() );
}
8 src/org/exist/dom/DocumentImpl.java
View
@@ -878,7 +878,7 @@ public Node getNextSibling() {
* @exception DOMException if an error occurs
*/
public Attr createAttribute(String name) throws DOMException {
- final AttrImpl attr = new AttrImpl(new QName(name, "", null));
+ final AttrImpl attr = new AttrImpl(new QName(name, "", null), getBrokerPool().getSymbols());
attr.setOwnerDocument(this);
return attr;
}
@@ -902,7 +902,7 @@ public Attr createAttributeNS(String namespaceURI, String qualifiedName) throws
prefix = qualifiedName.substring(0, p);
name = qualifiedName.substring(p);
}
- final AttrImpl attr = new AttrImpl(new QName(name, namespaceURI, prefix));
+ final AttrImpl attr = new AttrImpl(new QName(name, namespaceURI, prefix), getBrokerPool().getSymbols());
attr.setOwnerDocument(this);
return attr;
}
@@ -915,7 +915,7 @@ public Attr createAttributeNS(String namespaceURI, String qualifiedName) throws
* @exception DOMException if an error occurs
*/
public Element createElement(String tagName) throws DOMException {
- final ElementImpl element = new ElementImpl(new QName(tagName, "", null));
+ final ElementImpl element = new ElementImpl(new QName(tagName, "", null), getBrokerPool().getSymbols());
element.setOwnerDocument(this);
return element;
}
@@ -939,7 +939,7 @@ public Element createElementNS(String namespaceURI, String qualifiedName) throws
prefix = qualifiedName.substring(0, p);
name = qualifiedName.substring(p);
}
- final ElementImpl element = new ElementImpl(new QName(name, namespaceURI, prefix));
+ final ElementImpl element = new ElementImpl(new QName(name, namespaceURI, prefix), getBrokerPool().getSymbols());
element.setOwnerDocument(this);
return element;
}
13 src/org/exist/dom/ElementImpl.java
View
@@ -100,9 +100,13 @@ public ElementImpl() {
*
* @param nodeName Description of the Parameter
*/
- public ElementImpl(QName nodeName) {
+ public ElementImpl(QName nodeName, SymbolTable symbols) throws DOMException {
super(Node.ELEMENT_NODE, nodeName);
this.nodeName = nodeName;
+ if (symbols.getSymbol(nodeName.getLocalName()) < 0) {
+ throw new DOMException(DOMException.INVALID_ACCESS_ERR,
+ "Too many element/attribute names registered in the database. No of distinct names is limited to 16bit. Aborting store.");
+ }
}
public ElementImpl(ElementImpl other) {
@@ -555,7 +559,8 @@ private Node appendChild(Txn transaction, NodeId newNodeId, NodeImplRef last, No
new QName(child.getLocalName() == null ?
child.getNodeName() : child.getLocalName(),
child.getNamespaceURI(),
- child.getPrefix())
+ child.getPrefix()),
+ broker.getBrokerPool().getSymbols()
);
elem.setNodeId(newNodeId);
elem.setOwnerDocument(owner);
@@ -620,7 +625,7 @@ private Node appendChild(Txn transaction, NodeId newNodeId, NodeImplRef last, No
String name = attr.getLocalName();
if (name == null) {name = attr.getName();}
final QName attrName = new QName(name, ns, prefix);
- final AttrImpl attrib = new AttrImpl(attrName, attr.getValue());
+ final AttrImpl attrib = new AttrImpl(attrName, attr.getValue(), broker.getBrokerPool().getSymbols());
attrib.setNodeId(newNodeId);
attrib.setOwnerDocument(owner);
if (ns != null && attrName.compareTo(Namespaces.XML_ID_QNAME) == Constants.EQUAL) {
@@ -754,7 +759,7 @@ public NamedNodeMap getAttributes() {
final String prefix = entry.getKey().toString();
final String ns = entry.getValue().toString();
final QName attrName = new QName(prefix, Namespaces.XMLNS_NS, "xmlns");
- final AttrImpl attr = new AttrImpl(attrName, ns);
+ final AttrImpl attr = new AttrImpl(attrName, ns, null);
attr.setOwnerDocument(ownerDocument);
map.setNamedItem(attr);
}
9 src/org/exist/dom/NamedNode.java
View
@@ -23,6 +23,7 @@
package org.exist.dom;
import org.exist.numbering.NodeId;
+import org.w3c.dom.DOMException;
/**
* A node with a QName, i.e. an element or attribute.
@@ -74,6 +75,14 @@ public void setNodeName(QName name) {
nodeName = name;
}
+ public void setNodeName(QName name, SymbolTable symbols) throws DOMException {
+ nodeName = name;
+ if (symbols.getSymbol(nodeName.getLocalName()) < 0) {
+ throw new DOMException(DOMException.INVALID_ACCESS_ERR,
+ "Too many element/attribute names registered in the database. No of distinct names is limited to 16bit. Aborting store.");
+ }
+ }
+
/* (non-Javadoc)
* @see org.exist.dom.NodeImpl#clear()
*/
7 src/org/exist/dom/SymbolTable.java
View
@@ -497,7 +497,12 @@ public synchronized int getId(String name) {
if (id != -1) {
return id;
}
- id = add(++offset, name);
+ // symbol space exceeded. return -1 to indicate.
+ if (offset == Short.MAX_VALUE) {
+ return -1;
+ }
+
+ id = add(++offset, name);
//we use "++offset" here instead of "offset++",
//because the system expects id's to start at 1, not 0
write(id, name);
6 src/org/exist/memtree/DOMIndexer.java
View
@@ -101,7 +101,7 @@ public void scan() throws EXistException {
*/
public void store() {
//Create a wrapper element as root node
- final ElementImpl elem = new ElementImpl(ROOT_QNAME);
+ final ElementImpl elem = new ElementImpl(ROOT_QNAME, broker.getBrokerPool().getSymbols());
elem.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance());
elem.setOwnerDocument(targetDoc);
elem.setChildCount(doc.getChildCount());
@@ -266,7 +266,7 @@ private void initElement( int nodeNr, ElementImpl elem )
elem.setOwnerDocument( targetDoc );
elem.setAttributes( attribs );
elem.setChildCount( doc.getChildCountFor( nodeNr ) + attribs );
- elem.setNodeName( doc.nodeName[nodeNr] );
+ elem.setNodeName( doc.nodeName[nodeNr], broker.getBrokerPool().getSymbols() );
final Map<String, String> ns = getNamespaces( nodeNr );
if( ns != null ) {
@@ -316,7 +316,7 @@ private void storeAttributes( int nodeNr, ElementImpl elem, NodePath path ) thro
while( ( attr < doc.nextAttr ) && ( doc.attrParent[attr] == nodeNr ) ) {
final QName qn = doc.attrName[attr];
final AttrImpl attrib = (AttrImpl)NodePool.getInstance().borrowNode( Node.ATTRIBUTE_NODE );
- attrib.setNodeName( qn );
+ attrib.setNodeName( qn, broker.getBrokerPool().getSymbols() );
attrib.setValue( doc.attrValue[attr] );
attrib.setOwnerDocument( targetDoc );
elem.appendChildInternal( prevNode, attrib );
4 src/org/exist/xquery/update/Rename.java
View
@@ -149,12 +149,12 @@ public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathExc
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
final ElementImpl newElem = new ElementImpl((ElementImpl) node);
- newElem.setNodeName(newQName);
+ newElem.setNodeName(newQName, context.getBroker().getBrokerPool().getSymbols());
parent.updateChild(transaction, node, newElem);
break;
case Node.ATTRIBUTE_NODE:
final AttrImpl newAttr = new AttrImpl((AttrImpl) node);
- newAttr.setNodeName(newQName);
+ newAttr.setNodeName(newQName, context.getBroker().getBrokerPool().getSymbols());
parent.updateChild(transaction, node, newAttr);
break;
default:
2  src/org/exist/xquery/update/Replace.java
View
@@ -158,7 +158,7 @@ public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathExc
break;
case Node.ATTRIBUTE_NODE:
final AttrImpl attr = (AttrImpl) node;
- attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue());
+ attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
parent.updateChild(transaction, node, attribute);
break;
2  src/org/exist/xquery/update/Update.java
View
@@ -169,7 +169,7 @@ public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathExc
break;
}
final AttrImpl attr = (AttrImpl) node;
- attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue());
+ attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
parent.updateChild(transaction, node, attribute);
break;
2  src/org/exist/xupdate/Replace.java
View
@@ -93,7 +93,7 @@ public long process(Txn transaction) throws PermissionDeniedException, LockExcep
case Node.ATTRIBUTE_NODE:
final AttrImpl attr = (AttrImpl) node;
temp = children.item(0);
- attribute = new AttrImpl(attr.getQName(), temp.getNodeValue());
+ attribute = new AttrImpl(attr.getQName(), temp.getNodeValue(), broker.getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
parent.updateChild(transaction, node, attribute);
break;
2  src/org/exist/xupdate/Update.java
View
@@ -109,7 +109,7 @@ public long process(Txn transaction) throws PermissionDeniedException, LockExcep
}
final AttrImpl attr = (AttrImpl) node;
temp = children.item(0);
- attribute = new AttrImpl(attr.getQName(), temp.getNodeValue());
+ attribute = new AttrImpl(attr.getQName(), temp.getNodeValue(), broker.getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
parent.updateChild(transaction, node, attribute);
break;
Please sign in to comment.
Something went wrong with that request. Please try again.