utils: Copy g_ascii_string_to_unsigned from glib-2.54.0

This avoids the glib's version bump needed for the subsequent min-free-space-size
porting patches.

Closes: #1912
Approved by: alexlarsson
This commit is contained in:
Umang Jain
2018-08-02 17:25:33 +05:30
committed by Atomic Bot
parent 2d3f493f27
commit d34d117ae4
2 changed files with 93 additions and 0 deletions

View File

@@ -241,6 +241,14 @@ gboolean flatpak_remove_dangling_symlinks (GFile *dir,
GCancellable *cancellable,
GError **error);
gboolean flatpak_utils_ascii_string_to_unsigned (const gchar *str,
guint base,
guint64 min,
guint64 max,
guint64 *out_num,
GError **error);
#if !GLIB_CHECK_VERSION (2, 40, 0)
static inline gboolean
g_key_file_save_to_file (GKeyFile *key_file,

View File

@@ -5964,3 +5964,88 @@ flatpak_check_required_version (const char *ref,
return TRUE;
}
static gboolean
str_has_sign (const gchar *str)
{
return str[0] == '-' || str[0] == '+';
}
static gboolean
str_has_hex_prefix (const gchar *str)
{
return str[0] == '0' && g_ascii_tolower (str[1]) == 'x';
}
/* Copied from glib-2.54.0 to avoid the Glib's version bump.
* Function name in glib: g_ascii_string_to_unsigned
* If this is being dropped(migration to g_ascii_string_to_unsigned)
* make sure to remove str_has_hex_prefix and str_has_sign helpers too.
*/
gboolean
flatpak_utils_ascii_string_to_unsigned (const gchar *str,
guint base,
guint64 min,
guint64 max,
guint64 *out_num,
GError **error)
{
guint64 number;
const gchar *end_ptr = NULL;
gint saved_errno = 0;
g_return_val_if_fail (str != NULL, FALSE);
g_return_val_if_fail (base >= 2 && base <= 36, FALSE);
g_return_val_if_fail (min <= max, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (str[0] == '\0')
{
g_set_error_literal (error,
G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_INVALID,
_("Empty string is not a number"));
return FALSE;
}
errno = 0;
number = g_ascii_strtoull (str, (gchar **)&end_ptr, base);
saved_errno = errno;
if (/* We do not allow leading whitespace, but g_ascii_strtoull
* accepts it and just skips it, so we need to check for it
* ourselves.
*/
g_ascii_isspace (str[0]) ||
/* Unsigned number should have no sign.
*/
str_has_sign (str) ||
/* We don't support hexadecimal numbers prefixed with 0x or
* 0X.
*/
(base == 16 && str_has_hex_prefix (str)) ||
(saved_errno != 0 && saved_errno != ERANGE) ||
end_ptr == NULL ||
*end_ptr != '\0')
{
g_set_error (error,
G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_INVALID,
_("“%s” is not an unsigned number"), str);
return FALSE;
}
if (saved_errno == ERANGE || number < min || number > max)
{
gchar *min_str = g_strdup_printf ("%" G_GUINT64_FORMAT, min);
gchar *max_str = g_strdup_printf ("%" G_GUINT64_FORMAT, max);
g_set_error (error,
G_NUMBER_PARSER_ERROR, G_NUMBER_PARSER_ERROR_OUT_OF_BOUNDS,
_("Number “%s” is out of bounds [%s, %s]"),
str, min_str, max_str);
g_free (min_str);
g_free (max_str);
return FALSE;
}
if (out_num != NULL)
*out_num = number;
return TRUE;
}