diff -rw /tmp/Django-1.4/django/conf/global_settings.py /tmp/Django-1.4.5/django/conf/global_settings.py 31a32,35 > # Hosts/domain names that are valid for this site. > # "*" matches anything, ".example.com" matches example.com and all subdomains > ALLOWED_HOSTS = ['*'] > diff -rw /tmp/Django-1.4/django/conf/project_template/project_name/settings.py /tmp/Django-1.4.5/django/conf/project_template/project_name/settings.py 22a23,26 > # Hosts/domain names that are valid for this site; required if DEBUG is False > # See https://docs.djangoproject.com/en/1.4/ref/settings/#allowed-hosts > ALLOWED_HOSTS = [] > 26,29c30 < # On Unix systems, a value of None will cause Django to use the same < # timezone as the operating system. < # If running in a Windows environment this must be set to the same as your < # system time zone. --- > # In a Windows environment this must be set to your system time zone. diff -rw /tmp/Django-1.4/django/contrib/admin/filters.py /tmp/Django-1.4.5/django/contrib/admin/filters.py 11,12c11,12 < from django.core.exceptions import ImproperlyConfigured < from django.utils.encoding import smart_unicode --- > from django.core.exceptions import ImproperlyConfigured, ValidationError > from django.utils.encoding import smart_unicode, force_unicode 15d14 < 17a17 > from django.contrib.admin.options import IncorrectLookupParameters 105c105 < 'selected': self.value() == lookup, --- > 'selected': self.value() == force_unicode(lookup), 131a132 > try: 132a134,135 > except ValidationError, e: > raise IncorrectLookupParameters(e) 157a161,163 > if hasattr(field, 'rel'): > rel_name = field.rel.get_related_field().name > else: diff -rw /tmp/Django-1.4/django/contrib/admin/options.py /tmp/Django-1.4.5/django/contrib/admin/options.py 248c248 < pk_attr_name = None --- > rel_name = None 258c258 < pk_attr_name = model._meta.pk.name --- > rel_name = field.rel.get_related_field().name 261c261 < pk_attr_name = model._meta.pk.name --- > rel_name = model._meta.pk.name 263,264c263,264 < pk_attr_name = None < if pk_attr_name and len(parts) > 1 and parts[-1] == pk_attr_name: --- > rel_name = None > if rel_name and len(parts) > 1 and parts[-1] == rel_name: 1319a1320 > # First check if the user can see this history. 1320a1322,1327 > obj = get_object_or_404(model, pk=unquote(object_id)) > > if not self.has_change_permission(request, obj): > raise PermissionDenied > > # Then get the history for this object. 1327,1328c1334 < # If no history was found, see whether this object even exists. < obj = get_object_or_404(model, pk=unquote(object_id)) --- > diff -rw /tmp/Django-1.4/django/contrib/admin/static/admin/css/widgets.css /tmp/Django-1.4.5/django/contrib/admin/static/admin/css/widgets.css 44c44,45 < .selector .selector-filter label { --- > .selector .selector-filter label, > .inline-group .aligned .selector .selector-filter label { diff -rw /tmp/Django-1.4/django/contrib/admin/tests.py /tmp/Django-1.4.5/django/contrib/admin/tests.py 28d27 < super(AdminSeleniumWebDriverTestCase, cls).tearDownClass() 30a30 > super(AdminSeleniumWebDriverTestCase, cls).tearDownClass() diff -rw /tmp/Django-1.4/django/contrib/admin/views/main.py /tmp/Django-1.4.5/django/contrib/admin/views/main.py 261c261 < ordering.append('pk') --- > ordering.append('-pk') diff -rw /tmp/Django-1.4/django/contrib/auth/context_processors.py /tmp/Django-1.4.5/django/contrib/auth/context_processors.py 13a14,18 > def __iter__(self): > # To fix 'item in perms.someapp' and __getitem__ iteraction we need to > # define __iter__. See #18979 for details. > raise TypeError("PermLookupDict is not iterable.") > diff -rw /tmp/Django-1.4/django/contrib/auth/hashers.py /tmp/Django-1.4.5/django/contrib/auth/hashers.py 38c38,39 < if len(encoded) == 32 and '$' not in encoded: --- > if ((len(encoded) == 32 and '$' not in encoded) or > (len(encoded) == 37 and encoded.startswith('md5$$'))): 349a351,352 > if len(encoded) == 37 and encoded.startswith('md5$$'): > encoded = encoded[5:] diff -rw /tmp/Django-1.4/django/contrib/auth/tests/context_processors.py /tmp/Django-1.4.5/django/contrib/auth/tests/context_processors.py 4a5 > from django.contrib.auth.context_processors import PermWrapper, PermLookupDict 8a10,54 > > > class MockUser(object): > def has_module_perm(self, perm): > if perm == 'mockapp.someapp': > return True > return False > > def has_perm(self, perm): > if perm == 'someperm': > return True > return False > > > class PermWrapperTests(TestCase): > """ > Test some details of the PermWrapper implementation. > """ > class EQLimiterObject(object): > """ > This object makes sure __eq__ will not be called endlessly. > """ > def __init__(self): > self.eq_calls = 0 > > def __eq__(self, other): > if self.eq_calls > 0: > return True > self.eq_calls += 1 > return False > > def test_permwrapper_in(self): > """ > Test that 'something' in PermWrapper doesn't end up in endless loop. > """ > perms = PermWrapper(MockUser()) > def raises(): > self.EQLimiterObject() in perms > self.assertRaises(raises, TypeError) > > def test_permlookupdict_in(self): > pldict = PermLookupDict(MockUser(), 'mockapp') > def raises(): > self.EQLimiterObject() in pldict > self.assertRaises(raises, TypeError) diff -rw /tmp/Django-1.4/django/contrib/auth/tests/forms.py /tmp/Django-1.4.5/django/contrib/auth/tests/forms.py 11a12 > from django.utils.translation import ugettext as _ 336c337 < [u"The user account associated with this e-mail address cannot reset the password."]) --- > [_(u"The user account associated with this e-mail address cannot reset the password.")]) diff -rw /tmp/Django-1.4/django/contrib/auth/tests/hashers.py /tmp/Django-1.4.5/django/contrib/auth/tests/hashers.py 61a62,66 > # Alternate unsalted syntax > alt_encoded = "md5$$%s" % encoded > self.assertTrue(is_password_usable(alt_encoded)) > self.assertTrue(check_password(u'letmein', alt_encoded)) > self.assertFalse(check_password('letmeinz', alt_encoded)) diff -rw /tmp/Django-1.4/django/contrib/auth/tests/urls.py /tmp/Django-1.4.5/django/contrib/auth/tests/urls.py 53a54 > (r'^admin_password_reset/$', 'django.contrib.auth.views.password_reset', dict(is_admin_site=True)), diff -rw /tmp/Django-1.4/django/contrib/auth/tests/views.py /tmp/Django-1.4.5/django/contrib/auth/tests/views.py 9a10 > from django.core.exceptions import SuspiciousOperation 107a109,149 > > @override_settings(ALLOWED_HOSTS=['adminsite.com']) > def test_admin_reset(self): > "If the reset view is marked as being for admin, the HTTP_HOST header is used for a domain override." > response = self.client.post('/admin_password_reset/', > {'email': 'staffmember@example.com'}, > HTTP_HOST='adminsite.com' > ) > self.assertEqual(response.status_code, 302) > self.assertEqual(len(mail.outbox), 1) > self.assertTrue("http://adminsite.com" in mail.outbox[0].body) > self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email) > > # Skip any 500 handler action (like sending more mail...) > @override_settings(DEBUG_PROPAGATE_EXCEPTIONS=True) > def test_poisoned_http_host(self): > "Poisoned HTTP_HOST headers can't be used for reset emails" > # This attack is based on the way browsers handle URLs. The colon > # should be used to separate the port, but if the URL contains an @, > # the colon is interpreted as part of a username for login purposes, > # making 'evil.com' the request domain. Since HTTP_HOST is used to > # produce a meaningful reset URL, we need to be certain that the > # HTTP_HOST header isn't poisoned. This is done as a check when get_host() > # is invoked, but we check here as a practical consequence. > with self.assertRaises(SuspiciousOperation): > self.client.post('/password_reset/', > {'email': 'staffmember@example.com'}, > HTTP_HOST='www.example:dr.frankenstein@evil.tld' > ) > self.assertEqual(len(mail.outbox), 0) > > # Skip any 500 handler action (like sending more mail...) > @override_settings(DEBUG_PROPAGATE_EXCEPTIONS=True) > def test_poisoned_http_host_admin_site(self): > "Poisoned HTTP_HOST headers can't be used for reset emails on admin views" > with self.assertRaises(SuspiciousOperation): > self.client.post('/admin_password_reset/', > {'email': 'staffmember@example.com'}, > HTTP_HOST='www.example:dr.frankenstein@evil.tld' > ) > self.assertEqual(len(mail.outbox), 0) diff -rw /tmp/Django-1.4/django/contrib/auth/views.py /tmp/Django-1.4.5/django/contrib/auth/views.py 7c7 < from django.utils.http import base36_to_int --- > from django.utils.http import base36_to_int, is_safe_url 37,45c37,38 < netloc = urlparse.urlparse(redirect_to)[1] < < # Use default setting if redirect_to is empty < if not redirect_to: < redirect_to = settings.LOGIN_REDIRECT_URL < < # Heavier security check -- don't allow redirection to a different < # host. < elif netloc and netloc != request.get_host(): --- > # Ensure the user-originating redirection url is safe. > if not is_safe_url(url=redirect_to, host=request.get_host()): 48c41 < # Okay, security checks complete. Log the user in. --- > # Okay, security check complete. Log the user in. 81,83c74,76 < redirect_to = request.REQUEST.get(redirect_field_name, '') < if redirect_to: < netloc = urlparse.urlparse(redirect_to)[1] --- > > if redirect_field_name in request.REQUEST: > next_page = request.REQUEST[redirect_field_name] 85,86c78,83 < if not (netloc and netloc != request.get_host()): < return HttpResponseRedirect(redirect_to) --- > if not is_safe_url(url=next_page, host=request.get_host()): > next_page = request.path > > if next_page: > # Redirect to this page until the session has been cleared. > return HttpResponseRedirect(next_page) 88d84 < if next_page is None: 99,101d94 < else: < # Redirect to this page until the session has been cleared. < return HttpResponseRedirect(next_page or request.path) 159c152 < opts = dict(opts, domain_override=request.META['HTTP_HOST']) --- > opts = dict(opts, domain_override=request.get_host()) diff -rw /tmp/Django-1.4/django/contrib/comments/views/comments.py /tmp/Django-1.4.5/django/contrib/comments/views/comments.py 47,49d46 < # Check to see if the POST data overrides the view's next argument. < next = data.get("next", next) < 103c100 < "next": next, --- > "next": data.get("next", next), 134c131 < return next_redirect(data, next, comment_done, c=comment._get_pk_val()) --- > return next_redirect(request, next, comment_done, c=comment._get_pk_val()) diff -rw /tmp/Django-1.4/django/contrib/comments/views/moderation.py /tmp/Django-1.4.5/django/contrib/comments/views/moderation.py 13d12 < 30c29 < return next_redirect(request.POST.copy(), next, flag_done, c=comment.pk) --- > return next_redirect(request, next, flag_done, c=comment.pk) 57c56 < return next_redirect(request.POST.copy(), next, delete_done, c=comment.pk) --- > return next_redirect(request, next, delete_done, c=comment.pk) 84c83 < return next_redirect(request.POST.copy(), next, approve_done, c=comment.pk) --- > return next_redirect(request, next, approve_done, c=comment.pk) diff -rw /tmp/Django-1.4/django/contrib/comments/views/utils.py /tmp/Django-1.4.5/django/contrib/comments/views/utils.py 7d6 < from django.http import HttpResponseRedirect 8a8 > from django.http import HttpResponseRedirect 12a13 > from django.utils.http import is_safe_url 14c15 < def next_redirect(data, default, default_view, **get_kwargs): --- > def next_redirect(request, default, default_view, **get_kwargs): 24,25c25,26 < next = data.get("next", default) < if next is None: --- > next = request.POST.get('next', default) > if not is_safe_url(url=next, host=request.get_host()): 26a28 > diff -rw /tmp/Django-1.4/django/contrib/contenttypes/tests.py /tmp/Django-1.4.5/django/contrib/contenttypes/tests.py 11a12 > from django.test.utils import override_settings 116a118 > @override_settings(ALLOWED_HOSTS=['example.com']) diff -rw /tmp/Django-1.4/django/contrib/gis/db/backends/oracle/compiler.py /tmp/Django-1.4.5/django/contrib/gis/db/backends/oracle/compiler.py 10,32c10 < def placeholder(self, field, val): < if field is None: < # A field value of None means the value is raw. < return val < elif hasattr(field, 'get_placeholder'): < # Some fields (e.g. geo fields) need special munging before < # they can be inserted. < ph = field.get_placeholder(val, self.connection) < if ph == 'NULL': < # If the placeholder returned is 'NULL', then we need to < # to remove None from the Query parameters. Specifically, < # cx_Oracle will assume a CHAR type when a placeholder ('%s') < # is used for columns of MDSYS.SDO_GEOMETRY. Thus, we use < # 'NULL' for the value, and remove None from the query params. < # See also #10888. < param_idx = self.query.columns.index(field.column) < params = list(self.query.params) < params.pop(param_idx) < self.query.params = tuple(params) < return ph < else: < # Return the common case for the placeholder < return '%s' --- > pass diff -rw /tmp/Django-1.4/django/contrib/gis/db/backends/oracle/operations.py /tmp/Django-1.4.5/django/contrib/gis/db/backends/oracle/operations.py 11a12 > from itertools import izip 289a291,299 > > def modify_insert_params(self, placeholders, params): > """Drop out insert parameters for NULL placeholder. Needed for Oracle Spatial > backend due to #10888 > """ > # This code doesn't work for bulk insert cases. > assert len(placeholders) == 1 > return [[param for pholder,param > in izip(placeholders[0], params[0]) if pholder != 'NULL'], ] diff -rw /tmp/Django-1.4/django/contrib/gis/tests/inspectapp/tests.py /tmp/Django-1.4.5/django/contrib/gis/tests/inspectapp/tests.py 71,85c71,90 < expected = [ < '# This is an auto-generated Django model module created by ogrinspect.', < 'from django.contrib.gis.db import models', < '', < 'class Measurement(models.Model):', < ' f_decimal = models.DecimalField(max_digits=0, decimal_places=0)', < ' f_int = models.IntegerField()', < ' f_datetime = models.DateTimeField()', < ' f_time = models.TimeField()', < ' f_float = models.FloatField()', < ' f_char = models.CharField(max_length=10)', < ' f_date = models.DateField()', < ' geom = models.PolygonField()', < ' objects = models.GeoManager()', < ] --- > self.assertTrue(model_def.startswith( > '# This is an auto-generated Django model module created by ogrinspect.\n' > 'from django.contrib.gis.db import models\n' > '\n' > 'class Measurement(models.Model):\n' > )) > > # The ordering of model fields might vary depending on several factors (version of GDAL, etc.) > self.assertIn(' f_decimal = models.DecimalField(max_digits=0, decimal_places=0)', model_def) > self.assertIn(' f_int = models.IntegerField()', model_def) > self.assertIn(' f_datetime = models.DateTimeField()', model_def) > self.assertIn(' f_time = models.TimeField()', model_def) > self.assertIn(' f_float = models.FloatField()', model_def) > self.assertIn(' f_char = models.CharField(max_length=10)', model_def) > self.assertIn(' f_date = models.DateField()', model_def) > > self.assertTrue(model_def.endswith( > ' geom = models.PolygonField()\n' > ' objects = models.GeoManager()' > )) 87d91 < self.assertEqual(model_def, '\n'.join(expected)) diff -rw /tmp/Django-1.4/django/contrib/markup/templatetags/markup.py /tmp/Django-1.4.5/django/contrib/markup/templatetags/markup.py 68,69c68,69 < python_markdown_deprecation = "The use of Python-Markdown " < "< 2.1 in Django is deprecated; please update to the current version" --- > python_markdown_deprecation = ("The use of Python-Markdown " > "< 2.1 in Django is deprecated; please update to the current version") diff -rw /tmp/Django-1.4/django/contrib/sites/tests.py /tmp/Django-1.4.5/django/contrib/sites/tests.py 5a6 > from django.test.utils import override_settings 41a43 > @override_settings(ALLOWED_HOSTS=['example.com']) diff -rw /tmp/Django-1.4/django/contrib/staticfiles/storage.py /tmp/Django-1.4.5/django/contrib/staticfiles/storage.py 193,194c193,194 < # delete cache of all handled paths < self.cache.delete_many([self.cache_key(path) for path in paths]) --- > # where to store the new paths > hashed_paths = {} 243c243 < self.cache.set(self.cache_key(name), hashed_name) --- > hashed_paths[self.cache_key(name)] = hashed_name 244a245,247 > > # Finally set the cache > self.cache.set_many(hashed_paths) diff -rw /tmp/Django-1.4/django/core/files/images.py /tmp/Django-1.4.5/django/core/files/images.py 49a50,53 > # Most of the time PIL only needs a small chunk to parse the image and > # get the dimensions, but with some TIFF files PIL needs to parse the > # whole file. > chunk_size = 1024 51c55 < data = file.read(1024) --- > data = file.read(chunk_size) 56a61 > chunk_size = chunk_size*2 diff -rw /tmp/Django-1.4/django/core/management/commands/testserver.py /tmp/Django-1.4.5/django/core/management/commands/testserver.py 38c38,45 < call_command('runserver', addrport=addrport, shutdown_message=shutdown_message, use_reloader=False, use_ipv6=options['use_ipv6']) --- > use_threading = connection.features.test_db_allows_multiple_connections > call_command('runserver', > addrport=addrport, > shutdown_message=shutdown_message, > use_reloader=False, > use_ipv6=options['use_ipv6'], > use_threading=use_threading > ) diff -rw /tmp/Django-1.4/django/core/serializers/xml_serializer.py /tmp/Django-1.4.5/django/core/serializers/xml_serializer.py 10a11,12 > from xml.sax import handler > from xml.sax.expatreader import ExpatParser as _ExpatParser 152c154 < self.event_stream = pulldom.parse(self.stream) --- > self.event_stream = pulldom.parse(self.stream, self._make_parser()) 154a157,160 > def _make_parser(self): > """Create a hardened XML parser (no custom/external entities).""" > return DefusedExpatParser() > 292a299,385 > > > # Below code based on Christian Heimes' defusedxml > > > class DefusedExpatParser(_ExpatParser): > """ > An expat parser hardened against XML bomb attacks. > > Forbids DTDs, external entity references > > """ > def __init__(self, *args, **kwargs): > _ExpatParser.__init__(self, *args, **kwargs) > self.setFeature(handler.feature_external_ges, False) > self.setFeature(handler.feature_external_pes, False) > > def start_doctype_decl(self, name, sysid, pubid, has_internal_subset): > raise DTDForbidden(name, sysid, pubid) > > def entity_decl(self, name, is_parameter_entity, value, base, > sysid, pubid, notation_name): > raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name) > > def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name): > # expat 1.2 > raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name) > > def external_entity_ref_handler(self, context, base, sysid, pubid): > raise ExternalReferenceForbidden(context, base, sysid, pubid) > > def reset(self): > _ExpatParser.reset(self) > parser = self._parser > parser.StartDoctypeDeclHandler = self.start_doctype_decl > parser.EntityDeclHandler = self.entity_decl > parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl > parser.ExternalEntityRefHandler = self.external_entity_ref_handler > > > class DefusedXmlException(ValueError): > """Base exception.""" > def __repr__(self): > return str(self) > > > class DTDForbidden(DefusedXmlException): > """Document type definition is forbidden.""" > def __init__(self, name, sysid, pubid): > super(DTDForbidden, self).__init__() > self.name = name > self.sysid = sysid > self.pubid = pubid > > def __str__(self): > tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})" > return tpl.format(self.name, self.sysid, self.pubid) > > > class EntitiesForbidden(DefusedXmlException): > """Entity definition is forbidden.""" > def __init__(self, name, value, base, sysid, pubid, notation_name): > super(EntitiesForbidden, self).__init__() > self.name = name > self.value = value > self.base = base > self.sysid = sysid > self.pubid = pubid > self.notation_name = notation_name > > def __str__(self): > tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})" > return tpl.format(self.name, self.sysid, self.pubid) > > > class ExternalReferenceForbidden(DefusedXmlException): > """Resolving an external reference is forbidden.""" > def __init__(self, context, base, sysid, pubid): > super(ExternalReferenceForbidden, self).__init__() > self.context = context > self.base = base > self.sysid = sysid > self.pubid = pubid > > def __str__(self): > tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})" > return tpl.format(self.sysid, self.pubid) diff -rw /tmp/Django-1.4/django/db/backends/__init__.py /tmp/Django-1.4.5/django/db/backends/__init__.py 85a86,96 > def abort(self): > """ > Roll back any ongoing transaction and clean the transaction state > stack. > """ > if self._dirty: > self._rollback() > self._dirty = False > while self.transaction_state: > self.leave_transaction_management() > 472a484,491 > def bulk_batch_size(self, fields, objs): > """ > Returns the maximum allowed batch size for the backend. The fields > are the fields going to be inserted in the batch, the objs contains > all the objects to be inserted. > """ > return len(objs) > 509a529,539 > def distinct_sql(self, fields): > """ > Returns an SQL DISTINCT clause which removes duplicate rows from the > result set. If any fields are given, only the given fields are being > checked for duplicates. > """ > if fields: > raise NotImplementedError('DISTINCT ON fields is not supported by this database backend') > else: > return 'DISTINCT' > 565,575d594 < def distinct_sql(self, fields): < """ < Returns an SQL DISTINCT clause which removes duplicate rows from the < result set. If any fields are given, only the given fields are being < checked for duplicates. < """ < if fields: < raise NotImplementedError('DISTINCT ON fields is not supported by this database backend') < else: < return 'DISTINCT' < 867a887,892 > > def modify_insert_params(self, placeholders, params): > """Allow modification of insert parameters. Needed for Oracle Spatial > backend due to #10888. > """ > return params diff -rw /tmp/Django-1.4/django/db/backends/mysql/base.py /tmp/Django-1.4.5/django/db/backends/mysql/base.py 180c180 < cursor.execute("SHOW TABLE STATUS WHERE Name='INTROSPECT_TEST'") --- > cursor.execute("SHOW TABLE STATUS LIKE 'INTROSPECT_TEST'") 409a410 > new_connection = False 411,412c412,421 < self.cursor() < m = server_version_re.match(self.connection.get_server_info()) --- > # Ensure we have a connection with the DB by using a temporary > # cursor > new_connection = True > self.cursor().close() > server_info = self.connection.get_server_info() > if new_connection: > # Make sure we close the connection > self.connection.close() > self.connection = None > m = server_version_re.match(server_info) 414c423 < raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info()) --- > raise Exception('Unable to determine MySQL version from version string %r' % server_info) diff -rw /tmp/Django-1.4/django/db/backends/sqlite3/base.py /tmp/Django-1.4.5/django/db/backends/sqlite3/base.py 86c86 < can_combine_inserts_with_and_without_auto_increment_pk = True --- > can_combine_inserts_with_and_without_auto_increment_pk = False 106a107,113 > def bulk_batch_size(self, fields, objs): > """ > SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of > 999 variables per query. > """ > return (999 // len(fields)) if len(fields) > 0 else len(objs) > 211c218 < res.extend(["UNION SELECT %s" % ", ".join(["%s"] * len(fields))] * (num_values - 1)) --- > res.extend(["UNION ALL SELECT %s" % ", ".join(["%s"] * len(fields))] * (num_values - 1)) diff -rw /tmp/Django-1.4/django/db/__init__.py /tmp/Django-1.4.5/django/db/__init__.py 45,46c45,52 < for conn in connections.all(): < conn.close() --- > # Avoid circular imports > from django.db import transaction > for conn in connections: > # If an error happens here the connection will be left in broken > # state. Once a good db connection is again available, the > # connection state will be cleaned up. > transaction.abort(conn) > connections[conn].close() diff -rw /tmp/Django-1.4/django/db/models/fields/__init__.py /tmp/Django-1.4.5/django/db/models/fields/__init__.py 1026c1026,1027 < def __init__(self, protocol='both', unpack_ipv4=False, *args, **kwargs): --- > def __init__(self, verbose_name=None, name=None, protocol='both', > unpack_ipv4=False, *args, **kwargs): 1032c1033 < Field.__init__(self, *args, **kwargs) --- > Field.__init__(self, verbose_name, name, *args, **kwargs) diff -rw /tmp/Django-1.4/django/db/models/fields/related.py /tmp/Django-1.4.5/django/db/models/fields/related.py 242c242 < return (self.get_query_set(instance=instances[0]), --- > return (self.get_query_set(instance=instances[0]).filter(**params), 534,536c534,560 < self._pk_val = self.instance.pk < if self._pk_val is None: < raise ValueError("%r instance needs to have a primary key value before a many-to-many relationship can be used." % instance.__class__.__name__) --- > self._fk_val = self._get_fk_val(instance, source_field_name) > if self._fk_val is None: > raise ValueError('"%r" needs to have a value for field "%s" before ' > 'this many-to-many relationship can be used.' % > (instance, source_field_name)) > # Even if this relation is not to pk, we require still pk value. > # The wish is that the instance has been already saved to DB, > # although having a pk value isn't a guarantee of that. > if instance.pk is None: > raise ValueError("%r instance needs to have a primary key value before " > "a many-to-many relationship can be used." % > instance.__class__.__name__) > > def _get_fk_val(self, obj, field_name): > """ > Returns the correct value for this relationship's foreign key. This > might be something else than pk value when to_field is used. > """ > if not self.through: > # Make custom m2m fields with no through model defined usable. > return obj.pk > fk = self.through._meta.get_field(field_name) > if fk.rel.field_name and fk.rel.field_name != fk.rel.to._meta.pk.attname: > attname = fk.rel.get_related_field().get_attname() > return fk.get_prep_lookup('exact', getattr(obj, attname)) > else: > return obj.pk 638c662,666 < new_ids.add(obj.pk) --- > fk_val = self._get_fk_val(obj, target_field_name) > if fk_val is None: > raise ValueError('Cannot add "%r": the value for field "%s" is None' % > (obj, target_field_name)) > new_ids.add(self._get_fk_val(obj, target_field_name)) 646c674 < source_field_name: self._pk_val, --- > source_field_name: self._fk_val, 660c688 < '%s_id' % source_field_name: self._pk_val, --- > '%s_id' % source_field_name: self._fk_val, 664a693 > 683c712 < old_ids.add(obj.pk) --- > old_ids.add(self._get_fk_val(obj, target_field_name)) 697c726 < source_field_name: self._pk_val, --- > source_field_name: self._fk_val, 717c746 < source_field_name: self._pk_val --- > source_field_name: self._fk_val diff -rw /tmp/Django-1.4/django/db/models/query.py /tmp/Django-1.4.5/django/db/models/query.py 380c380 < def bulk_create(self, objs): --- > def bulk_create(self, objs, batch_size=None): 393,394c393,396 < # insert into the childmost table. We're punting on these for now < # because they are relatively rare cases. --- > # insert into the childmost table. Some databases might allow doing > # this by using RETURNING clause for the insert query. We're punting > # on these for now because they are relatively rare cases. > assert batch_size is None or batch_size > 0 410c412 < self.model._base_manager._insert(objs, fields=fields, using=self.db) --- > self._batched_insert(objs, fields, batch_size) 414c416 < self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db) --- > self._batched_insert(objs_with_pk, fields, batch_size) 416c418,419 < self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db) --- > fields= [f for f in fields if not isinstance(f, AutoField)] > self._batched_insert(objs_without_pk, fields, batch_size) 851a855,868 > def _batched_insert(self, objs, fields, batch_size): > """ > A little helper method for bulk_insert to insert the bulk one batch > at a time. Inserts recursively a batch from the front of the bulk and > then _batched_insert() the remaining objects again. > """ > if not objs: > return > ops = connections[self.db].ops > batch_size = (batch_size or max(ops.bulk_batch_size(fields, objs), 1)) > for batch in [objs[i:i+batch_size] > for i in range(0, len(objs), batch_size)]: > self.model._base_manager._insert(batch, fields=fields, > using=self.db) diff -rw /tmp/Django-1.4/django/db/models/sql/compiler.py /tmp/Django-1.4.5/django/db/models/sql/compiler.py 887a888,889 > # Oracle Spatial needs to remove some values due to #10888 > params = self.connection.ops.modify_insert_params(placeholders, params) diff -rw /tmp/Django-1.4/django/db/transaction.py /tmp/Django-1.4.5/django/db/transaction.py 27a28,42 > def abort(using=None): > """ > Roll back any ongoing transactions and clean the transaction management > state of the connection. > > This method is to be used only in cases where using balanced > leave_transaction_management() calls isn't possible. For example after a > request has finished, the transaction state isn't known, yet the connection > must be cleaned up for the next request. > """ > if using is None: > using = DEFAULT_DB_ALIAS > connection = connections[using] > connection.abort() > diff -rw /tmp/Django-1.4/django/forms/fields.py /tmp/Django-1.4.5/django/forms/fields.py 573,586c573,576 < # load() is the only method that can spot a truncated JPEG, < # but it cannot be called sanely after verify() < trial_image = Image.open(file) < trial_image.load() < < # Since we're about to use the file again we have to reset the < # file object if possible. < if hasattr(file, 'reset'): < file.reset() < < # verify() is the only method that can spot a corrupt PNG, < # but it must be called immediately after the constructor < trial_image = Image.open(file) < trial_image.verify() --- > # load() could spot a truncated JPEG, but it loads the entire > # image in memory, which is a DoS vector. See #3848 and #18520. > # verify() must be called immediately after the constructor. > Image.open(file).verify() diff -rw /tmp/Django-1.4/django/forms/formsets.py /tmp/Django-1.4.5/django/forms/formsets.py 21a22,24 > # default maximum number of forms in a formset, to prevent memory exhaustion > DEFAULT_MAX_NUM = 1000 > 114c117 < for i in xrange(self.total_form_count()): --- > for i in xrange(min(self.total_form_count(), self.absolute_max)): 362a366,370 > if max_num is None: > max_num = DEFAULT_MAX_NUM > # hard limit on forms instantiated, to prevent memory-exhaustion attacks > # limit defaults to DEFAULT_MAX_NUM, but developer can increase it via max_num > absolute_max = max(DEFAULT_MAX_NUM, max_num) 365c373 < 'max_num': max_num} --- > 'max_num': max_num, 'absolute_max': absolute_max} diff -rw /tmp/Django-1.4/django/forms/widgets.py /tmp/Django-1.4.5/django/forms/widgets.py 489a490,495 > > # Defined at module level so that CheckboxInput is picklable (#17976) > def boolean_check(v): > return not (v is False or v is None or v == '') > > 495,498c501 < if check_test is None: < self.check_test = lambda v: not (v is False or v is None or v == '') < else: < self.check_test = check_test --- > self.check_test = boolean_check if check_test is None else check_test diff -rw /tmp/Django-1.4/django/http/__init__.py /tmp/Django-1.4.5/django/http/__init__.py 12c12 < from urlparse import urljoin --- > from urlparse import urljoin, urlparse 117c117 < from django.core.exceptions import ImproperlyConfigured --- > from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation 128a129,130 > host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9:]+\])(:\d+)?$") > 214a217,219 > > allowed_hosts = ['*'] if settings.DEBUG else settings.ALLOWED_HOSTS > if validate_host(host, allowed_hosts): 215a221,223 > else: > raise SuspiciousOperation( > "Invalid HTTP_HOST header (you may need to set ALLOWED_HOSTS): %s" % host) 734,735c742,743 < class HttpResponseRedirect(HttpResponse): < status_code = 302 --- > class HttpResponseRedirectBase(HttpResponse): > allowed_schemes = ['http', 'https', 'ftp'] 738c746,749 < super(HttpResponseRedirect, self).__init__() --- > super(HttpResponseRedirectBase, self).__init__() > parsed = urlparse(redirect_to) > if parsed.scheme and parsed.scheme not in self.allowed_schemes: > raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed.scheme) 741,742c752,753 < class HttpResponsePermanentRedirect(HttpResponse): < status_code = 301 --- > class HttpResponseRedirect(HttpResponseRedirectBase): > status_code = 302 744,746c755,756 < def __init__(self, redirect_to): < super(HttpResponsePermanentRedirect, self).__init__() < self['Location'] = iri_to_uri(redirect_to) --- > class HttpResponsePermanentRedirect(HttpResponseRedirectBase): > status_code = 301 792a803,842 > def validate_host(host, allowed_hosts): > """ > Validate the given host header value for this site. > > Check that the host looks valid and matches a host or host pattern in the > given list of ``allowed_hosts``. Any pattern beginning with a period > matches a domain and all its subdomains (e.g. ``.example.com`` matches > ``example.com`` and any subdomain), ``*`` matches anything, and anything > else must match exactly. > > Return ``True`` for a valid host, ``False`` otherwise. > > """ > # All validation is case-insensitive > host = host.lower() > > # Basic sanity check > if not host_validation_re.match(host): > return False > > # Validate only the domain part. > if host[-1] == ']': > # It's an IPv6 address without a port. > domain = host > else: > domain = host.rsplit(':', 1)[0] > > for pattern in allowed_hosts: > pattern = pattern.lower() > match = ( > pattern == '*' or > pattern.startswith('.') and ( > domain.endswith(pattern) or domain == pattern[1:] > ) or > pattern == domain > ) > if match: > return True > > return False diff -rw /tmp/Django-1.4/django/__init__.py /tmp/Django-1.4.5/django/__init__.py 1c1 < VERSION = (1, 4, 0, 'final', 0) --- > VERSION = (1, 4, 5, 'final', 0) diff -rw /tmp/Django-1.4/django/middleware/transaction.py /tmp/Django-1.4.5/django/middleware/transaction.py 17a18,21 > # This rollback might fail because of network failure for example. > # If rollback isn't possible it is impossible to clean the > # connection's state. So leave the connection in dirty state and > # let request_finished signal deal with cleaning the connection. 24a29,34 > # Note: it is possible that the commit fails. If the reason is > # closed connection or some similar reason, then there is > # little hope to proceed nicely. However, in some cases ( > # deferred foreign key checks for exampl) it is still possible > # to rollback(). > try: 25a36,44 > except Exception: > # If the rollback fails, the transaction state will be > # messed up. It doesn't matter, the connection will be set > # to clean state after the request finishes. And, we can't > # clean the state here properly even if we wanted to, the > # connection is in transaction but we can't rollback... > transaction.rollback() > transaction.leave_transaction_management() > raise diff -rw /tmp/Django-1.4/django/test/testcases.py /tmp/Django-1.4.5/django/test/testcases.py 65a66 > real_abort = transaction.abort 75a77 > transaction.abort = nop 82a85 > transaction.abort = real_abort 1145a1149,1155 > > # Restore sqlite connections' non-sharability > for conn in connections.all(): > if (conn.settings_dict['ENGINE'] == 'django.db.backends.sqlite3' > and conn.settings_dict['NAME'] == ':memory:'): > conn.allow_thread_sharing = False > diff -rw /tmp/Django-1.4/django/test/utils.py /tmp/Django-1.4.5/django/test/utils.py 77a78,80 > settings._original_allowed_hosts = settings.ALLOWED_HOSTS > settings.ALLOWED_HOSTS = ['*'] > 94a98,100 > > settings.ALLOWED_HOSTS = settings._original_allowed_hosts > del settings._original_allowed_hosts diff -rw /tmp/Django-1.4/django/utils/encoding.py /tmp/Django-1.4.5/django/utils/encoding.py 185a186,197 > > # Forwards compatibility with Django 1.5 > > def python_2_unicode_compatible(klass): > # Always use the Python 2 branch of the decorator here in Django 1.4 > klass.__unicode__ = klass.__str__ > klass.__str__ = lambda self: self.__unicode__().encode('utf-8') > return klass > > smart_text = smart_unicode > force_text = force_unicode > smart_bytes = smart_str diff -rw /tmp/Django-1.4/django/utils/html_parser.py /tmp/Django-1.4.5/django/utils/html_parser.py 2a3 > import sys 3a5 > current_version = sys.version_info 4a7,14 > use_workaround = ( > (current_version < (2, 7, 3)) or > (current_version >= (3, 0) and current_version < (3, 2, 3)) > ) > > if not use_workaround: > HTMLParser = _HTMLParser.HTMLParser > else: diff -rw /tmp/Django-1.4/django/utils/http.py /tmp/Django-1.4.5/django/utils/http.py 226a227,238 > > def is_safe_url(url, host=None): > """ > Return ``True`` if the url is a safe redirection (i.e. it doesn't point to > a different host). > > Always returns ``False`` on an empty url. > """ > if not url: > return False > netloc = urlparse.urlparse(url)[1] > return not netloc or netloc == host diff -rw /tmp/Django-1.4/django/utils/safestring.py /tmp/Django-1.4.5/django/utils/safestring.py 119a120,125 > # Forwards compatibility with Django 1.5 > > EscapeBytes = EscapeString > EscapeText = EscapeUnicode > SafeBytes = SafeString > SafeText = SafeUnicode Only in /tmp/Django-1.4.5/django/utils: six.py diff -rw /tmp/Django-1.4/django/utils/translation/trans_real.py /tmp/Django-1.4.5/django/utils/translation/trans_real.py 441,442c441,442 < inline_re = re.compile(r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))(\s+.*context\s+(?:"[^"]*?")|(?:'[^']*?'))?\s*""") < block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+(?:"[^"]*?")|(?:'[^']*?'))?(?:\s+|$)""") --- > inline_re = re.compile(r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*""") > block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""") diff -rw /tmp/Django-1.4/django/views/debug.py /tmp/Django-1.4.5/django/views/debug.py 158,160c158,171 < func_name = tb_frame.f_code.co_name < func = tb_frame.f_globals.get(func_name) < sensitive_variables = getattr(func, 'sensitive_variables', []) --- > # Loop through the frame's callers to see if the sensitive_variables > # decorator was used. > current_frame = tb_frame.f_back > sensitive_variables = None > while current_frame is not None: > if (current_frame.f_code.co_name == 'sensitive_variables_wrapper' > and 'sensitive_variables_wrapper' in current_frame.f_locals): > # The sensitive_variables decorator was used, so we take note > # of the sensitive variables' names. > wrapper = current_frame.f_locals['sensitive_variables_wrapper'] > sensitive_variables = getattr(wrapper, 'sensitive_variables', None) > break > current_frame = current_frame.f_back > diff -rw /tmp/Django-1.4/django/views/decorators/debug.py /tmp/Django-1.4.5/django/views/decorators/debug.py 29c29 < def wrapper(*args, **kwargs): --- > def sensitive_variables_wrapper(*args, **kwargs): 31c31 < wrapper.sensitive_variables = variables --- > sensitive_variables_wrapper.sensitive_variables = variables 33c33 < wrapper.sensitive_variables = '__ALL__' --- > sensitive_variables_wrapper.sensitive_variables = '__ALL__' 35c35 < return wrapper --- > return sensitive_variables_wrapper 64c64 < def wrapper(request, *args, **kwargs): --- > def sensitive_post_parameters_wrapper(request, *args, **kwargs): 70c70 < return wrapper --- > return sensitive_post_parameters_wrapper diff -rw /tmp/Django-1.4/django/views/i18n.py /tmp/Django-1.4.5/django/views/i18n.py 10a11,12 > from django.utils.http import is_safe_url > 23,26c25,28 < next = request.REQUEST.get('next', None) < if not next: < next = request.META.get('HTTP_REFERER', None) < if not next: --- > next = request.REQUEST.get('next') > if not is_safe_url(url=next, host=request.get_host()): > next = request.META.get('HTTP_REFERER') > if not is_safe_url(url=next, host=request.get_host()):
Leave a Reply
You must be logged in to post a comment.
Свежие комментарии