summaryrefslogtreecommitdiffstats
path: root/nova/utils.py
diff options
context:
space:
mode:
authorMatthew Sherborne <msherborne@gmail.com>2013-02-26 10:35:42 +1000
committerGerrit Code Review <review@openstack.org>2013-03-14 13:31:02 +0000
commit3478f1e121d84d15558d338a32315f13250cf3bb (patch)
tree94709583e91e7410881403b7010d132a6c35b22e /nova/utils.py
parent2830ef14eca5695e796e8e3104528bbc8766bafa (diff)
downloadnova-3478f1e121d84d15558d338a32315f13250cf3bb.tar.gz
nova-3478f1e121d84d15558d338a32315f13250cf3bb.tar.xz
nova-3478f1e121d84d15558d338a32315f13250cf3bb.zip
Makes safe xml data calls raise 400 http error instead of 500
When we parse incoming XML safely, if there was an error raised it would be an expat.Expat() error, which would bubble up to the api and turn into a HTTP 500 (Internal Error) It turns out that all the places we use the safe_xml parsing are in Deserializers, close to the API, so in this patch we just change the error it raises straight to nova.exception.MalformedRequest(). This causes the api to fail with the proper 400 (Malformed Request) when it encounters corrupt XML. This is caught at nova.api.openstack.wsgi._process_stack and __call__. We also take the opportunity to move the new safe parser from nova.utils to nova.api.openstack.xmlutil as the openstack api is the only thing that uses it. Fixes: bug #1133111 Change-Id: Ifa2ed7ee128241cfe8dbcdc5bd75194d96b6cdb5
Diffstat (limited to 'nova/utils.py')
-rw-r--r--nova/utils.py58
1 files changed, 0 insertions, 58 deletions
diff --git a/nova/utils.py b/nova/utils.py
index fe6c75df3..dbbbd1eb6 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -36,10 +36,6 @@ import struct
import sys
import tempfile
import time
-from xml.dom import minidom
-from xml.parsers import expat
-from xml import sax
-from xml.sax import expatreader
from xml.sax import saxutils
from eventlet import event
@@ -657,60 +653,6 @@ class DynamicLoopingCall(LoopingCallBase):
return self.done
-class ProtectedExpatParser(expatreader.ExpatParser):
- """An expat parser which disables DTD's and entities by default."""
-
- def __init__(self, forbid_dtd=True, forbid_entities=True,
- *args, **kwargs):
- # Python 2.x old style class
- expatreader.ExpatParser.__init__(self, *args, **kwargs)
- self.forbid_dtd = forbid_dtd
- self.forbid_entities = forbid_entities
-
- def start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
- raise ValueError("Inline DTD forbidden")
-
- def entity_decl(self, entityName, is_parameter_entity, value, base,
- systemId, publicId, notationName):
- raise ValueError("<!ENTITY> entity declaration forbidden")
-
- def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
- # expat 1.2
- raise ValueError("<!ENTITY> unparsed entity forbidden")
-
- def external_entity_ref(self, context, base, systemId, publicId):
- raise ValueError("<!ENTITY> external entity forbidden")
-
- def notation_decl(self, name, base, sysid, pubid):
- raise ValueError("<!ENTITY> notation forbidden")
-
- def reset(self):
- expatreader.ExpatParser.reset(self)
- if self.forbid_dtd:
- self._parser.StartDoctypeDeclHandler = self.start_doctype_decl
- self._parser.EndDoctypeDeclHandler = None
- if self.forbid_entities:
- self._parser.EntityDeclHandler = self.entity_decl
- self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
- self._parser.ExternalEntityRefHandler = self.external_entity_ref
- self._parser.NotationDeclHandler = self.notation_decl
- try:
- self._parser.SkippedEntityHandler = None
- except AttributeError:
- # some pyexpat versions do not support SkippedEntity
- pass
-
-
-def safe_minidom_parse_string(xml_string):
- """Parse an XML string using minidom safely.
-
- """
- try:
- return minidom.parseString(xml_string, parser=ProtectedExpatParser())
- except sax.SAXParseException as se:
- raise expat.ExpatError()
-
-
def xhtml_escape(value):
"""Escapes a string so it is valid within XML or XHTML.