From 5f4ffb369fd82c8f64082566d816ec3ae2339e79 Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Sat, 4 Aug 2007 00:27:59 +0000 Subject: [PATCH] gis: wktfield now takes advantage of lazy geometries; geos may take unicode input; fixed utils module git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5795 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/geos/base.py | 17 +++++++++++++---- django/contrib/gis/oldforms/__init__.py | 8 +++----- django/contrib/gis/tests/__init__.py | 6 +++--- django/contrib/gis/utils/__init__.py | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/django/contrib/gis/geos/base.py b/django/contrib/gis/geos/base.py index d0af4388a8..3c7454cb34 100644 --- a/django/contrib/gis/geos/base.py +++ b/django/contrib/gis/geos/base.py @@ -7,7 +7,7 @@ from ctypes import \ byref, string_at, create_string_buffer, pointer, \ c_char_p, c_double, c_int, c_size_t -from types import StringType, IntType, FloatType +from types import StringType, UnicodeType, IntType, FloatType # Python and GEOS-related dependencies. import re @@ -17,8 +17,11 @@ from django.contrib.gis.geos.error import GEOSException, GEOSGeometryIndexError from django.contrib.gis.geos.coordseq import GEOSCoordSeq, create_cs if HAS_NUMPY: from numpy import ndarray, array -# Regular expression for recognizing HEXEWKB. -hex_regex = re.compile(r'^[0-9A-Fa-f]+$') +# Regular expression for recognizing HEXEWKB and WKT. A prophylactic measure +# to prevent potentially malicious input from reaching the underlying C +# library. Not a substitute for good web security programming practices. +hex_regex = re.compile(r'^[0-9A-F]+$', re.I) +wkt_regex = re.compile(r'^(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+$', re.I) class GEOSGeometry(object): "A class that, generally, encapsulates a GEOS geometry." @@ -38,6 +41,10 @@ class GEOSGeometry(object): # Initially, setting the pointer to NULL self._ptr = GEOSPointer(0) + if isinstance(geo_input, UnicodeType): + # Encoding to ASCII, WKT or HEXEWKB doesn't need any more. + geo_input = geo_input.encode('ascii') + if isinstance(geo_input, StringType): if input_type: warn('input_type keyword is deprecated') @@ -46,9 +53,11 @@ class GEOSGeometry(object): sz = c_size_t(len(geo_input)) buf = create_string_buffer(geo_input) g = lgeos.GEOSGeomFromHEX_buf(buf, sz) - else: + elif wkt_regex.match(geo_input): # Otherwise, the geometry is in WKT form. g = lgeos.GEOSGeomFromWKT(c_char_p(geo_input)) + else: + raise GEOSException, 'given string input "%s" unrecognized as WKT or HEXEWKB.' % geo_input elif isinstance(geo_input, (IntType, GEOSPointer)): # When the input is either a raw pointer value (an integer), or a GEOSPointer object. diff --git a/django/contrib/gis/oldforms/__init__.py b/django/contrib/gis/oldforms/__init__.py index 9e2bbf0613..0f3f33c78e 100644 --- a/django/contrib/gis/oldforms/__init__.py +++ b/django/contrib/gis/oldforms/__init__.py @@ -1,16 +1,14 @@ from django.oldforms import LargeTextField -from django.contrib.gis.geos import hex_to_wkt class WKTField(LargeTextField): "An oldforms LargeTextField for editing WKT text in the admin." def render(self, data): - # PostGIS uses EWKBHEX to store its values internally, converting - # to WKT for the admin first -- unless there's no data, then just - # pass None to LargeTextField's render. + # Returns the WKT value for the geometry field. When no such data + # is present, return None to LargeTextField's render. if not data: return super(WKTField, self).render(None) else: - return super(WKTField, self).render(hex_to_wkt(data)) + return super(WKTField, self).render(data.wkt) diff --git a/django/contrib/gis/tests/__init__.py b/django/contrib/gis/tests/__init__.py index 317008923d..5b95df99e2 100644 --- a/django/contrib/gis/tests/__init__.py +++ b/django/contrib/gis/tests/__init__.py @@ -1,8 +1,5 @@ from copy import copy from unittest import TestSuite, TextTestRunner -from django.contrib.gis.db.backend import create_spatial_db -from django.db import connection -from django.test.utils import destroy_test_db # Tests that do not require setting up and tearing down a spatial database. test_suite_names = ['test_gdal_driver', @@ -54,6 +51,9 @@ def run_tests(module_list, verbosity=1): The tests may be run by invoking `./manage.py test`. """ from django.conf import settings + from django.contrib.gis.db.backend import create_spatial_db + from django.db import connection + from django.test.utils import destroy_test_db # Getting initial values. old_debug = settings.DEBUG diff --git a/django/contrib/gis/utils/__init__.py b/django/contrib/gis/utils/__init__.py index 209e2c121a..93158c9553 100644 --- a/django/contrib/gis/utils/__init__.py +++ b/django/contrib/gis/utils/__init__.py @@ -1,3 +1,3 @@ from LayerMapping import LayerMapping from inspect_data import sample -from spatial_db import create_spatial_db +