#9180: Low-level cache interface incorrectly tries to typecast bytestring
--------------------------+-------------------------------------------------
Reporter: p | Owner: nobody
Status: new | Milestone:
Component: Cache system | Version: 1.0
Keywords: | Stage: Unreviewed
Has_patch: 0 |
--------------------------+-------------------------------------------------
The low-level Django cache API encodes basestrings as UTF-8 when
{{{set}}}ting, and decodes basestrings as Unicode when {{{get}}}ting.
If you're trying to store a string of bytes in the cache -- for instance,
the raw bytes of an image -- the set operation will possibly modify the
data by encoding it, and the get operation will potentially raise a
!DjangoUnicodeDecodeError if the codec can't decode bytes in the string.
{{{
#!python
from django.core.cache import cache
from django.utils.encoding import DjangoUnicodeDecodeError
# The simplest possible GIF: a 43-byte, 1x1-pixel transparent image
EMPTY_GIF_BYTES =
'GIF89a\x01\x00\x01\x00\xf0\x00\x00\xb0\x8cZ\x00\x00\x00!\xf9\x04\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;'
cache.set('empty_gif', EMPTY_GIF_BYTES)
try:
cache.get('empty_gif')
except DjangoUnicodeDecodeError:
print 'Tried to decode GIF bytestring as a Unicode string'
else:
print 'Got the raw GIF bytestring'
}}}
A workaround is to create a one-tuple from the bytestring when storing,
and when retrieving, returning the single element from the tuple.
{{{
#!python
def raw_cache_set(key, value, timeout_seconds=None):
cache.set(key, (value,), timeout_seconds=timeout_seconds)
def raw_cache_get(key):
value = cache.get(key)
if value is not None:
return value[0]
raw_cache_set('empty_gif', EMPTY_GIF_BYTES)
assert raw_cache_get('empty_gif') == EMPTY_GIF_BYTES
}}}
One possible fix would be to expose a {{{raw}}} keyword argument boolean
to {{{cache.get}}}, {{{cache.set}}}, {{{cache.add}}}, {{{cache.get_many}}}
that would conditionally skip any {{{smart_unicode}}} or other
encoding/decoding logic when storing or retrieving from the cache.
--
Ticket URL: <http://code.djangoproject.com/ticket/9180>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---