[misc] Make safe_xxx integer conversions safer by checking for NULL input

Also don't touch output on error + fix missing check for return in db.c
This commit is contained in:
ejurgensen 2021-10-09 00:48:36 +02:00
parent c4d57aa5d1
commit 41e3733ccc
2 changed files with 38 additions and 24 deletions

View File

@ -819,11 +819,14 @@ struct_field_set_uint32(void *dst, const void *src, bool parse_integers)
{ {
char *srcstr; char *srcstr;
uint32_t srcu32val; uint32_t srcu32val;
int ret;
if (parse_integers) if (parse_integers)
{ {
srcstr = *(char **)(src); srcstr = *(char **)(src);
safe_atou32(srcstr, &srcu32val); ret = safe_atou32(srcstr, &srcu32val);
if (ret < 0)
srcu32val = 0;
} }
else else
srcu32val = *(uint32_t *)(src); srcu32val = *(uint32_t *)(src);
@ -836,11 +839,14 @@ struct_field_set_int64(void *dst, const void *src, bool parse_integers)
{ {
char *srcstr; char *srcstr;
int64_t srci64val; int64_t srci64val;
int ret;
if (parse_integers) if (parse_integers)
{ {
srcstr = *(char **)(src); srcstr = *(char **)(src);
safe_atoi64(srcstr, &srci64val); ret = safe_atoi64(srcstr, &srci64val);
if (ret < 0)
srci64val = 0;
} }
else else
srci64val = *(int64_t *)(src); srci64val = *(int64_t *)(src);

View File

@ -398,7 +398,11 @@ safe_atoi32(const char *str, int32_t *val)
char *end; char *end;
long intval; long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_atoi32 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtol(str, &end, 10); intval = strtol(str, &end, 10);
@ -407,21 +411,18 @@ safe_atoi32(const char *str, int32_t *val)
|| ((errno != 0) && (intval == 0))) || ((errno != 0) && (intval == 0)))
{ {
DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno)); DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
return -1; return -1;
} }
if (end == str) if (end == str)
{ {
DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str); DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
return -1; return -1;
} }
if (intval > INT32_MAX) if (intval > INT32_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }
@ -436,7 +437,11 @@ safe_atou32(const char *str, uint32_t *val)
char *end; char *end;
unsigned long intval; unsigned long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_atou32 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtoul(str, &end, 10); intval = strtoul(str, &end, 10);
@ -445,21 +450,18 @@ safe_atou32(const char *str, uint32_t *val)
|| ((errno != 0) && (intval == 0))) || ((errno != 0) && (intval == 0)))
{ {
DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno)); DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
return -1; return -1;
} }
if (end == str) if (end == str)
{ {
DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str); DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
return -1; return -1;
} }
if (intval > UINT32_MAX) if (intval > UINT32_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }
@ -474,7 +476,11 @@ safe_hextou32(const char *str, uint32_t *val)
char *end; char *end;
unsigned long intval; unsigned long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_hextou32 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtoul(str, &end, 16); intval = strtoul(str, &end, 16);
@ -483,21 +489,18 @@ safe_hextou32(const char *str, uint32_t *val)
|| ((errno != 0) && (intval == 0))) || ((errno != 0) && (intval == 0)))
{ {
DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno)); DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
return -1; return -1;
} }
if (end == str) if (end == str)
{ {
DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str); DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
return -1; return -1;
} }
if (intval > UINT32_MAX) if (intval > UINT32_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }
@ -512,7 +515,11 @@ safe_atoi64(const char *str, int64_t *val)
char *end; char *end;
long long intval; long long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_atoi64 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtoll(str, &end, 10); intval = strtoll(str, &end, 10);
@ -521,21 +528,18 @@ safe_atoi64(const char *str, int64_t *val)
|| ((errno != 0) && (intval == 0))) || ((errno != 0) && (intval == 0)))
{ {
DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno)); DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
return -1; return -1;
} }
if (end == str) if (end == str)
{ {
DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str); DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
return -1; return -1;
} }
if (intval > INT64_MAX) if (intval > INT64_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }
@ -550,7 +554,11 @@ safe_atou64(const char *str, uint64_t *val)
char *end; char *end;
unsigned long long intval; unsigned long long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_atou64 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtoull(str, &end, 10); intval = strtoull(str, &end, 10);
@ -573,7 +581,6 @@ safe_atou64(const char *str, uint64_t *val)
if (intval > UINT64_MAX) if (intval > UINT64_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }
@ -588,7 +595,11 @@ safe_hextou64(const char *str, uint64_t *val)
char *end; char *end;
unsigned long long intval; unsigned long long intval;
*val = 0; if (str == NULL)
{
DPRINTF(E_SPAM, L_MISC, "Input to safe_hextou64 is NULL\n");
return -1;
}
errno = 0; errno = 0;
intval = strtoull(str, &end, 16); intval = strtoull(str, &end, 16);
@ -597,21 +608,18 @@ safe_hextou64(const char *str, uint64_t *val)
|| ((errno != 0) && (intval == 0))) || ((errno != 0) && (intval == 0)))
{ {
DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno)); DPRINTF(E_DBG, L_MISC, "Invalid integer in string (%s): %s\n", str, strerror(errno));
return -1; return -1;
} }
if (end == str) if (end == str)
{ {
DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str); DPRINTF(E_DBG, L_MISC, "No integer found in string (%s)\n", str);
return -1; return -1;
} }
if (intval > UINT64_MAX) if (intval > UINT64_MAX)
{ {
DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str); DPRINTF(E_DBG, L_MISC, "Integer value too large (%s)\n", str);
return -1; return -1;
} }