Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #8314 -- Fixed an infinite loop caused when submitting a sessio…

…n 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
  • Loading branch information...
commit 9e423b51e325c9226e2f744bfa52336a626bf63a 1 parent 9b66eae
Malcolm Tredinnick authored August 14, 2008
9  django/contrib/sessions/backends/base.py
@@ -153,13 +153,16 @@ def _set_session_key(self, session_key):
153 153
 
154 154
     session_key = property(_get_session_key, _set_session_key)
155 155
 
156  
-    def _get_session(self):
157  
-        # Lazily loads session from storage.
  156
+    def _get_session(self, no_load=False):
  157
+        """
  158
+        Lazily loads session from storage (unless "no_load" is True, when only
  159
+        an empty dict is stored) and stores it in the current instance.
  160
+        """
158 161
         self.accessed = True
159 162
         try:
160 163
             return self._session_cache
161 164
         except AttributeError:
162  
-            if self._session_key is None:
  165
+            if self._session_key is None or no_load:
163 166
                 self._session_cache = {}
164 167
             else:
165 168
                 self._session_cache = self.load()
3  django/contrib/sessions/backends/cache.py
@@ -30,7 +30,8 @@ def save(self, must_create=False):
30 30
             func = self._cache.add
31 31
         else:
32 32
             func = self._cache.set
33  
-        result = func(self.session_key, self._session, self.get_expiry_age())
  33
+        result = func(self.session_key, self._get_session(no_load=must_create),
  34
+                self.get_expiry_age())
34 35
         if must_create and not result:
35 36
             raise CreateError
36 37
 
2  django/contrib/sessions/backends/db.py
@@ -49,7 +49,7 @@ def save(self, must_create=False):
49 49
         """
50 50
         obj = Session(
51 51
             session_key = self.session_key,
52  
-            session_data = self.encode(self._session),
  52
+            session_data = self.encode(self._get_session(no_load=must_create)),
53 53
             expire_date = self.get_expiry_date()
54 54
         )
55 55
         sid = transaction.savepoint()
2  django/contrib/sessions/backends/file.py
@@ -73,7 +73,7 @@ def save(self, must_create=False):
73 73
             flags |= os.O_EXCL
74 74
         # Because this may trigger a load from storage, we must do it before
75 75
         # truncating the file to save.
76  
-        session_data = self._session
  76
+        session_data = self._get_session(no_load=must_create)
77 77
         try:
78 78
             fd = os.open(self._key_to_file(self.session_key), flags)
79 79
             try:
13  django/contrib/sessions/tests.py
@@ -5,6 +5,7 @@
5 5
 >>> from django.contrib.sessions.backends.cache import SessionStore as CacheSession
6 6
 >>> from django.contrib.sessions.backends.file import SessionStore as FileSession
7 7
 >>> from django.contrib.sessions.backends.base import SessionBase
  8
+>>> from django.contrib.sessions.models import Session
8 9
 
9 10
 >>> db_session = DatabaseSession()
10 11
 >>> db_session.modified
@@ -36,6 +37,12 @@
36 37
 >>> db_session.modified, db_session.accessed
37 38
 (True, True)
38 39
 
  40
+# Submitting an invalid session key (either by guessing, or if the db has
  41
+# removed the key) results in a new key being generated.
  42
+>>> Session.objects.filter(pk=db_session.session_key).delete()
  43
+>>> db_session = DatabaseSession(db_session.session_key)
  44
+>>> db_session.save()
  45
+
39 46
 >>> file_session = FileSession()
40 47
 >>> file_session.modified
41 48
 False
@@ -65,6 +72,9 @@
65 72
 False
66 73
 >>> file_session.modified, file_session.accessed
67 74
 (True, True)
  75
+>>> Session.objects.filter(pk=file_session.session_key).delete()
  76
+>>> file_session = FileSession(file_session.session_key)
  77
+>>> file_session.save()
68 78
 
69 79
 # Make sure the file backend checks for a good storage dir
70 80
 >>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer"
@@ -99,6 +109,9 @@
99 109
 False
100 110
 >>> cache_session.modified, cache_session.accessed
101 111
 (True, True)
  112
+>>> Session.objects.filter(pk=cache_session.session_key).delete()
  113
+>>> cache_session = CacheSession(cache_session.session_key)
  114
+>>> cache_session.save()
102 115
 
103 116
 >>> s = SessionBase()
104 117
 >>> s._session['some key'] = 'exists' # Pre-populate the session with some data

0 notes on commit 9e423b5

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