diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-02-24 14:46:28 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-03-04 09:34:39 +0100 |
| commit | fe886a3b58a93cfbe8864b485f93cb6d426cd1f2 (patch) | |
| tree | ca577650416169c886986fd51054283a0d0867f7 /tests | |
| parent | 7deb87c93e5f45ded3ccd1e6162bed6a30000af8 (diff) | |
[2.2.x] Fixed CVE-2020-9402 -- Properly escaped tolerance parameter in GIS functions and aggregates on Oracle.
Thanks to Norbert Szetei for the report.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/gis_tests/distapp/tests.py | 31 | ||||
| -rw-r--r-- | tests/gis_tests/geoapp/tests.py | 39 |
2 files changed, 69 insertions, 1 deletions
diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py index 67558582dc..42f6e0be9a 100644 --- a/tests/gis_tests/distapp/tests.py +++ b/tests/gis_tests/distapp/tests.py @@ -400,6 +400,37 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase): ).filter(d=D(m=1)) self.assertTrue(qs.exists()) + @unittest.skipUnless( + connection.vendor == 'oracle', + 'Oracle supports tolerance paremeter.', + ) + def test_distance_function_tolerance_escaping(self): + qs = Interstate.objects.annotate( + d=Distance( + Point(500, 500, srid=3857), + Point(0, 0, srid=3857), + tolerance='0.05) = 1 OR 1=1 OR (1+1', + ), + ).filter(d=D(m=1)).values('pk') + msg = 'The tolerance parameter has the wrong type' + with self.assertRaisesMessage(TypeError, msg): + qs.exists() + + @unittest.skipUnless( + connection.vendor == 'oracle', + 'Oracle supports tolerance paremeter.', + ) + def test_distance_function_tolerance(self): + # Tolerance is greater than distance. + qs = Interstate.objects.annotate( + d=Distance( + Point(0, 0, srid=3857), + Point(1, 1, srid=3857), + tolerance=1.5, + ), + ).filter(d=0).values('pk') + self.assertIs(qs.exists(), True) + @skipIfDBFeature("supports_distance_geodetic") @skipUnlessDBFeature("has_Distance_function") def test_distance_function_raw_result_d_lookup(self): diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index eaf7e61321..29d87c9005 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -1,4 +1,5 @@ import tempfile +import unittest from io import StringIO from django.contrib.gis import gdal @@ -8,7 +9,7 @@ from django.contrib.gis.geos import ( MultiPoint, MultiPolygon, Point, Polygon, fromstr, ) from django.core.management import call_command -from django.db import NotSupportedError, connection +from django.db import DatabaseError, NotSupportedError, connection from django.test import TestCase, skipUnlessDBFeature from ..utils import ( @@ -563,6 +564,42 @@ class GeoQuerySetTest(TestCase): qs = City.objects.filter(name='NotACity') self.assertIsNone(qs.aggregate(Union('point'))['point__union']) + @unittest.skipUnless( + connection.vendor == 'oracle', + 'Oracle supports tolerance paremeter.', + ) + def test_unionagg_tolerance(self): + City.objects.create( + point=fromstr('POINT(-96.467222 32.751389)', srid=4326), + name='Forney', + ) + tx = Country.objects.get(name='Texas').mpoly + # Tolerance is greater than distance between Forney and Dallas, that's + # why Dallas is ignored. + forney_houston = GEOSGeometry( + 'MULTIPOINT(-95.363151 29.763374, -96.467222 32.751389)', + srid=4326, + ) + self.assertIs( + forney_houston.equals( + City.objects.filter(point__within=tx).aggregate( + Union('point', tolerance=32000), + )['point__union'], + ), + True, + ) + + @unittest.skipUnless( + connection.vendor == 'oracle', + 'Oracle supports tolerance paremeter.', + ) + def test_unionagg_tolerance_escaping(self): + tx = Country.objects.get(name='Texas').mpoly + with self.assertRaises(DatabaseError): + City.objects.filter(point__within=tx).aggregate( + Union('point', tolerance='0.05))), (((1'), + ) + def test_within_subquery(self): """ Using a queryset inside a geo lookup is working (using a subquery) |
