From 5cfe0a1800d155ec6b609bae3d83e1eeb6fdaa75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Sch=C3=B6nbuchner?= Date: Thu, 8 Aug 2019 20:26:52 +0200 Subject: [PATCH] used defusedxml for parse and fromstring --- .../base/management/commands/load_thesaurus.py | 4 ++-- geonode/catalogue/backends/generic.py | 14 +++++++------- geonode/catalogue/backends/pycsw_local.py | 6 +++--- geonode/catalogue/metadataxsl/views.py | 3 ++- geonode/catalogue/models.py | 3 ++- geonode/catalogue/views.py | 3 ++- geonode/geoserver/helpers.py | 17 +++++++++-------- geonode/geoserver/views.py | 3 ++- geonode/layers/metadata.py | 4 ++-- geonode/layers/views.py | 8 ++++---- geonode/maps/tests.py | 4 ++-- geonode/maps/views.py | 4 ++-- geonode/monitoring/tests.py | 6 +++--- geonode/monitoring/utils.py | 4 ++-- geonode/qgis_server/gis_tools.py | 4 ++-- geonode/qgis_server/helpers.py | 4 ++-- geonode/qgis_server/models.py | 8 +++++--- geonode/qgis_server/tests/test_helpers.py | 5 +++-- geonode/qgis_server/tests/test_views.py | 4 ++-- geonode/security/tests.py | 7 ++++--- geonode/tests/csw.py | 8 ++++---- geonode/tests/integration.py | 8 ++++---- geonode/upload/utils.py | 3 ++- 23 files changed, 72 insertions(+), 62 deletions(-) diff --git a/geonode/base/management/commands/load_thesaurus.py b/geonode/base/management/commands/load_thesaurus.py index 9d64bf44514..d7d4db117a2 100644 --- a/geonode/base/management/commands/load_thesaurus.py +++ b/geonode/base/management/commands/load_thesaurus.py @@ -18,7 +18,7 @@ # ######################################################################### -import xml.etree.ElementTree as etree +from defusedxml import lxml as dlxml from django.core.management.base import BaseCommand, CommandError @@ -83,7 +83,7 @@ def load_thesaurus(self, input_file, name, store): 'skos': 'http://www.w3.org/2004/02/skos/core#' } - tfile = etree.parse(input_file) + tfile = dlxml.parse(input_file) root = tfile.getroot() scheme = root.find('skos:ConceptScheme', ns) diff --git a/geonode/catalogue/backends/generic.py b/geonode/catalogue/backends/generic.py index 86e9731a802..97c80e1767b 100644 --- a/geonode/catalogue/backends/generic.py +++ b/geonode/catalogue/backends/generic.py @@ -27,7 +27,7 @@ from owslib.csw import CatalogueServiceWeb, namespaces from owslib.util import http_post from urlparse import urlparse -from lxml import etree +from defusedxml import lxml as dlxml from geonode.catalogue.backends.base import BaseCatalogueBackend logger = logging.getLogger(__name__) @@ -100,7 +100,7 @@ def login(self): urllib2.HTTPCookieProcessor(), urllib2.HTTPRedirectHandler()) response = self.opener.open(request) - doc = etree.fromstring(response.read()) + doc = dlxml.fromstring(response.read()) assert doc.tag == 'ok', "GeoNetwork login failed!" self.connected = True @@ -174,7 +174,7 @@ def csw_gen_xml(self, layer, template): def csw_gen_anytext(self, xml): """ get all element data from an XML document """ - xml = etree.fromstring(xml) + xml = dlxml.fromstring(xml) return ' '.join([value.strip() for value in xml.xpath('//text()')]) def csw_request(self, layer, template): @@ -201,7 +201,7 @@ def create_from_layer(self, layer): # set layer.uuid based on what GeoNetwork returns # this is needed for inserting FGDC metadata in GN - exml = etree.fromstring(response.read()) + exml = dlxml.fromstring(response.read()) identifier = exml.find( '{%s}InsertResult/{%s}BriefRecord/identifier' % (namespaces['csw'], namespaces['csw'])).text @@ -255,7 +255,7 @@ def set_metadata_privs(self, uuid, privileges): # get the id of the data. request = urllib2.Request(get_dbid_url) response = self.urlopen(request) - doc = etree.fromstring(response.read()) + doc = dlxml.fromstring(response.read()) data_dbid = doc.find( 'metadata/{http://www.fao.org/geonetwork}info/id').text @@ -295,7 +295,7 @@ def _geonetwork_get_group_ids(self): self.base, urllib.urlencode({'type': 'groups'})) request = urllib2.Request(get_groups_url) response = self.urlopen(request) - doc = etree.fromstring(response.read()) + doc = dlxml.fromstring(response.read()) groups = {} for gp in doc.findall('groups/group'): groups[gp.find('name').text.lower()] = gp.attrib['id'] @@ -311,7 +311,7 @@ def _geonetwork_get_operation_ids(self): self.base, urllib.urlencode({'type': 'operations'})) request = urllib2.Request(get_ops_url) response = self.urlopen(request) - doc = etree.fromstring(response.read()) + doc = dlxml.fromstring(response.read()) ops = {} for op in doc.findall('operations/operation'): ops[op.find('name').text.lower()] = op.attrib['id'] diff --git a/geonode/catalogue/backends/pycsw_local.py b/geonode/catalogue/backends/pycsw_local.py index 8007479da0f..ca41ede3602 100644 --- a/geonode/catalogue/backends/pycsw_local.py +++ b/geonode/catalogue/backends/pycsw_local.py @@ -19,7 +19,7 @@ ######################################################################### import os -from lxml import etree +from defusedxml import lxml as dlxml from django.conf import settings from ConfigParser import SafeConfigParser from owslib.iso import MD_Metadata @@ -76,7 +76,7 @@ def get_record(self, uuid): if len(results) < 1: return None - result = etree.fromstring(results).find('{http://www.isotc211.org/2005/gmd}MD_Metadata') + result = dlxml.fromstring(results).find('{http://www.isotc211.org/2005/gmd}MD_Metadata') if result is None: return None @@ -96,7 +96,7 @@ def search_records(self, keywords, start, limit, bbox): with self.catalogue: lresults = self._csw_local_dispatch(keywords, keywords, start + 1, limit, bbox) # serialize XML - e = etree.fromstring(lresults) + e = dlxml.fromstring(lresults) self.catalogue.records = \ [MD_Metadata(x) for x in e.findall('//{http://www.isotc211.org/2005/gmd}MD_Metadata')] diff --git a/geonode/catalogue/metadataxsl/views.py b/geonode/catalogue/metadataxsl/views.py index 3374ff94a30..4aecbe4001a 100644 --- a/geonode/catalogue/metadataxsl/views.py +++ b/geonode/catalogue/metadataxsl/views.py @@ -22,6 +22,7 @@ import logging from lxml import etree +from defusedxml import lxml as dlxml from django.shortcuts import get_object_or_404 from django.http import HttpResponse @@ -53,7 +54,7 @@ def prefix_xsl_line(req, id): try: # generate an XML document (GeoNode's default is ISO) if resource.metadata_uploaded and resource.metadata_uploaded_preserve: - md_doc = etree.tostring(etree.fromstring(resource.metadata_xml)) + md_doc = etree.tostring(dlxml.fromstring(resource.metadata_xml)) else: md_doc = catalogue.catalogue.csw_gen_xml(resource, 'catalogue/full_metadata.xml') xml = md_doc diff --git a/geonode/catalogue/models.py b/geonode/catalogue/models.py index c1325f5a17e..3f81b3733d0 100644 --- a/geonode/catalogue/models.py +++ b/geonode/catalogue/models.py @@ -24,6 +24,7 @@ from django.conf import settings from django.db.models import signals from lxml import etree +from defusedxml import lxml as dlxml from geonode.layers.models import Layer from geonode.documents.models import Document from geonode.catalogue import get_catalogue @@ -85,7 +86,7 @@ def catalogue_post_save(instance, sender, **kwargs): # generate an XML document (GeoNode's default is ISO) if instance.metadata_uploaded and instance.metadata_uploaded_preserve: - md_doc = etree.tostring(etree.fromstring(instance.metadata_xml)) + md_doc = etree.tostring(dlxml.fromstring(instance.metadata_xml)) else: md_doc = catalogue.catalogue.csw_gen_xml(instance, 'catalogue/full_metadata.xml') diff --git a/geonode/catalogue/views.py b/geonode/catalogue/views.py index fad6abb8c31..b8d7efaea12 100644 --- a/geonode/catalogue/views.py +++ b/geonode/catalogue/views.py @@ -22,6 +22,7 @@ import os import logging import xml.etree.ElementTree as ET +from defusedxml import lxml as dlxml from django.conf import settings from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render @@ -173,7 +174,7 @@ def csw_global_dispatch(request): ET.register_namespace(prefix, uri) if access_token and not access_token.is_expired(): - tree = ET.fromstring(content) + tree = dlxml.fromstring(content) for online_resource in tree.findall( '*//gmd:CI_OnlineResource', spaces): try: diff --git a/geonode/geoserver/helpers.py b/geonode/geoserver/helpers.py index 7f66cf1d9f6..868efce90ad 100755 --- a/geonode/geoserver/helpers.py +++ b/geonode/geoserver/helpers.py @@ -54,6 +54,7 @@ from geoserver.workspace import Workspace from gsimporter import Client from lxml import etree +from defusedxml import lxml as dlxml from owslib.wcs import WebCoverageService from owslib.wms import WebMapService from geonode import GeoNodeException @@ -188,7 +189,7 @@ def extract_name_from_sld(gs_catalog, sld, sld_file=None): dom = etree.XML(sld) elif sld_file and isfile(sld_file): sld = open(sld_file, "r").read() - dom = etree.parse(sld_file) + dom = dlxml.parse(sld_file) except Exception: logger.exception("The uploaded SLD file is not valid XML") raise Exception( @@ -318,7 +319,7 @@ def set_layer_style(saved_layer, title, sld, base_file=None): etree.XML(sld) elif base_file and isfile(base_file): sld = open(base_file, "r").read() - etree.parse(base_file) + dlxml.parse(base_file) except Exception: logger.exception("The uploaded SLD file is not valid XML") # raise Exception("The uploaded SLD file is not valid XML") @@ -913,7 +914,7 @@ def set_attributes_from_geoserver(layer, overwrite=False): # The code below will fail if http_client cannot be imported or # WFS not supported req, body = http_client.get(dft_url) - doc = etree.fromstring(body) + doc = dlxml.fromstring(body) path = ".//{xsd}extension/{xsd}sequence/{xsd}element".format( xsd="{http://www.w3.org/2001/XMLSchema}") attribute_map = [[n.attrib["name"], n.attrib["type"]] for n in doc.findall( @@ -961,7 +962,7 @@ def set_attributes_from_geoserver(layer, overwrite=False): }) try: req, body = http_client.get(dc_url) - doc = etree.fromstring(body) + doc = dlxml.fromstring(body) path = ".//{wcs}Axis/{wcs}AvailableKeys/{wcs}Key".format( wcs="{http://www.opengis.net/wcs/1.1.1}") attribute_map = [[n.text, "raster"] for n in doc.findall(path)] @@ -1575,7 +1576,7 @@ def wps_execute_layer_attribute_statistics(layer_name, field): headers=headers, user=ogc_server_settings.credentials.username) - exml = etree.fromstring(content) + exml = dlxml.fromstring(content) result = {} @@ -1618,13 +1619,13 @@ def _stylefilterparams_geowebcache_layer(layer_name): # check/write GWC filter parameters import xml.etree.ElementTree as ET body = None - tree = ET.fromstring(_) + tree = dlxml.fromstring(_) param_filters = tree.findall('parameterFilters') if param_filters and len(param_filters) > 0: if not param_filters[0].findall('styleParameterFilter'): style_filters_xml = "STYLES\ " - style_filters_elem = ET.fromstring(style_filters_xml) + style_filters_elem = dlxml.fromstring(style_filters_xml) param_filters[0].append(style_filters_elem) body = ET.tostring(tree) if body: @@ -1694,7 +1695,7 @@ def style_update(request, url): style_name = os.path.basename(request.path) else: try: - tree = ET.ElementTree(ET.fromstring(request.body)) + tree = ET.ElementTree(dlxml.fromstring(request.body)) elm_namedlayer_name = tree.findall( './/{http://www.opengis.net/sld}Name')[0] elm_user_style_name = tree.findall( diff --git a/geonode/geoserver/views.py b/geonode/geoserver/views.py index 96f4937fcae..5f271afecfe 100644 --- a/geonode/geoserver/views.py +++ b/geonode/geoserver/views.py @@ -24,6 +24,7 @@ import logging import traceback from lxml import etree +from defusedxml import lxml as dlxml from os.path import isfile from urlparse import urlsplit, urljoin @@ -776,7 +777,7 @@ def get_capabilities(request, layerid=None, user=None, namespaces = {'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - layercap = etree.fromstring(layercap) + layercap = dlxml.fromstring(layercap) rootdoc = etree.ElementTree(layercap) format_online_resource(workspace, layername, rootdoc, namespaces) service_name = rootdoc.find('.//wms:Service/wms:Name', namespaces) diff --git a/geonode/layers/metadata.py b/geonode/layers/metadata.py index 8925dcec045..27dd9651835 100644 --- a/geonode/layers/metadata.py +++ b/geonode/layers/metadata.py @@ -24,7 +24,7 @@ # Standard Modules import logging import datetime -from lxml import etree +from defusedxml import lxml as dlxml # Geonode functionality from geonode import GeoNodeException @@ -42,7 +42,7 @@ def set_metadata(xml): # check if document is XML try: - exml = etree.fromstring(xml) + exml = dxml.fromstring(xml) except Exception as err: raise GeoNodeException( 'Uploaded XML document is not XML: %s' % str(err)) diff --git a/geonode/layers/views.py b/geonode/layers/views.py index c9d3d2a7cc3..15994bdef51 100644 --- a/geonode/layers/views.py +++ b/geonode/layers/views.py @@ -471,12 +471,12 @@ def sld_definition(style): if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400: wms_capabilities = wms_capabilities_resp.getvalue() if wms_capabilities: - import xml.etree.ElementTree as ET + from defusedxml import lxml as dlxml namespaces = {'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - e = ET.fromstring(wms_capabilities) + e = dlxml.fromstring(wms_capabilities) for atype in e.findall( "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces): dim_name = atype.get('name') @@ -584,12 +584,12 @@ def sld_definition(style): if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400: wms_capabilities = wms_capabilities_resp.getvalue() if wms_capabilities: - import xml.etree.ElementTree as ET + from defusedxml import lxml as dlxml namespaces = {'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - e = ET.fromstring(wms_capabilities) + e = dlxml.fromstring(wms_capabilities) for atype in e.findall( "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces): dim_name = atype.get('name') diff --git a/geonode/maps/tests.py b/geonode/maps/tests.py index ca46477d0b5..5121b0d8469 100644 --- a/geonode/maps/tests.py +++ b/geonode/maps/tests.py @@ -22,7 +22,7 @@ from geonode.tests.base import GeoNodeBaseTestSupport from datetime import datetime -from lxml import etree +from defusedxml import lxml as dlxml from django.core.urlresolvers import reverse @@ -265,7 +265,7 @@ def test_map_to_wmc(self): self.assertEquals(response.status_code, 200) # check specific XPaths - wmc = etree.fromstring(response.content) + wmc = dlxml.fromstring(response.content) namespace = '{http://www.opengis.net/context}' title = '{ns}General/{ns}Title'.format(ns=namespace) diff --git a/geonode/maps/views.py b/geonode/maps/views.py index 264f67557bf..b735fbfa42d 100644 --- a/geonode/maps/views.py +++ b/geonode/maps/views.py @@ -897,12 +897,12 @@ def sld_definition(style): if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400: wms_capabilities = wms_capabilities_resp.getvalue() if wms_capabilities: - import xml.etree.ElementTree as ET + from defusedxml import lxml as dlxml namespaces = {'wms': 'http://www.opengis.net/wms', 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - e = ET.fromstring(wms_capabilities) + e = dlxml.fromstring(wms_capabilities) for atype in e.findall( "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces): dim_name = atype.get('name') diff --git a/geonode/monitoring/tests.py b/geonode/monitoring/tests.py index fb04b8f8eb4..0a615f7c776 100644 --- a/geonode/monitoring/tests.py +++ b/geonode/monitoring/tests.py @@ -26,7 +26,7 @@ import os import pytz -from xml.etree.ElementTree import fromstring +from defusedxml import lxml as dlxml import json import xmljson from decimal import Decimal @@ -56,8 +56,8 @@ req_err_xml = open(req_err_path, 'rt').read() req_xml = open(req_path, 'rt').read() -req_big = xmljson.yahoo.data(fromstring(req_xml)) -req_err_big = xmljson.yahoo.data(fromstring(req_err_xml)) +req_big = xmljson.yahoo.data(dlxml.fromstring(req_xml)) +req_err_big = xmljson.yahoo.data(dlxml.fromstring(req_err_xml)) @override_settings(USE_TZ=True) diff --git a/geonode/monitoring/utils.py b/geonode/monitoring/utils.py index 9c738e4bae9..bf3e8e5b08f 100644 --- a/geonode/monitoring/utils.py +++ b/geonode/monitoring/utils.py @@ -35,7 +35,7 @@ from bs4 import BeautifulSoup as bs from requests.auth import HTTPBasicAuth from datetime import datetime, timedelta -from xml.etree import ElementTree as etree +from defusedxml import lxml as dlxml from django.conf import settings from django.db.models.fields.related import RelatedField @@ -179,7 +179,7 @@ def get_request(self, href, format=format): except (ValueError, TypeError,): # traceback.print_exc() try: - data = etree.fromstring(r.content) + data = dlxml.fromstring(r.content) except Exception as err: log.debug("Cannot parse xml contents for %s: %s", href, err, exc_info=err) data = bs(r.content) diff --git a/geonode/qgis_server/gis_tools.py b/geonode/qgis_server/gis_tools.py index 3aa3388c1c9..b6a4c5fa75b 100644 --- a/geonode/qgis_server/gis_tools.py +++ b/geonode/qgis_server/gis_tools.py @@ -23,7 +23,7 @@ from urllib import urlencode, urlretrieve from os.path import splitext from math import atan, degrees, sinh, pi -from lxml import etree +from defusedxml import lxml as dlxml from django.conf import settings as geonode_config @@ -63,7 +63,7 @@ def set_attributes(layer, overwrite=False): try: temp_file = urlretrieve(dft_url)[0] with open(temp_file, 'r') as wfs_file: - doc = etree.fromstring(wfs_file.read()) + doc = dlxml.fromstring(wfs_file.read()) path = './/{xsd}extension/{xsd}sequence/{xsd}element'.format( xsd='{http://www.w3.org/2001/XMLSchema}') diff --git a/geonode/qgis_server/helpers.py b/geonode/qgis_server/helpers.py index 2c8adfedd91..0b774286570 100644 --- a/geonode/qgis_server/helpers.py +++ b/geonode/qgis_server/helpers.py @@ -32,7 +32,7 @@ from django.contrib.gis.geos import GEOSGeometry, Point from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import reverse -from lxml import etree +from defusedxml import lxml as dlxml from requests import Request from geonode import qgis_server, geoserver @@ -791,7 +791,7 @@ def style_list(layer, internal=True, generating_qgis_capabilities=False): try: response = requests.get(url) - root_xml = etree.fromstring(response.content) + root_xml = dlxml.fromstring(response.content) styles_xml = root_xml.xpath( 'wms:Capability/wms:Layer/wms:Layer/wms:Style', namespaces={ diff --git a/geonode/qgis_server/models.py b/geonode/qgis_server/models.py index 5ae043871a3..467de1f1861 100644 --- a/geonode/qgis_server/models.py +++ b/geonode/qgis_server/models.py @@ -29,6 +29,8 @@ from django.utils.translation import ugettext_lazy as _ from geonode.security.models import PermissionLevelMixin from lxml import etree +from defusedxml import lxml as dlxml + from geonode import qgis_server from geonode.layers.models import Layer @@ -221,10 +223,10 @@ def from_get_capabilities_style_xml( """ if isinstance(style_xml, str): - style_xml = etree.fromstring(style_xml) + style_xml = dlxml.fromstring(style_xml) elif isinstance(style_xml, ElementTree.Element): - style_xml = etree.fromstring( + style_xml = dlxml.fromstring( ElementTree.tostring( style_xml, encoding='utf-8', method='xml')) @@ -248,7 +250,7 @@ def from_get_capabilities_style_xml( response = requests.get(style_url) style_body = etree.tostring( - etree.fromstring(response.content), pretty_print=True) + dlxml.fromstring(response.content), pretty_print=True) default_dict = { 'title': style_xml.xpath( diff --git a/geonode/qgis_server/tests/test_helpers.py b/geonode/qgis_server/tests/test_helpers.py index fb57ec621a9..2463cdfff17 100644 --- a/geonode/qgis_server/tests/test_helpers.py +++ b/geonode/qgis_server/tests/test_helpers.py @@ -27,6 +27,7 @@ from geonode.qgis_server.models import QGISServerLayer from lxml import etree +from defusedxml import lxml as dlxml import gisdata import shutil @@ -157,14 +158,14 @@ def test_style_management_url(self): self.assertEqual(response.headers.get('Content-Type'), 'text/xml') # it has to contains qgis tags - style_xml = etree.fromstring(response.content) + style_xml = dlxml.fromstring(response.content) self.assertTrue('qgis' in style_xml.tag) # Add new style # change default style slightly self.assertTrue('WhiteToBlack' not in response.content) self.assertTrue('BlackToWhite' in response.content) - new_style_xml = etree.fromstring( + new_style_xml = dlxml.fromstring( response.content.replace('BlackToWhite', 'WhiteToBlack')) new_xml_content = etree.tostring(new_style_xml, pretty_print=True) diff --git a/geonode/qgis_server/tests/test_views.py b/geonode/qgis_server/tests/test_views.py index ca50d44ee18..7303c651c8b 100644 --- a/geonode/qgis_server/tests/test_views.py +++ b/geonode/qgis_server/tests/test_views.py @@ -28,7 +28,7 @@ from imghdr import what import requests -from lxml import etree +from defusedxml import lxml as dlxml import gisdata from django.conf import settings @@ -267,7 +267,7 @@ def test_ogc_specific_layer(self): # Check xml content self.assertEqual(response.status_code, 200, response.content) - root = etree.fromstring(response.content) + root = dlxml.fromstring(response.content) layer_xml = root.xpath( 'wms:Capability/wms:Layer/wms:Layer/wms:Name', namespaces={'wms': 'http://www.opengis.net/wms'}) diff --git a/geonode/security/tests.py b/geonode/security/tests.py index 0446f734624..aac880e41a8 100644 --- a/geonode/security/tests.py +++ b/geonode/security/tests.py @@ -450,6 +450,7 @@ def test_layer_upload_with_time(self): check_layer(saved_layer) from lxml import etree + from defusedxml import lxml as dlxml from geonode.geoserver.helpers import get_store from geonode.geoserver.signals import gs_catalog @@ -475,7 +476,7 @@ def test_layer_upload_with_time(self): self.assertEquals(r.status_code, 200) _log(r.text) - featureType = etree.ElementTree(etree.fromstring(r.text)) + featureType = etree.ElementTree(dlxml.fromstring(r.text)) metadata = featureType.findall('./[metadata]') self.assertEquals(len(metadata), 0) @@ -511,7 +512,7 @@ def test_layer_upload_with_time(self): self.assertEquals(r.status_code, 200) _log(r.text) - featureType = etree.ElementTree(etree.fromstring(r.text)) + featureType = etree.ElementTree(dlxml.fromstring(r.text)) metadata = featureType.findall('./[metadata]') _log(etree.tostring(metadata[0], encoding='utf8', method='xml')) self.assertEquals(len(metadata), 1) @@ -534,7 +535,7 @@ def test_layer_upload_with_time(self): 'xlink': 'http://www.w3.org/1999/xlink', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance'} - e = etree.fromstring(wms_capabilities) + e = dlxml.fromstring(wms_capabilities) for atype in e.findall( "./[wms:Name='%s']/wms:Dimension[@name='time']" % (saved_layer.alternate), namespaces): dim_name = atype.get('name') diff --git a/geonode/tests/csw.py b/geonode/tests/csw.py index 7c4c445ef6e..03a54f16a75 100644 --- a/geonode/tests/csw.py +++ b/geonode/tests/csw.py @@ -27,7 +27,7 @@ from lxml import etree -from django.conf import settings +from defusedxml import lxml as dlxml from geonode import geoserver, qgis_server from geonode.utils import check_ogc_backend @@ -310,7 +310,7 @@ def test_csw_upload_fgdc(self): if csw.catalogue.type == 'pycsw_http': # upload a native FGDC metadata document md_doc = etree.tostring( - etree.fromstring( + dlxml.fromstring( open( os.path.join( gisdata.GOOD_METADATA, @@ -418,7 +418,7 @@ def test_csw_bulk_upload(self): for mfile in files: if mfile.endswith('.xml'): md_doc = etree.tostring( - etree.fromstring( + dlxml.fromstring( open( os.path.join( root, @@ -431,7 +431,7 @@ def test_csw_bulk_upload(self): csw.catalogue.results['insertresults'][0]) for md in glob.glob(os.path.join(gisdata.GOOD_METADATA, 'wustl.edu', '*.xml')): - md_doc = etree.tostring(etree.fromstring(open(md).read())) + md_doc = etree.tostring(dlxml.fromstring(open(md).read())) csw.catalogue.transaction( ttype='insert', typename='gmd:MD_Metadata', diff --git a/geonode/tests/integration.py b/geonode/tests/integration.py index a13b54427da..ed358ea5e16 100644 --- a/geonode/tests/integration.py +++ b/geonode/tests/integration.py @@ -34,7 +34,7 @@ # import traceback import gisdata from decimal import Decimal -from lxml import etree +from defusedxml import lxml as dlxml from urlparse import urljoin from django.conf import settings @@ -1465,7 +1465,7 @@ def test_capabilities(self): # 0. test capabilities_layer url = reverse('capabilities_layer', args=[layer1.id]) resp = self.client.get(url) - layercap = etree.fromstring(resp.content) + layercap = dlxml.fromstring(resp.content) rootdoc = etree.ElementTree(layercap) layernodes = rootdoc.findall('./[wms:Name]', namespaces) layernode = layernodes[0] @@ -1477,7 +1477,7 @@ def test_capabilities(self): # 1. test capabilities_user url = reverse('capabilities_user', args=[norman.username]) resp = self.client.get(url) - layercap = etree.fromstring(resp.content) + layercap = dlxml.fromstring(resp.content) rootdoc = etree.ElementTree(layercap) layernodes = rootdoc.findall('./[wms:Name]', namespaces) @@ -1496,7 +1496,7 @@ def test_capabilities(self): # 2. test capabilities_category url = reverse('capabilities_category', args=[category.identifier]) resp = self.client.get(url) - layercap = etree.fromstring(resp.content) + layercap = dlxml.fromstring(resp.content) rootdoc = etree.ElementTree(layercap) layernodes = rootdoc.findall('./[wms:Name]', namespaces) diff --git a/geonode/upload/utils.py b/geonode/upload/utils.py index 9db32bff39b..3618804b563 100644 --- a/geonode/upload/utils.py +++ b/geonode/upload/utils.py @@ -26,6 +26,7 @@ import traceback from lxml import etree +from defusedxml import lxml as dlxml from osgeo import ogr from django.conf import settings from django.core.urlresolvers import reverse @@ -182,7 +183,7 @@ def _byteify(data, ignore_dicts=False): def get_kml_doc(kml_bytes): """Parse and return an etree element with the kml file's content""" - kml_doc = etree.fromstring( + kml_doc = dlxml.fromstring( kml_bytes, parser=etree.XMLParser(resolve_entities=False) )