This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository libx2goclient. commit a31d40ee8c640215023c801a2b64ccf0ba4acb37 Author: Mihai Moldovan <ionic@ionic.de> Date: Sat Mar 28 09:24:29 2020 +0100 src/x2goclient-utils.{c,h}: add x2goclient_str_to_int (). Helper function that converts a string number to a long-long-type. --- src/x2goclient-utils.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ src/x2goclient-utils.h | 4 ++ 2 files changed, 122 insertions(+) diff --git a/src/x2goclient-utils.c b/src/x2goclient-utils.c index ccdd82c..39e448a 100644 --- a/src/x2goclient-utils.c +++ b/src/x2goclient-utils.c @@ -22,6 +22,9 @@ Boston, MA 02110-1301, USA. */ +#include <errno.h> +#include <stdlib.h> + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,3 +34,118 @@ void x2goclient_clear_strings (gpointer data) { g_free (data); } + +/** + * x2goclient_str_to_int: + * @str: (in) (not optional) (not nullable): input string + * @min: (in): true if a minimum limit should be checked for + * @limit_min: (in): the minimum limit to check for + * @max: (in): true if a maximum limit should be checked for + * @limit_max: (in) the maximum limit to check for + * @end: (out) (optional) (nullable): pointer to final string after the scanned + * value + * @conv_err: (out) (not optional) (not nullable): will be set to true on + * conversion errors + * @min_err: (out) (not optional) (not nullable): will be set to true if value + * falls short of minimum limit + * and on underflows + * @max_err: (out) (not optional) (not nullable): will be set to true if value + * exceeds maximum limit and on + * overflows + * + * Takes a string and converts it into a #long long integer. + * + * The error output parameters @conv_err, @min_err and @max_err MUST NOT be + * %NULL at any time. + * + * Multiple error conditions exist: + * - If the value pointed to by @conv_err is %TRUE and the values pointed to + * by @min_err and @max_err are both %FALSE, there was an error converting + * the initial string to a proper integer value. The return value will not + * contain a meaningful value. + * - If the values pointed to by @conv_err and @min_err are both %TRUE, an + * underflow occurred and the scanned input value was smaller than the + * minimum representable value by #long long. The return value will + * not contain a meaningful value. + * - If the values pointed to by @conv_err and @max_err are both %TRUE, an + * overflow occurred and the scanned input value was higher than the + * maximum representable value by #long long. The return value will + * not contain a meaningful value. + * - If the value pointed to by @conv_err is %FALSE and the value pointed to + * by @min_err is %TRUE, the value was converted successfully but was + * lower than the value passed via @limit_min and failed the minimum + * check. The return value will still contain the originally converted + * number. + * - If the value pointed to by @conv_err is %FALSE and the value pointed to + * by @max_err is %TRUE, the value was converted successfully but was + * higher than the value passed via @limit_max and failed the maximum + * check. The returned value will still contain the originally converted + * number. + * + * The values pointed to by @conv_err, @min_err and @max_err SHOULD never be + * all set to %TRUE by this function at the same time. Otherwise, that's a bug. + * + * If the value pointed to by @min is %FALSE, @limit_min will not be touched + * and has no meaning to the function. The same logic applies to @max and + * @limit_max. + * + * If the pointer passed as @end is not %NULL its value will be set to the + * first character after the parsed integer value like strtoll() does under + * the following circumstances: + * - If %conv_err is %FALSE. + * - If %conv_err is %TRUE and %min_err is %TRUE. + * - If %conv_err is %TRUE and %max_err is %TRUE. + * Otherwise, the pointer value will not be a meaningful one and you should not + * use or rely on it. + * + * Returns: the converted value as a #long long, unless an error occurred + */ +long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long limit_min, _Bool max, long long limit_max, const gchar **restrict end, _Bool *restrict conv_err, _Bool *restrict min_err, _Bool *restrict max_err) { + long long ret = 42; + + *min_err = *max_err = FALSE; + + if (end) { + *end = NULL; + } + + errno = 0; + int saved_errno = 0; + gchar *endptr = NULL; + ret = strtoll (str, &endptr, 10); + saved_errno = errno; + + if (0 != saved_errno) { + *conv_err = TRUE; + ret = 42; + + if (ERANGE == saved_errno) { + if (end) { + *end = endptr; + } + + if (LLONG_MIN == ret) { + *min_err = TRUE; + } + else if (LLONG_MAX == ret) { + *max_err = TRUE; + } + } + } + else { + *conv_err = FALSE; + + if (end) { + *end = endptr; + } + + if ((min) && (limit_min > ret)) { + *min_err = TRUE; + } + else if ((max) && (limit_max < ret)) { + *max_err = TRUE; + } + } + + return (ret); +} diff --git a/src/x2goclient-utils.h b/src/x2goclient-utils.h index 0959a32..1a100d2 100644 --- a/src/x2goclient-utils.h +++ b/src/x2goclient-utils.h @@ -25,12 +25,16 @@ #ifndef x2goclient_utils_h #define x2goclient_utils_h +#include <stdbool.h> + #include <gmodule.h> G_BEGIN_DECLS void x2goclient_clear_strings (gpointer data); +long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long limit_min, _Bool max, long long limit_max, const gchar **restrict end, _Bool *restrict conv_err, _Bool *restrict min_err, _Bool *restrict max_err); + G_END_DECLS #endif /* x2goclient_utils_h */ -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git