summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-08-14 19:43:08 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-08-14 19:43:08 +0000
commit9e423b51e325c9226e2f744bfa52336a626bf63a (patch)
tree5cd7afed4caf64dfd64d2dada7dd58fdec937074
parent9b66eae75f037c5f22eb94b33a8328015d0ec9c2 (diff)
Fixed #8314 -- Fixed an infinite loop caused when submitting a session key (via
a cookie) with no corresponding entry in the database. This only affected the database backend, but I've applied the same fix to all three backends for robustness. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8351 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/sessions/backends/base.py9
-rw-r--r--django/contrib/sessions/backends/cache.py3
-rw-r--r--django/contrib/sessions/backends/db.py2
-rw-r--r--django/contrib/sessions/backends/file.py2
-rw-r--r--django/contrib/sessions/tests.py13
5 files changed, 23 insertions, 6 deletions
diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
index 9f4bf6f487..f64ef852cf 100644
--- a/django/contrib/sessions/backends/base.py
+++ b/django/contrib/sessions/backends/base.py
@@ -153,13 +153,16 @@ class SessionBase(object):
session_key = property(_get_session_key, _set_session_key)
- def _get_session(self):
- # Lazily loads session from storage.
+ def _get_session(self, no_load=False):
+ """
+ Lazily loads session from storage (unless "no_load" is True, when only
+ an empty dict is stored) and stores it in the current instance.
+ """
self.accessed = True
try:
return self._session_cache
except AttributeError:
- if self._session_key is None:
+ if self._session_key is None or no_load:
self._session_cache = {}
else:
self._session_cache = self.load()
diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py
index 2988d3ee09..157d18a586 100644
--- a/django/contrib/sessions/backends/cache.py
+++ b/django/contrib/sessions/backends/cache.py
@@ -30,7 +30,8 @@ class SessionStore(SessionBase):
func = self._cache.add
else:
func = self._cache.set
- result = func(self.session_key, self._session, self.get_expiry_age())
+ result = func(self.session_key, self._get_session(no_load=must_create),
+ self.get_expiry_age())
if must_create and not result:
raise CreateError
diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py
index df9d64e7c4..e697bc56b1 100644
--- a/django/contrib/sessions/backends/db.py
+++ b/django/contrib/sessions/backends/db.py
@@ -49,7 +49,7 @@ class SessionStore(SessionBase):
"""
obj = Session(
session_key = self.session_key,
- session_data = self.encode(self._session),
+ session_data = self.encode(self._get_session(no_load=must_create)),
expire_date = self.get_expiry_date()
)
sid = transaction.savepoint()
diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py
index 7fb608df90..3438b097c4 100644
--- a/django/contrib/sessions/backends/file.py
+++ b/django/contrib/sessions/backends/file.py
@@ -73,7 +73,7 @@ class SessionStore(SessionBase):
flags |= os.O_EXCL
# Because this may trigger a load from storage, we must do it before
# truncating the file to save.
- session_data = self._session
+ session_data = self._get_session(no_load=must_create)
try:
fd = os.open(self._key_to_file(self.session_key), flags)
try:
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index ec4da2d543..9b88bed8d8 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -5,6 +5,7 @@ r"""
>>> from django.contrib.sessions.backends.cache import SessionStore as CacheSession
>>> from django.contrib.sessions.backends.file import SessionStore as FileSession
>>> from django.contrib.sessions.backends.base import SessionBase
+>>> from django.contrib.sessions.models import Session
>>> db_session = DatabaseSession()
>>> db_session.modified
@@ -36,6 +37,12 @@ False
>>> db_session.modified, db_session.accessed
(True, True)
+# Submitting an invalid session key (either by guessing, or if the db has
+# removed the key) results in a new key being generated.
+>>> Session.objects.filter(pk=db_session.session_key).delete()
+>>> db_session = DatabaseSession(db_session.session_key)
+>>> db_session.save()
+
>>> file_session = FileSession()
>>> file_session.modified
False
@@ -65,6 +72,9 @@ False
False
>>> file_session.modified, file_session.accessed
(True, True)
+>>> Session.objects.filter(pk=file_session.session_key).delete()
+>>> file_session = FileSession(file_session.session_key)
+>>> file_session.save()
# Make sure the file backend checks for a good storage dir
>>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer"
@@ -99,6 +109,9 @@ False
False
>>> cache_session.modified, cache_session.accessed
(True, True)
+>>> Session.objects.filter(pk=cache_session.session_key).delete()
+>>> cache_session = CacheSession(cache_session.session_key)
+>>> cache_session.save()
>>> s = SessionBase()
>>> s._session['some key'] = 'exists' # Pre-populate the session with some data