Django

Code

Changeset 5030

Show
Ignore:
Timestamp:
04/19/07 07:49:40 (2 years ago)
Author:
jbronn
Message:

gis: Fixed segfault on invalid WKT (added test for both invalid HEX and WKT). GEOSException now a proper exception. Updated error handler.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/gis/django/contrib/gis/geos/GEOSGeometry.py

    r5023 r5030  
    8383    raise GEOSException, 'Unsupported OS "%s"' % os.name 
    8484 
     85# The GEOSException class 
     86class GEOSException(Exception): pass 
     87 
    8588# Getting the GEOS C library.  The C interface (CDLL) is used for 
    8689#  both *NIX and Windows. 
     
    99102ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p) 
    100103def error_h(fmt, list): 
    101     # TODO: Figure out why improper format code given w/some GEOS errors 
    102     if not list: 
    103         sys.stderr.write(fmt) 
     104    if list: 
     105        err_msg = fmt % list 
    104106    else: 
    105         sys.stderr.write('ERROR: %s' % str(list)) 
     107        err_msg = fmt 
     108    sys.stderr.write(err_msg) 
    106109error_h = ERRORFUNC(error_h) 
    107110 
     
    112115lgeos.initGEOS(notice_h, error_h) 
    113116 
    114 class GEOSException: 
    115     "Exception class for any GEOS-related errors." 
    116     def __init__(self, msg): 
    117         self.msg = msg 
    118     def __str__(self): 
    119         return repr(self.msg) 
    120  
    121117class GEOSGeometry: 
    122118    "A class that, generally, encapsulates a GEOS geometry." 
     
    125121    def __init__(self, input, geom_type='wkt'): 
    126122        "Takes an input and the type of the input for initialization." 
     123 
    127124        if geom_type == 'wkt': 
    128125            # If the geometry is in WKT form 
    129             self._g = lgeos.GEOSGeomFromWKT(c_char_p(input)) 
     126            buf = create_string_buffer(input) 
     127            g = lgeos.GEOSGeomFromWKT(buf) 
    130128        elif geom_type == 'hex': 
    131             # If the geometry is in EWHEX form. 
     129            # If the geometry is in HEX form. 
    132130            sz = c_size_t(len(input)) 
    133131            buf = create_string_buffer(input) 
    134             self._g = lgeos.GEOSGeomFromHEX_buf(buf, sz) 
     132            g = lgeos.GEOSGeomFromHEX_buf(buf, sz) 
    135133        elif geom_type == 'geos': 
    136134            # When the input is a C pointer (Python integer) 
    137             self._g = input 
     135            g = input 
    138136        else: 
    139137            # Invalid geometry type. 
    140138            raise GEOSException, 'Improper geometry input type!' 
    141139 
     140        # If the geometry pointer is NULL (0), then raise an exception. 
     141        if not g: 
     142            self._g = False # Setting this before raising the exception 
     143            raise GEOSException, 'Invalid %s given!' % geom_type.upper() 
     144        else: 
     145            self._g = g 
     146 
    142147        # Setting the class type (e.g. 'Point', 'Polygon', etc.) 
    143148        self.__class__ = GEO_CLASSES[self.geom_type] 
    144149 
    145         # If the geometry pointer is NULL (0), then raise an exception. 
    146         if not self._g: 
    147             raise GEOSException, 'Could not initialize on input!' 
    148  
    149150    def __del__(self): 
    150151        "This cleans up the memory allocated for the geometry." 
    151         lgeos.GEOSGeom_destroy(self._g) 
     152        if self._g: lgeos.GEOSGeom_destroy(self._g) 
    152153 
    153154    def __str__(self): 
     
    413414 
    414415    def __del__(self): 
    415         lgeos.GEOSCoordSeq_destroy(self._cs) 
     416        if self._cs: lgeos.GEOSCoordSeq_destroy(self._cs) 
    416417 
    417418    def __iter__(self): 
     
    488489        idx = c_uint(index) 
    489490 
    490         # 'd' is the value of the point 
     491        # 'd' is the value of the point, passed in by reference 
    491492        d = c_double() 
    492493        status = lgeos.GEOSCoordSeq_getOrdinate(self._cs, idx, dim, byref(d)) 
  • django/branches/gis/django/contrib/gis/tests/geometries.py

    r5008 r5030  
    88        self.wkt = wkt 
    99 
    10         m = wkt_regex.match(wkt) 
    11         if not m: 
    12             raise Exception, 'Improper WKT: "%s"' % wkt 
    13         self.geo_type = m.group('type') 
     10        self.bad = kwargs.pop('bad', False) 
    1411 
     12        if not self.bad: 
     13            m = wkt_regex.match(wkt) 
     14            if not m: 
     15                raise Exception, 'Improper WKT: "%s"' % wkt 
     16            self.geo_type = m.group('type') 
    1517 
    1618        for key, value in kwargs.items(): 
     
    4244           ) 
    4345 
     46# Errors 
     47errors = (TestGeom('GEOMETR##!@#%#............a32515', bad=True, hex=False), 
     48          TestGeom('Foo.Bar', bad=True, hex=False), 
     49          TestGeom('POINT (5, 23)', bad=True, hex=False), 
     50          TestGeom('AAABBBDDDAAD##@#1113511111-098111111111111111533333333333333', bad=True, hex=True), 
     51          TestGeom('FFFFFFFFFFFFFFFFF1355555555555555555565111', bad=True, hex=True), 
     52          ) 
     53 
    4454# Polygons 
    4555polygons = (TestGeom('POLYGON ((0 0, 0 100, 100 100, 100 0, 0 0), (10 10, 10 90, 90 90, 90 10, 10 10) ))', 
     
    5262                     n_i=0, ext_ring_cs=False 
    5363                     ), 
    54              
    5564            ) 
    5665 
  • django/branches/gis/django/contrib/gis/tests/test_geos.py

    r5023 r5030  
    66class GeosTest2(unittest.TestCase): 
    77 
    8     def test010_wkt(self): 
     8    def test0100_wkt(self): 
    99        "Testing WKT output." 
    1010        for g in wkt_out: 
     
    1212            self.assertEqual(g.ewkt, geom.wkt) 
    1313 
    14     def test011_hex(self): 
     14    def test0101_hex(self): 
    1515        "Testing HEX output." 
    1616        for g in hex_wkt: 
     
    1818            self.assertEqual(g.hex, geom.hex) 
    1919 
     20    def test0102_errors(self): 
     21        "Testing the Error handlers." 
     22        for err in errors: 
     23            if err.hex: 
     24                self.assertRaises(GEOSException, GEOSGeometry, err.wkt, 'hex') 
     25            else: 
     26                self.assertRaises(GEOSException, GEOSGeometry, err.wkt) 
     27                 
    2028    def test02_points(self): 
    2129        "Testing Point objects."