[gdk-pixbuf] io-ico: Fix option parsing to be locale-independent
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdk-pixbuf] io-ico: Fix option parsing to be locale-independent
- Date: Fri, 17 Feb 2017 11:41:31 +0000 (UTC)
commit 91723d7328b128d20626731f98b414c773a98ba1
Author: Philip Withnall <philip tecnocode co uk>
Date: Sat Jan 7 16:35:54 2017 +0000
io-ico: Fix option parsing to be locale-independent
sscanf() and strtol() are both locale-dependent. In addition, the return
value of sscanf() was not being checked (so it could fail without being
noticed), and there was no bounds checking being performed.
Bounds checking is now performed, although the bounds have been chosen
for conservative backwards-compatibility, and may not be the most
appropriate.
Coverity CID: 1388522
https://bugzilla.gnome.org/show_bug.cgi?id=776990
gdk-pixbuf/io-ico.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 54 insertions(+), 4 deletions(-)
---
diff --git a/gdk-pixbuf/io-ico.c b/gdk-pixbuf/io-ico.c
index 2b0441f..ddb804c 100644
--- a/gdk-pixbuf/io-ico.c
+++ b/gdk-pixbuf/io-ico.c
@@ -1240,6 +1240,47 @@ write_icon (FILE *f, GSList *entries)
}
}
+/* Locale-independent signed integer string parser, base 10.
+ * @minimum and @maximum are valid inclusively. */
+static gboolean
+ascii_strtoll (const gchar *str,
+ gint64 minimum,
+ gint64 maximum,
+ gint64 *out,
+ GError **error)
+{
+ gint64 retval;
+ const gchar *end_ptr;
+
+ errno = 0;
+ retval = g_ascii_strtoll (str, (gchar **) &end_ptr, 10);
+
+ if (errno != 0) {
+ g_set_error_literal (error,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ g_strerror (errno));
+ return FALSE;
+ } else if (end_ptr == str || *end_ptr != '\0') {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Argument is not an integer: %s", str);
+ return FALSE;
+ } else if ((maximum < G_MAXINT64 && retval > maximum) ||
+ (minimum > G_MININT64 && retval < minimum)) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Argument should be in range [%" G_GINT64_FORMAT
+ ", %" G_GINT64_FORMAT "]: %s",
+ minimum, maximum, str);
+ return FALSE;
+ }
+
+ g_assert (retval >= minimum && retval <= maximum);
+
+ if (out != NULL)
+ *out = retval;
+
+ return TRUE;
+}
+
static gboolean
gdk_pixbuf__ico_image_save (FILE *f,
GdkPixbuf *pixbuf,
@@ -1265,15 +1306,24 @@ gdk_pixbuf__ico_image_save (FILE *f,
gchar **viter;
for (kiter = keys, viter = values; *kiter && *viter; kiter++, viter++) {
- char *endptr;
+ gint64 out;
if (strcmp (*kiter, "depth") == 0) {
- sscanf (*viter, "%d", &icon->depth);
+ if (!ascii_strtoll (*viter, 1, 32,
+ &out, error))
+ return FALSE;
+ icon->depth = out;
}
else if (strcmp (*kiter, "x_hot") == 0) {
- hot_x = strtol (*viter, &endptr, 10);
+ if (!ascii_strtoll (*viter, G_MININT, G_MAXINT,
+ &out, error))
+ return FALSE;
+ hot_x = out;
}
else if (strcmp (*kiter, "y_hot") == 0) {
- hot_y = strtol (*viter, &endptr, 10);
+ if (!ascii_strtoll (*viter, G_MININT, G_MAXINT,
+ &out, error))
+ return FALSE;
+ hot_y = out;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]