mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-07 04:58:01 +02:00
all: merge branch 'th/strtoll-workaround'
https://bugzilla.redhat.com/show_bug.cgi?id=1797915 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/456 (cherry picked from commitd342fa267d) (cherry picked from commit85811e67dd) (cherry picked from commit32e0bd7e72)
This commit is contained in:
commit
307bc73fc7
5 changed files with 174 additions and 14 deletions
|
|
@ -2286,7 +2286,7 @@ _nm_utils_parse_tc_handle (const char *str, GError **error)
|
||||||
|
|
||||||
nm_assert (str);
|
nm_assert (str);
|
||||||
|
|
||||||
maj = g_ascii_strtoll (str, (char **) &sep, 0x10);
|
maj = nm_g_ascii_strtoll (str, (char **) &sep, 0x10);
|
||||||
if (sep == str)
|
if (sep == str)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
@ -2295,7 +2295,7 @@ _nm_utils_parse_tc_handle (const char *str, GError **error)
|
||||||
if (sep[0] == ':') {
|
if (sep[0] == ':') {
|
||||||
const char *str2 = &sep[1];
|
const char *str2 = &sep[1];
|
||||||
|
|
||||||
min = g_ascii_strtoll (str2, (char **) &sep, 0x10);
|
min = nm_g_ascii_strtoll (str2, (char **) &sep, 0x10);
|
||||||
sep = nm_str_skip_leading_spaces (sep);
|
sep = nm_str_skip_leading_spaces (sep);
|
||||||
if (sep[0] != '\0')
|
if (sep[0] != '\0')
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -714,6 +714,158 @@ nm_utils_parse_inaddr_prefix (int addr_family,
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_g_ascii_strtoll()
|
||||||
|
* @nptr: the string to parse
|
||||||
|
* @endptr: the pointer on the first invalid chars
|
||||||
|
* @base: the base.
|
||||||
|
*
|
||||||
|
* This wraps g_ascii_strtoll() and should in almost all cases behave identical
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* However, it seems there are situations where g_ascii_strtoll() might set
|
||||||
|
* errno to some unexpected value EAGAIN. Possibly this is related to creating
|
||||||
|
* the C locale during
|
||||||
|
*
|
||||||
|
* #ifdef USE_XLOCALE
|
||||||
|
* return strtoll_l (nptr, endptr, base, get_C_locale ());
|
||||||
|
*
|
||||||
|
* This wrapper tries to workaround that condition.
|
||||||
|
*/
|
||||||
|
gint64
|
||||||
|
nm_g_ascii_strtoll (const char *nptr,
|
||||||
|
char **endptr,
|
||||||
|
guint base)
|
||||||
|
{
|
||||||
|
int try_count = 2;
|
||||||
|
gint64 v;
|
||||||
|
const int errsv_orig = errno;
|
||||||
|
int errsv;
|
||||||
|
|
||||||
|
nm_assert (nptr);
|
||||||
|
nm_assert (base == 0u || (base >= 2u && base <= 36u));
|
||||||
|
|
||||||
|
again:
|
||||||
|
errno = 0;
|
||||||
|
v = g_ascii_strtoll (nptr, endptr, base);
|
||||||
|
errsv = errno;
|
||||||
|
|
||||||
|
if (errsv == 0) {
|
||||||
|
if (errsv_orig != 0)
|
||||||
|
errno = errsv_orig;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( errsv == ERANGE
|
||||||
|
&& NM_IN_SET (v, G_MININT64, G_MAXINT64))
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if ( errsv == EINVAL
|
||||||
|
&& v == 0
|
||||||
|
&& nptr
|
||||||
|
&& nptr[0] == '\0')
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if (try_count-- > 0)
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
#if NM_MORE_ASSERTS
|
||||||
|
g_critical ("g_ascii_strtoll() for \"%s\" failed with errno=%d (%s) and v=%"G_GINT64_FORMAT,
|
||||||
|
nptr,
|
||||||
|
errsv,
|
||||||
|
nm_strerror_native (errsv),
|
||||||
|
v);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See nm_g_ascii_strtoll() */
|
||||||
|
guint64
|
||||||
|
nm_g_ascii_strtoull (const char *nptr,
|
||||||
|
char **endptr,
|
||||||
|
guint base)
|
||||||
|
{
|
||||||
|
int try_count = 2;
|
||||||
|
guint64 v;
|
||||||
|
const int errsv_orig = errno;
|
||||||
|
int errsv;
|
||||||
|
|
||||||
|
nm_assert (nptr);
|
||||||
|
nm_assert (base == 0u || (base >= 2u && base <= 36u));
|
||||||
|
|
||||||
|
again:
|
||||||
|
errno = 0;
|
||||||
|
v = g_ascii_strtoull (nptr, endptr, base);
|
||||||
|
errsv = errno;
|
||||||
|
|
||||||
|
if (errsv == 0) {
|
||||||
|
if (errsv_orig != 0)
|
||||||
|
errno = errsv_orig;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( errsv == ERANGE
|
||||||
|
&& NM_IN_SET (v, G_MAXUINT64))
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if ( errsv == EINVAL
|
||||||
|
&& v == 0
|
||||||
|
&& nptr
|
||||||
|
&& nptr[0] == '\0')
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if (try_count-- > 0)
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
#if NM_MORE_ASSERTS
|
||||||
|
g_critical ("g_ascii_strtoull() for \"%s\" failed with errno=%d (%s) and v=%"G_GUINT64_FORMAT,
|
||||||
|
nptr,
|
||||||
|
errsv,
|
||||||
|
nm_strerror_native (errsv),
|
||||||
|
v);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see nm_g_ascii_strtoll(). */
|
||||||
|
double
|
||||||
|
nm_g_ascii_strtod (const char *nptr,
|
||||||
|
char **endptr)
|
||||||
|
{
|
||||||
|
int try_count = 2;
|
||||||
|
double v;
|
||||||
|
int errsv;
|
||||||
|
|
||||||
|
nm_assert (nptr);
|
||||||
|
|
||||||
|
again:
|
||||||
|
v = g_ascii_strtod (nptr, endptr);
|
||||||
|
errsv = errno;
|
||||||
|
|
||||||
|
if (errsv == 0)
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if (errsv == ERANGE)
|
||||||
|
return v;
|
||||||
|
|
||||||
|
if (try_count-- > 0)
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
#if NM_MORE_ASSERTS
|
||||||
|
g_critical ("g_ascii_strtod() for \"%s\" failed with errno=%d (%s) and v=%f",
|
||||||
|
nptr,
|
||||||
|
errsv,
|
||||||
|
nm_strerror_native (errsv),
|
||||||
|
v);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Not really much else to do. Return the parsed value and leave errno set
|
||||||
|
* to the unexpected value. */
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/* _nm_utils_ascii_str_to_int64:
|
/* _nm_utils_ascii_str_to_int64:
|
||||||
*
|
*
|
||||||
* A wrapper for g_ascii_strtoll, that checks whether the whole string
|
* A wrapper for g_ascii_strtoll, that checks whether the whole string
|
||||||
|
|
@ -741,7 +893,7 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
v = g_ascii_strtoll (str, (char **) &s, base);
|
v = nm_g_ascii_strtoll (str, (char **) &s, base);
|
||||||
|
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return fallback;
|
return fallback;
|
||||||
|
|
@ -777,7 +929,7 @@ _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
v = g_ascii_strtoull (str, (char **) &s, base);
|
v = nm_g_ascii_strtoull (str, (char **) &s, base);
|
||||||
|
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return fallback;
|
return fallback;
|
||||||
|
|
@ -796,8 +948,8 @@ _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64
|
||||||
|
|
||||||
if ( v != 0
|
if ( v != 0
|
||||||
&& str[0] == '-') {
|
&& str[0] == '-') {
|
||||||
/* I don't know why, but g_ascii_strtoull() accepts minus signs ("-2" gives 18446744073709551614).
|
/* As documented, g_ascii_strtoull() accepts negative values, and returns their
|
||||||
* For "-0" that is OK, but otherwise not. */
|
* absolute value. We don't. */
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -539,6 +539,17 @@ gboolean nm_utils_parse_inaddr_prefix (int addr_family,
|
||||||
char **out_addr,
|
char **out_addr,
|
||||||
int *out_prefix);
|
int *out_prefix);
|
||||||
|
|
||||||
|
gint64 nm_g_ascii_strtoll (const char *nptr,
|
||||||
|
char **endptr,
|
||||||
|
guint base);
|
||||||
|
|
||||||
|
guint64 nm_g_ascii_strtoull (const char *nptr,
|
||||||
|
char **endptr,
|
||||||
|
guint base);
|
||||||
|
|
||||||
|
double nm_g_ascii_strtod (const char *nptr,
|
||||||
|
char **endptr);
|
||||||
|
|
||||||
gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
|
gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
|
||||||
guint64 _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64 max, guint64 fallback);
|
guint64 _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64 max, guint64 fallback);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -680,7 +680,7 @@ convert_uuids_to_capabilities (const char **strings)
|
||||||
|
|
||||||
parts = g_strsplit (*iter, "-", -1);
|
parts = g_strsplit (*iter, "-", -1);
|
||||||
if (parts && parts[0]) {
|
if (parts && parts[0]) {
|
||||||
switch (g_ascii_strtoull (parts[0], NULL, 16)) {
|
switch (_nm_utils_ascii_str_to_int64 (parts[0], 16, 0, G_MAXINT, -1)) {
|
||||||
case 0x1103:
|
case 0x1103:
|
||||||
capabilities |= NM_BT_CAPABILITY_DUN;
|
capabilities |= NM_BT_CAPABILITY_DUN;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -582,9 +582,8 @@ update_ip6_setting_from_if_block (NMConnection *connection,
|
||||||
const char *nameserver_v;
|
const char *nameserver_v;
|
||||||
const char *nameservers_v;
|
const char *nameservers_v;
|
||||||
const char *search_v;
|
const char *search_v;
|
||||||
int prefix_int = 128;
|
guint prefix_int;
|
||||||
|
|
||||||
/* Address */
|
|
||||||
address_v = ifparser_getkey (block, "address");
|
address_v = ifparser_getkey (block, "address");
|
||||||
if (!address_v) {
|
if (!address_v) {
|
||||||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
||||||
|
|
@ -592,12 +591,12 @@ update_ip6_setting_from_if_block (NMConnection *connection,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prefix */
|
|
||||||
prefix_v = ifparser_getkey (block, "netmask");
|
prefix_v = ifparser_getkey (block, "netmask");
|
||||||
if (prefix_v)
|
if (prefix_v)
|
||||||
prefix_int = g_ascii_strtoll (prefix_v, NULL, 10);
|
prefix_int = _nm_utils_ascii_str_to_int64 (prefix_v, 10, 0, 128, G_MAXINT);
|
||||||
|
else
|
||||||
|
prefix_int = 128;
|
||||||
|
|
||||||
/* Add the new address to the setting */
|
|
||||||
addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error);
|
addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -610,7 +609,6 @@ update_ip6_setting_from_if_block (NMConnection *connection,
|
||||||
}
|
}
|
||||||
nm_ip_address_unref (addr);
|
nm_ip_address_unref (addr);
|
||||||
|
|
||||||
/* gateway */
|
|
||||||
gateway_v = ifparser_getkey (block, "gateway");
|
gateway_v = ifparser_getkey (block, "gateway");
|
||||||
if (gateway_v) {
|
if (gateway_v) {
|
||||||
if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) {
|
if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) {
|
||||||
|
|
@ -631,7 +629,6 @@ update_ip6_setting_from_if_block (NMConnection *connection,
|
||||||
if (!nm_setting_ip_config_get_num_dns (s_ip6))
|
if (!nm_setting_ip_config_get_num_dns (s_ip6))
|
||||||
_LOGI ("No dns-nameserver configured in /etc/network/interfaces");
|
_LOGI ("No dns-nameserver configured in /etc/network/interfaces");
|
||||||
|
|
||||||
/* DNS searches */
|
|
||||||
search_v = ifparser_getkey (block, "dns-search");
|
search_v = ifparser_getkey (block, "dns-search");
|
||||||
if (search_v) {
|
if (search_v) {
|
||||||
gs_free const char **list = NULL;
|
gs_free const char **list = NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue