Invalid handling of chunked delivery of status codes
Safihre opened this issue · comments
SABnzbd version
Any
Operating system
Any
Using Docker image
None
Description
User reported Downloader crashes:
https://forums.sabnzbd.org/viewtopic.php?t=26559
First we expected just a crappy server since it's not one of the very well known providers, but the user supplied us with a test NZB and access to the server.
I found that our status code handling in recv_chunk
and process_nw
does not consider that statuses can be delivered in chunks.
As an example for pre-check:
- We request the article.
- First
recv_chunk
the data received and in the buffer is223 0 <8ovy7qDr2UbhGvy6Xo6@107f9dd2724620839a39cFeqL0UPPpJjg1sd0
, which is missing the closing>\r\n
- We see the
223
inprocess_nw
and sayArticle present
. - We request the next article and reset the
nw.data_position
to0
, however, the server wasn't done yet with our first request. - The next
recv_chunk
we read the leftover>\r\n
and nownw.data[:nw.data_position]
is:>\r\n
NNTP always ends in \r\n
, so we should not have done anything unless that was the last data we recieved.
Awesome edge case!
How are you intending on resolving it?
I was thinking we could make nw.status_code
search for \r\n
and handle it returing None in process_nw
also cache/store the value to avoid repeatedly searching.
I think you should use data_view
for the search, else you'd copy the whole buffer.
I recall from the spec there is a maximum line length you could limit it to but slicing the data_view doesn't use memory anyway.
I recall from the spec there is a maximum line length you could limit it to
That would be RFC 3977 §3.1: The initial line of the response MUST NOT exceed 512 octets, which includes the response code and the terminating CRLF pair [...]
I think it's pretty simple, we need to modify recv_chunk to also return if it's end of line CRLF.
Only if that's the case we process the status code.