Code

Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#12197 closed (invalid)

parse_accept_lang_header parse HTTP_ACCEPT_LANGUAGE with wrong Quality factors

Reported by: flier.lu@… Owned by: nobody
Component: Internationalization Version: 1.1
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by adrian)

According to the RFC 2616 <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html>, HTTP_ACCEPT_LANGUAGE could have several languages options, such as

da, en-gb;q=0.8, en;q=0.7

So, django parse those string with parse_accept_lang_header method, and order the options base on its 'q' quality factor.

But the re.split seems return a list with a empty string as first element, such as

s = 'da, en-gb;q=0.8, en;q=0.7'

r.split(s)

['', 'da', None, '', 'en-gb', '0.8', '', 'en', '0.7', '']

But parse_accept_lang_header use it from index 0, it means they align to wrong index

To fix the issues, you could modify the accept_language_re, or use the return list from index 1.

def parse_accept_lang_header(lang_string):
    """
    Parses the lang_string, which is the body of an HTTP Accept-Language
    header, and returns a list of (lang, q-value), ordered by 'q' values.

    Any format errors in lang_string results in an empty list being returned.
    """
    result = []
    pieces = accept_language_re.split(lang_string)
    if pieces[-1]:
        return []
    for i in range(0, len(pieces) - 1, 3):
        first, lang, priority = pieces[i : i + 3]
        if first:
            return []
        priority = priority and float(priority) or 1.0
        result.append((lang, priority))
    result.sort(lambda x, y: -cmp(x[1], y[1]))
    return result

Attachments (0)

Change History (4)

comment:1 Changed 4 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 4 years ago by adrian

  • Description modified (diff)

comment:3 Changed 4 years ago by ramiro

  • Has patch unset
  • Resolution set to invalid
  • Status changed from new to closed

There is a test case in the Django test suite that test exactly for a header value almost identical to the one you posted that demonstrates the algorihtm is working as expected: http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/i18n/tests.py?rev=12373#L394

The fact that the list after splitting the header value by the RE is represented by three consecutive items for each lang specification element is by design and the value of the first one (first variable) is used to detect incorrectly formatted values if not empty, and then discarded.

So, I don't know your report is because of an issue you are seeing in real world usage or the result of a theoretical analisys. If it's the former please post more details, in the meantime I'm marking this ticket as invalid.

comment:4 Changed 3 years ago by jacob

  • milestone 1.2 deleted

Milestone 1.2 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.