Changeset 6607
- Timestamp:
- 10/26/07 14:52:29 (1 year ago)
- Files:
-
- django/branches/0.96-bugfixes/django/conf/global_settings.py (modified) (1 diff)
- django/branches/0.96-bugfixes/django/__init__.py (modified) (1 diff)
- django/branches/0.96-bugfixes/django/utils/translation/trans_real.py (modified) (4 diffs)
- django/branches/0.96-bugfixes/docs/release_notes_0.96.txt (modified) (2 diffs)
- django/branches/0.96-bugfixes/setup.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/0.96-bugfixes/django/conf/global_settings.py
r4766 r6607 238 238 # The User-Agent string to use when checking for URL validity through the 239 239 # isExistingURL validator. 240 URL_VALIDATOR_USER_AGENT = "Django/0.96 pre(http://www.djangoproject.com)"240 URL_VALIDATOR_USER_AGENT = "Django/0.96.1 (http://www.djangoproject.com)" 241 241 242 242 ############## django/branches/0.96-bugfixes/django/__init__.py
r4809 r6607 1 VERSION = (0, 96 , None)1 VERSION = (0, 96.1, None) django/branches/0.96-bugfixes/django/utils/translation/trans_real.py
r4486 r6607 1 1 "Translation helper functions" 2 2 3 import os, re, sys 3 import locale 4 import os 5 import re 6 import sys 4 7 import gettext as gettext_module 5 8 from cStringIO import StringIO … … 26 29 _default = None 27 30 28 # This is a cache for accept-header to translation object mappings to prevent29 # the accept parser to run multiple times for one user.31 # This is a cache for normalised accept-header languages to prevent multiple 32 # file lookups when checking the same locale on repeated requests. 30 33 _accepted = {} 31 34 32 def to_locale(language): 35 # Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9. 36 accept_language_re = re.compile(r''' 37 ([A-Za-z]{1,8}(?:-[A-Za-z]{1,8})*|\*) # "en", "en-au", "x-y-z", "*" 38 (?:;q=(0(?:\.\d{,3})?|1(?:.0{,3})?))? # Optional "q=1.00", "q=0.8" 39 (?:\s*,\s*|$) # Multiple accepts per header. 40 ''', re.VERBOSE) 41 42 def to_locale(language, to_lower=False): 33 43 "Turns a language name (en-us) into a locale name (en_US)." 34 44 p = language.find('-') 35 45 if p >= 0: 36 return language[:p].lower()+'_'+language[p+1:].upper() 46 if to_lower: 47 return language[:p].lower()+'_'+language[p+1:].lower() 48 else: 49 return language[:p].lower()+'_'+language[p+1:].upper() 37 50 else: 38 51 return language.lower() … … 310 323 return lang_code 311 324 312 lang_code = request.COOKIES.get('django_language' , None)313 if lang_code in supported and lang_code is not Noneand check_for_language(lang_code):325 lang_code = request.COOKIES.get('django_language') 326 if lang_code and lang_code in supported and check_for_language(lang_code): 314 327 return lang_code 315 328 316 accept = request.META.get('HTTP_ACCEPT_LANGUAGE', None) 317 if accept is not None: 318 319 t = _accepted.get(accept, None) 320 if t is not None: 321 return t 322 323 def _parsed(el): 324 p = el.find(';q=') 325 if p >= 0: 326 lang = el[:p].strip() 327 order = int(float(el[p+3:].strip())*100) 328 else: 329 lang = el 330 order = 100 331 p = lang.find('-') 332 if p >= 0: 333 mainlang = lang[:p] 334 else: 335 mainlang = lang 336 return (lang, mainlang, order) 337 338 langs = [_parsed(el) for el in accept.split(',')] 339 langs.sort(lambda a,b: -1*cmp(a[2], b[2])) 340 341 for lang, mainlang, order in langs: 342 if lang in supported or mainlang in supported: 343 langfile = gettext_module.find('django', globalpath, [to_locale(lang)]) 344 if langfile: 345 # reconstruct the actual language from the language 346 # filename, because otherwise we might incorrectly 347 # report de_DE if we only have de available, but 348 # did find de_DE because of language normalization 349 lang = langfile[len(globalpath):].split(os.path.sep)[1] 350 _accepted[accept] = lang 351 return lang 329 accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') 330 for lang, unused in parse_accept_lang_header(accept): 331 if lang == '*': 332 break 333 334 # We have a very restricted form for our language files (no encoding 335 # specifier, since they all must be UTF-8 and only one possible 336 # language each time. So we avoid the overhead of gettext.find() and 337 # look up the MO file manually. 338 339 normalized = locale.locale_alias.get(to_locale(lang, True)) 340 if not normalized: 341 continue 342 343 # Remove the default encoding from locale_alias 344 normalized = normalized.split('.')[0] 345 346 if normalized in _accepted: 347 # We've seen this locale before and have an MO file for it, so no 348 # need to check again. 349 return _accepted[normalized] 350 351 for lang in (normalized, normalized.split('_')[0]): 352 if lang not in supported: 353 continue 354 langfile = os.path.join(globalpath, lang, 'LC_MESSAGES', 355 'django.mo') 356 if os.path.exists(langfile): 357 _accepted[normalized] = lang 358 return lang 352 359 353 360 return settings.LANGUAGE_CODE … … 495 502 496 503 string_concat = lazy(string_concat, str) 504 505 def parse_accept_lang_header(lang_string): 506 """ 507 Parses the lang_string, which is the body of an HTTP Accept-Language 508 header, and returns a list of (lang, q-value), ordered by 'q' values. 509 510 Any format errors in lang_string results in an empty list being returned. 511 """ 512 result = [] 513 pieces = accept_language_re.split(lang_string) 514 if pieces[-1]: 515 return [] 516 for i in range(0, len(pieces) - 1, 3): 517 first, lang, priority = pieces[i : i + 3] 518 if first: 519 return [] 520 priority = priority and float(priority) or 1.0 521 result.append((lang, priority)) 522 result.sort(lambda x, y: -cmp(x[1], y[1])) 523 return result 524 django/branches/0.96-bugfixes/docs/release_notes_0.96.txt
r4803 r6607 1 ================================= 2 Django version 0.96 release notes3 ================================= 4 5 Welcome to Django 0.96 !1 =================================== 2 Django version 0.96.1 release notes 3 =================================== 4 5 Welcome to Django 0.96.1! 6 6 7 7 The primary goal for 0.96 is a cleanup and stabilization of the features 8 8 introduced in 0.95. There have been a few small `backwards-incompatible 9 changes `_ since 0.95, but the upgrade process should be fairly simple9 changes since 0.95`_, but the upgrade process should be fairly simple 10 10 and should not require major changes to existing applications. 11 11 … … 18 18 development version of Django. 19 19 20 Backwards-incompatible changes 20 Changes since the 0.96 release 21 21 ============================== 22 23 This release contains fixes for a security vulnerability discovered after the 24 initial release of Django 0.96. A bug in the i18n framework could allow an 25 attacker to send extremely large strings in the Accept-Language header and 26 cause a denial of service by filling available memory. 27 28 Because this problems wasn't discovered and fixed until after the 0.96 29 release, it's recommended that you use this release rather than the original 30 0.96. 31 32 Backwards-incompatible changes since 0.95 33 ========================================= 22 34 23 35 The following changes may require you to update your code when you switch from django/branches/0.96-bugfixes/setup.py
r4550 r6607 33 33 file_info[0] = '/PURELIB/%s' % file_info[0] 34 34 35 # Dynamically calculate the version based on django.VERSION.36 version = "%d.%d-%s" % (__import__('django').VERSION)37 38 35 setup( 39 36 name = "Django", 40 version = version,37 version = "0.96.1", 41 38 url = 'http://www.djangoproject.com/', 42 39 author = 'Lawrence Journal-World',
