Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed integer overflows that occurred when `OFTReal` fields were trea…

…ted as `OFTInteger`.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15946 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit abab0742d07b6a95f7eb46fcf6bd727f66f1ccd6 1 parent 83246ca
Justin Bronn authored March 30, 2011
14  django/contrib/gis/gdal/field.py
@@ -20,7 +20,7 @@ def __init__(self, feat, index):
20 20
         # Setting the feature pointer and index.
21 21
         self._feat = feat
22 22
         self._index = index
23  
-        
  23
+
24 24
         # Getting the pointer for this field.
25 25
         fld_ptr = capi.get_feat_field_defn(feat, index)
26 26
         if not fld_ptr:
@@ -33,6 +33,7 @@ def __init__(self, feat, index):
33 33
         # OFTReal with no precision should be an OFTInteger.
34 34
         if isinstance(self, OFTReal) and self.precision == 0:
35 35
             self.__class__ = OFTInteger
  36
+            self._double = True
36 37
 
37 38
     def __str__(self):
38 39
         "Returns the string representation of the Field."
@@ -95,10 +96,17 @@ def width(self):
95 96
 
96 97
 ### The Field sub-classes for each OGR Field type. ###
97 98
 class OFTInteger(Field):
  99
+    _double = False
  100
+
98 101
     @property
99 102
     def value(self):
100 103
         "Returns an integer contained in this field."
101  
-        return self.as_int()
  104
+        if self._double:
  105
+            # If this is really from an OFTReal field with no precision,
  106
+            # read as a double and cast as Python int (to prevent overflow).
  107
+            return int(self.as_double())
  108
+        else:
  109
+            return self.as_int()
102 110
 
103 111
     @property
104 112
     def type(self):
@@ -137,7 +145,7 @@ def value(self):
137 145
         "Returns a Python `datetime` object for this OFTDateTime field."
138 146
         # TODO: Adapt timezone information.
139 147
         #  See http://lists.maptools.org/pipermail/gdal-dev/2006-February/007990.html
140  
-        #  The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous), 
  148
+        #  The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
141 149
         #  100=GMT, 104=GMT+1, 80=GMT-5, etc.
142 150
         try:
143 151
             yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
17  django/contrib/gis/gdal/tests/test_ds.py
... ...
@@ -1,7 +1,8 @@
1  
-import os, os.path, unittest
  1
+import os
  2
+import unittest
2 3
 from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError, GDAL_VERSION
3 4
 from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString
4  
-from django.contrib.gis.geometry.test_data import get_ds_file, TestDS
  5
+from django.contrib.gis.geometry.test_data import get_ds_file, TestDS, TEST_DATA
5 6
 
6 7
 # List of acceptable data sources.
7 8
 ds_list = (TestDS('test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='ESRI Shapefile',
@@ -72,7 +73,7 @@ def test03a_layers(self):
72 73
                 self.assertEqual(source.nfld, len(layer.fields))
73 74
 
74 75
                 # Testing the layer's extent (an Envelope), and it's properties
75  
-                if source.driver == 'VRT' and (GDAL_VERSION > (1, 7, 0) and GDAL_VERSION < (1, 7, 3)):
  76
+                if source.driver == 'VRT' and (GDAL_VERSION >= (1, 7, 0) and GDAL_VERSION < (1, 7, 3)):
76 77
                     # There's a known GDAL regression with retrieving the extent
77 78
                     # of a VRT layer in versions 1.7.0-1.7.2:
78 79
                     #  http://trac.osgeo.org/gdal/ticket/3783
@@ -217,6 +218,16 @@ def test06_spatial_filter(self):
217 218
         lyr.spatial_filter = None
218 219
         self.assertEqual(3, len(lyr))
219 220
 
  221
+    def test07_integer_overflow(self):
  222
+        "Testing that OFTReal fields, treated as OFTInteger, do not overflow."
  223
+        # Using *.dbf from Census 2010 TIGER Shapefile for Texas,
  224
+        # which has land area ('ALAND10') stored in a Real field
  225
+        # with no precision.
  226
+        ds = DataSource(os.path.join(TEST_DATA, 'texas.dbf'))
  227
+        feat = ds[0][0]
  228
+        # Reference value obtained using `ogrinfo`.
  229
+        self.assertEqual(676586997978, feat.get('ALAND10'))
  230
+
220 231
 def suite():
221 232
     s = unittest.TestSuite()
222 233
     s.addTest(unittest.makeSuite(DataSourceTest))
BIN  django/contrib/gis/tests/data/texas.dbf
Binary file not shown

0 notes on commit abab074

Please sign in to comment.
Something went wrong with that request. Please try again.