Skip to content

Commit 378bcd8

Browse files
Require concrete string header values
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent ae46372 commit 378bcd8

File tree

2 files changed

+21
-51
lines changed

2 files changed

+21
-51
lines changed

hyperbrowser/header_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def normalize_headers(
4949
for key, value in _read_header_items(
5050
headers, mapping_error_message=mapping_error_message
5151
):
52-
if type(key) is not str or not isinstance(value, str):
52+
if type(key) is not str or type(value) is not str:
5353
raise HyperbrowserError(effective_pair_error_message)
5454
try:
5555
normalized_key = key.strip()

tests/test_header_utils.py

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,8 @@ def strip(self, chars=None): # type: ignore[override]
6464
return self._NormalizedHeaders('{"X-Trace-Id":"abc123"}')
6565

6666

67-
class _BrokenHeaderValueContains(str):
68-
def __contains__(self, item): # type: ignore[override]
69-
_ = item
70-
raise RuntimeError("header value contains exploded")
71-
72-
73-
class _BrokenHeaderValueStringify(str):
74-
def __str__(self) -> str:
75-
raise RuntimeError("header value stringify exploded")
67+
class _StringSubclassHeaderValue(str):
68+
pass
7669

7770

7871
def test_normalize_headers_trims_header_names():
@@ -102,6 +95,18 @@ def test_normalize_headers_rejects_string_subclass_header_names():
10295
)
10396

10497

98+
def test_normalize_headers_rejects_string_subclass_header_values():
99+
with pytest.raises(
100+
HyperbrowserError, match="headers must be a mapping of string pairs"
101+
) as exc_info:
102+
normalize_headers(
103+
{"X-Trace-Id": _StringSubclassHeaderValue("trace-1")},
104+
mapping_error_message="headers must be a mapping of string pairs",
105+
)
106+
107+
assert exc_info.value.original_error is None
108+
109+
105110
def test_normalize_headers_rejects_overly_long_header_names():
106111
long_header_name = "X-" + ("a" * 255)
107112
with pytest.raises(
@@ -170,12 +175,16 @@ def test_parse_headers_env_json_rejects_string_subclass_input_values():
170175
with pytest.raises(
171176
HyperbrowserError, match="HYPERBROWSER_HEADERS must be a string"
172177
):
173-
parse_headers_env_json(_NonStringHeadersEnvStripResult('{"X-Trace-Id":"abc123"}'))
178+
parse_headers_env_json(
179+
_NonStringHeadersEnvStripResult('{"X-Trace-Id":"abc123"}')
180+
)
174181

175182
with pytest.raises(
176183
HyperbrowserError, match="HYPERBROWSER_HEADERS must be a string"
177184
):
178-
parse_headers_env_json(_StringSubclassHeadersEnvStripResult('{"X-Trace-Id":"abc123"}'))
185+
parse_headers_env_json(
186+
_StringSubclassHeadersEnvStripResult('{"X-Trace-Id":"abc123"}')
187+
)
179188

180189

181190
def test_parse_headers_env_json_rejects_invalid_json():
@@ -270,45 +279,6 @@ def test_normalize_headers_rejects_control_characters():
270279
)
271280

272281

273-
def test_normalize_headers_wraps_header_character_validation_contains_failures():
274-
with pytest.raises(
275-
HyperbrowserError, match="Failed to validate header characters"
276-
) as exc_info:
277-
normalize_headers(
278-
{"X-Trace-Id": _BrokenHeaderValueContains("value")},
279-
mapping_error_message="headers must be a mapping of string pairs",
280-
)
281-
282-
assert isinstance(exc_info.value.original_error, RuntimeError)
283-
284-
285-
def test_normalize_headers_preserves_header_character_validation_contains_hyperbrowser_failures():
286-
class _BrokenHeaderValueContains(str):
287-
def __contains__(self, item): # type: ignore[override]
288-
_ = item
289-
raise HyperbrowserError("custom contains failure")
290-
291-
with pytest.raises(HyperbrowserError, match="custom contains failure") as exc_info:
292-
normalize_headers(
293-
{"X-Trace-Id": _BrokenHeaderValueContains("value")},
294-
mapping_error_message="headers must be a mapping of string pairs",
295-
)
296-
297-
assert exc_info.value.original_error is None
298-
299-
300-
def test_normalize_headers_wraps_header_character_validation_stringify_failures():
301-
with pytest.raises(
302-
HyperbrowserError, match="Failed to validate header characters"
303-
) as exc_info:
304-
normalize_headers(
305-
{"X-Trace-Id": _BrokenHeaderValueStringify("value")},
306-
mapping_error_message="headers must be a mapping of string pairs",
307-
)
308-
309-
assert isinstance(exc_info.value.original_error, RuntimeError)
310-
311-
312282
def test_parse_headers_env_json_rejects_control_characters():
313283
with pytest.raises(
314284
HyperbrowserError, match="headers must not contain control characters"

0 commit comments

Comments
 (0)