From 44b56ed059fa2963cf13ecdd4796b3ac45e800b6 Mon Sep 17 00:00:00 2001 From: Can Yavuz Date: Wed, 22 Feb 2012 11:17:37 +0100 Subject: [PATCH] let the XML parser fail gracefully on malformed XML --- djangorestframework/compat.py | 6 ++++++ djangorestframework/parsers.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index b818b4462..e81b428f3 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -465,3 +465,9 @@ except: from django.core.urlresolvers import reverse from django.utils.functional import lazy reverse_lazy = lazy(reverse, str) + +# xml.etree.parse only throws ParseError for python >= 2.7 +try: + from xml.etree import ParseError as ETParseError +except ImportError: # python < 2.7 + ETParseError = None diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 099abe9a0..7481666b3 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -20,6 +20,8 @@ from djangorestframework.compat import yaml from djangorestframework.response import ErrorResponse from djangorestframework.utils.mediatypes import media_type_matches from xml.etree import ElementTree as ET +from djangorestframework.compat import ETParseError +from xml.parsers.expat import ExpatError import datetime import decimal @@ -185,7 +187,11 @@ class XMLParser(BaseParser): `data` will simply be a string representing the body of the request. `files` will always be `None`. """ - tree = ET.parse(stream) + try: + tree = ET.parse(stream) + except (ExpatError, ETParseError, ValueError), exc: + content = {'detail': 'XML parse error - %s' % unicode(exc)} + raise ErrorResponse(status.HTTP_400_BAD_REQUEST, content) data = self._xml_convert(tree.getroot()) return (data, None)