Fix: Prevent Null Pointer Dereference in HTTPAdapter methods
Summary
This PR addresses a robustness issue in the HTTPAdapter class where None values in PreparedRequest objects could cause TypeError and AttributeError exceptions. The fix adds defensive null checks to prevent null pointer dereference errors when processing requests with uninitialized or None attributes.
Problem
PreparedRequest.__init__() initializes both self.url and self.headers to None. Several methods in HTTPAdapter did not handle these None values defensively, leading to potential crashes:
-
request_url()method: Calledurlparse(request.url)andselect_proxy(request.url, proxies)without checking ifrequest.urlisNone -
_urllib3_request_context()function: Calledurlparse(request.url)without null checks -
send()method: Evaluated"Content-Length" in request.headerswhenrequest.headerscould beNone, causingTypeError: argument of type 'NoneType' is not iterable
Solution
Added defensive null handling using the or operator with appropriate fallback values:
-
request.url or ""- Falls back to empty string for URL parsing operations -
request.headers or {}- Falls back to empty dict for membership checks
Changes Made
src/requests/adapters.py
-
_urllib3_request_context(): Changedurlparse(request.url)→urlparse(request.url or "") -
request_url(): Added null safety for:-
select_proxy(request.url or "", proxies) -
urlparse(request.url or "").scheme -
urldefragauth(request.url or "")
-
-
send(): Changed"Content-Length" in request.headers→"Content-Length" in (request.headers or {})
tests/test_adapters.py
Added comprehensive test coverage (103 new lines):
-
test_request_url_with_none_url()- Verifies graceful handling of None URL -
test_request_url_with_none_url_and_proxy()- Tests None URL with proxy configuration -
test_send_with_none_headers()- Ensures None headers don't cause TypeError -
test_urllib3_request_context_with_none_url()- Validates None URL handling in context builder
Impact
- Type: Bug fix / Robustness improvement
- Severity: Medium (prevents crashes but edge case scenario)
- Compatibility: Fully backward compatible, no API changes
- Performance: Negligible (only adds null coalescing checks)
Testing
All new tests pass and verify that the methods handle None values gracefully without raising TypeError or AttributeError exceptions. The fixes ensure robust behavior even when PreparedRequest objects are not fully initialized.
I should add that this issue was found because of I think (I'm not 100% sure because everything was also typed according to mypy rules in the commit) pylint in https://github.com/psf/requests/pull/7054, if it was pylint that found this issue and it is a legitimate issue then it makes a strong case for the project to start using it imo.