Skip to content

Commit 6544272

Browse files
authored
Prevent user-submitted garbage in locale fields (#17947)
* Parametrize test * Add failing tests * Only negotiate a known locale
1 parent f020942 commit 6544272

File tree

2 files changed

+50
-38
lines changed

2 files changed

+50
-38
lines changed

tests/unit/i18n/test_init.py

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,48 @@ def test_when_locale_is_missing(monkeypatch):
106106
assert i18n._locale(request) is locale_obj
107107

108108

109-
def test_negotiate_locale(monkeypatch):
110-
request = pretend.stub(_LOCALE_="fake-locale-attr")
111-
assert i18n._negotiate_locale(request) == "fake-locale-attr"
112-
113-
request = pretend.stub(params={"_LOCALE_": "fake-locale-param"})
114-
assert i18n._negotiate_locale(request) == "fake-locale-param"
115-
116-
request = pretend.stub(params={}, cookies={"_LOCALE_": "fake-locale-cookie"})
117-
assert i18n._negotiate_locale(request) == "fake-locale-cookie"
118-
119-
request = pretend.stub(params={}, cookies={}, accept_language=None)
120-
default_locale_negotiator = pretend.call_recorder(lambda r: "fake-locale-default")
121-
monkeypatch.setattr(i18n, "default_locale_negotiator", default_locale_negotiator)
122-
assert i18n._negotiate_locale(request) == "fake-locale-default"
123-
124-
request = pretend.stub(
125-
params={},
126-
cookies={},
127-
accept_language=pretend.stub(
128-
best_match=pretend.call_recorder(lambda *a, **kw: "fake-locale-best-match")
109+
@pytest.mark.parametrize(
110+
("req", "expected"),
111+
[
112+
(pretend.stub(_LOCALE_="eo", accept_language=None), "eo"),
113+
(pretend.stub(params={"_LOCALE_": "eo"}, accept_language=None), "eo"),
114+
(
115+
pretend.stub(params={}, cookies={"_LOCALE_": "eo"}, accept_language=None),
116+
"eo",
129117
),
130-
)
131-
assert i18n._negotiate_locale(request) == "fake-locale-best-match"
118+
(pretend.stub(params={}, cookies={}, accept_language=None), None),
119+
(
120+
pretend.stub(
121+
params={},
122+
cookies={},
123+
accept_language=pretend.stub(
124+
best_match=lambda *a, **kw: "fake-locale-best-match"
125+
),
126+
),
127+
"fake-locale-best-match",
128+
),
129+
(
130+
pretend.stub(
131+
params={}, cookies={}, _LOCALE_="garbage", accept_language=None
132+
),
133+
None,
134+
),
135+
(
136+
pretend.stub(
137+
params={"_LOCALE_": "garbage"}, cookies={}, accept_language=None
138+
),
139+
None,
140+
),
141+
(
142+
pretend.stub(
143+
params={}, cookies={"_LOCALE_": "garbage"}, accept_language=None
144+
),
145+
None,
146+
),
147+
],
148+
)
149+
def test_negotiate_locale(monkeypatch, req, expected):
150+
assert i18n._negotiate_locale(req) == expected
132151

133152

134153
def test_localize(monkeypatch):

warehouse/i18n/__init__.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,17 @@ def _locale(request):
8080

8181

8282
def _negotiate_locale(request):
83-
locale_name = getattr(request, LOCALE_ATTR, None)
84-
if locale_name is not None:
85-
return locale_name
86-
87-
locale_name = request.params.get(LOCALE_ATTR)
88-
if locale_name is not None:
89-
return locale_name
90-
91-
locale_name = request.cookies.get(LOCALE_ATTR)
92-
if locale_name is not None:
93-
return locale_name
94-
9583
if not request.accept_language:
96-
return default_locale_negotiator(request)
84+
locale_name = default_locale_negotiator(request)
85+
if locale_name in KNOWN_LOCALES:
86+
return locale_name
87+
else:
88+
return request.accept_language.best_match(
89+
tuple(KNOWN_LOCALES.keys()),
90+
default_match=default_locale_negotiator(request),
91+
)
9792

98-
return request.accept_language.best_match(
99-
tuple(KNOWN_LOCALES.keys()), default_match=default_locale_negotiator(request)
100-
)
93+
return None
10194

10295

10396
def _localize(request, message, **kwargs):

0 commit comments

Comments
 (0)