From 6072e108e2738dbde7c2ad976a45745551859a20 Mon Sep 17 00:00:00 2001 From: Paul McMillan Date: Thu, 16 Feb 2012 00:58:49 +0000 Subject: [PATCH] Fixed #17693. Input validation and tests for base36 conversion utils. Thanks Keryn Knight for the report. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17525 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/http.py | 2 ++ docs/ref/utils.txt | 2 +- tests/regressiontests/utils/http.py | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/django/utils/http.py b/django/utils/http.py index f47b58979c..1431f47246 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -171,6 +171,8 @@ def int_to_base36(i): """ digits = "0123456789abcdefghijklmnopqrstuvwxyz" factor = 0 + if (i < 0) or (i > sys.maxint): + raise ValueError("Base36 conversion input too large or incorrect type.") # Find starting factor while True: factor += 1 diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 2c0110f94a..f7ec638dd5 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -444,7 +444,7 @@ Atom1Feed .. function:: int_to_base36(i) - Converts an integer to a base 36 string. + Converts a positive integer less than sys.maxint to a base 36 string. ``django.utils.safestring`` =========================== diff --git a/tests/regressiontests/utils/http.py b/tests/regressiontests/utils/http.py index 4aed880a7c..a6e7a8f2fc 100644 --- a/tests/regressiontests/utils/http.py +++ b/tests/regressiontests/utils/http.py @@ -1,3 +1,5 @@ +import sys + from django.utils import http from django.utils import unittest from django.utils.datastructures import MultiValueDict @@ -98,3 +100,25 @@ class TestUtilsHttp(unittest.TestCase): utils.fix_IE_for_vary(ie_request, response) self.assertFalse('Vary' in response) + def test_base36(self): + # reciprocity works + for n in [0, 1, 1000, 1000000, sys.maxint]: + self.assertEqual(n, http.base36_to_int(http.int_to_base36(n))) + + # bad input + for n in [-1, sys.maxint+1, '1', 'foo', {1:2}, (1,2,3)]: + self.assertRaises(ValueError, http.int_to_base36, n) + + for n in ['#', ' ']: + self.assertRaises(ValueError, http.base36_to_int, n) + + for n in [123, {1:2}, (1,2,3)]: + self.assertRaises(TypeError, http.base36_to_int, n) + + # non-integer input + self.assertRaises(TypeError, http.int_to_base36, 3.141) + + # more explicit output testing + for n, b36 in [(0,'0'), (1,'1'), (42,'16'), (818469960,'django')]: + self.assertEqual(http.int_to_base36(n), b36) + self.assertEqual(http.base36_to_int(b36), n)