http: make the RTSP version check stricter

- make it only accept version 1.0, as that is the version curl supports
- convert the parser to use strparse
- the status code max is now 999, but it does allow != 3 digits

Closes #16435
This commit is contained in:
Daniel Stenberg 2025-02-21 23:48:51 +01:00
parent cfc657a48d
commit 4c5099868e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 35 additions and 23 deletions

View File

@ -151,6 +151,15 @@ int Curl_str_casecompare(struct Curl_str *str, const char *check);
Returns true if the provided string in the `str` argument matches the `check`
string case insensitively.
## `Curl_str_cmp`
~~~c
int Curl_str_cmp(struct Curl_str *str, const char *check);
~~~
Returns true if the provided string in the `str` argument matches the `check`
string case sensitively. This is *not* the same return code as `strcmp`.
## `Curl_str_nudge`
~~~c

View File

@ -3987,30 +3987,22 @@ static CURLcode http_rw_hd(struct Curl_easy *data,
}
else if(data->conn->handler->protocol & CURLPROTO_RTSP) {
const char *p = hd;
while(ISBLANK(*p))
p++;
if(!strncmp(p, "RTSP/", 5)) {
p += 5;
if(ISDIGIT(*p)) {
p++;
if((p[0] == '.') && ISDIGIT(p[1])) {
if(ISBLANK(p[2])) {
p += 3;
if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) {
k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 +
(p[2] - '0');
p += 3;
if(ISSPACE(*p)) {
fine_statusline = TRUE;
k->httpversion = 11; /* RTSP acts like HTTP 1.1 */
}
}
}
}
struct Curl_str ver;
curl_off_t status;
/* we set the max string a little excessive to forgive some leading
spaces */
if(!Curl_str_until(&p, &ver, 32, ' ') &&
!Curl_str_single(&p, ' ') &&
!Curl_str_number(&p, &status, 999)) {
Curl_str_trimblanks(&ver);
if(Curl_str_cmp(&ver, "RTSP/1.0")) {
k->httpcode = (int)status;
fine_statusline = TRUE;
k->httpversion = 11; /* RTSP acts like HTTP 1.1 */
}
if(!fine_statusline)
return CURLE_WEIRD_SERVER_REPLY;
}
if(!fine_statusline)
return CURLE_WEIRD_SERVER_REPLY;
}
if(fine_statusline) {

View File

@ -203,6 +203,16 @@ int Curl_str_casecompare(struct Curl_str *str, const char *check)
return ((str->len == clen) && strncasecompare(str->str, check, clen));
}
/* case sensitive string compare. Returns non-zero on match. */
int Curl_str_cmp(struct Curl_str *str, const char *check)
{
if(check) {
size_t clen = strlen(check);
return ((str->len == clen) && !strncmp(str->str, check, clen));
}
return !!(str->len);
}
/* Trim off 'num' number of bytes from the beginning (left side) of the
string. If 'num' is larger than the string, return error. */
int Curl_str_nudge(struct Curl_str *str, size_t num)

View File

@ -85,6 +85,7 @@ int Curl_str_newline(const char **linep);
/* case insensitive compare that the parsed string matches the
given string. */
int Curl_str_casecompare(struct Curl_str *str, const char *check);
int Curl_str_cmp(struct Curl_str *str, const char *check);
int Curl_str_nudge(struct Curl_str *str, size_t num);

View File

@ -11,7 +11,7 @@ OPTIONS
# Server-side
<reply>
<data>
RTSP/7.1 786
RTSP/1.0 786
RTSP/
</data>