ftp: make the MDTM date parser stricter (again)

A previous refactor made the parser more lenient and this takes it back
to making sure only ascii digits are accepted.

Added test 1684 to verify

Follow-up to 304b5183fd

Pointed out by Codex Security

Closes #21041
This commit is contained in:
Daniel Stenberg 2026-03-20 23:27:55 +01:00
parent 96d5b5c688
commit 322db3efc0
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 60 additions and 11 deletions

View file

@ -2489,24 +2489,27 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
return result;
}
static int twodigit(const char *p)
/* return TRUE on error, FALSE on success */
static bool twodigit(const char *p, int *val)
{
return ((p[0] - '0') * 10) + (p[1] - '0');
if(!ISDIGIT(p[0]) || !ISDIGIT(p[1]))
return TRUE;
/* curlx_hexval() works fine here since we make sure it is decimal above */
*val = (curlx_hexval(p[0]) * 10) + curlx_hexval(p[1]);
return FALSE;
}
static bool ftp_213_date(const char *p, int *year, int *month, int *day,
int *hour, int *minute, int *second)
{
size_t len = strlen(p);
if(len < 14)
int century;
if((strlen(p) < 14) || twodigit(&p[0], &century) || twodigit(&p[2], year) ||
twodigit(&p[4], month) || twodigit(&p[6], day) ||
twodigit(&p[8], hour) || twodigit(&p[10], minute) ||
twodigit(&p[12], second))
return FALSE;
*year = (twodigit(&p[0]) * 100) + twodigit(&p[2]);
*month = twodigit(&p[4]);
*day = twodigit(&p[6]);
*hour = twodigit(&p[8]);
*minute = twodigit(&p[10]);
*second = twodigit(&p[12]);
*year += century * 100;
if((*month > 12) || (*day > 31) || (*hour > 23) || (*minute > 59) ||
(*second > 60))
return FALSE;