diff --git a/app/core/gimpbrush-header.h b/app/core/gimpbrush-header.h index d5e23d09d1..9935110c29 100644 --- a/app/core/gimpbrush-header.h +++ b/app/core/gimpbrush-header.h @@ -18,16 +18,21 @@ #ifndef __GIMP_BRUSH_HEADER_H__ #define __GIMP_BRUSH_HEADER_H__ -#define GBRUSH_FILE_VERSION 2 -#define GBRUSH_MAGIC (('G' << 24) + ('I' << 16) + ('M' << 8) + ('P' << 0)) + +#define GIMP_BRUSH_FILE_VERSION 2 +#define GIMP_BRUSH_MAGIC (('G' << 24) + ('I' << 16) + \ + ('M' << 8) + ('P' << 0)) +#define GIMP_BRUSH_MAX_SIZE 10000 /* Max size in either dimension in px */ +#define GIMP_BRUSH_MAX_NAME 256 /* Max length of the brush's name */ + /* All field entries are MSB */ -typedef struct _BrushHeader BrushHeader; +typedef struct _GimpBrushHeader GimpBrushHeader; -struct _BrushHeader +struct _GimpBrushHeader { - guint32 header_size; /* header_size = sizeof (BrushHeader) + brush name */ + guint32 header_size; /* = sizeof (GimpBrushHeader) + brush name */ guint32 version; /* brush file version # */ guint32 width; /* width of brush */ guint32 height; /* height of brush */ @@ -40,4 +45,5 @@ struct _BrushHeader * comes the brush data--width * height * bytes bytes of it... */ + #endif /* __GIMP_BRUSH_HEADER_H__ */ diff --git a/app/core/gimpbrush-load.c b/app/core/gimpbrush-load.c index f0cd6df092..60368181f0 100644 --- a/app/core/gimpbrush-load.c +++ b/app/core/gimpbrush-load.c @@ -134,15 +134,15 @@ gimp_brush_load_brush (GimpContext *context, GInputStream *input, GError **error) { - GimpBrush *brush; - gsize bn_size; - BrushHeader header; - gchar *name = NULL; - guchar *pixmap; - guchar *mask; - gsize bytes_read; - gssize i, size; - gboolean success = TRUE; + GimpBrush *brush; + gsize bn_size; + GimpBrushHeader header; + gchar *name = NULL; + guchar *pixmap; + guchar *mask; + gsize bytes_read; + gssize i, size; + gboolean success = TRUE; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); @@ -188,7 +188,7 @@ gimp_brush_load_brush (GimpContext *context, return NULL; } - if (header.width > GIMP_BRUSH_MAX_SIZE || + if (header.width > GIMP_BRUSH_MAX_SIZE || header.height > GIMP_BRUSH_MAX_SIZE) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, @@ -225,7 +225,7 @@ gimp_brush_load_brush (GimpContext *context, /* fallthrough */ case 2: - if (header.magic_number == GBRUSH_MAGIC) + if (header.magic_number == GIMP_BRUSH_MAGIC) break; default: @@ -235,7 +235,7 @@ gimp_brush_load_brush (GimpContext *context, return NULL; } - if (header.header_size < sizeof (BrushHeader)) + if (header.header_size < sizeof (GimpBrushHeader)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Unsupported brush format")); @@ -247,7 +247,17 @@ gimp_brush_load_brush (GimpContext *context, { gchar *utf8; - name = g_new (gchar, bn_size); + if (bn_size > GIMP_BRUSH_MAX_NAME) + { + g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, + _("Invalid header data in '%s': " + "Brush name is too long: %lu"), + gimp_file_get_utf8_name (file), + (gulong) bn_size); + return NULL; + } + + name = g_new0 (gchar, bn_size + 1); if (! g_input_stream_read_all (input, name, bn_size, &bytes_read, NULL, error) || @@ -264,7 +274,7 @@ gimp_brush_load_brush (GimpContext *context, name = utf8; } - if (!name) + if (! name) name = g_strdup (_("Unnamed")); brush = g_object_new (GIMP_TYPE_BRUSH, diff --git a/app/core/gimpbrush.h b/app/core/gimpbrush.h index aaa0c32255..c82c10e921 100644 --- a/app/core/gimpbrush.h +++ b/app/core/gimpbrush.h @@ -21,7 +21,6 @@ #include "gimpdata.h" -#define GIMP_BRUSH_MAX_SIZE 10000.0 /*Max size in either dimension in px*/ #define GIMP_TYPE_BRUSH (gimp_brush_get_type ()) #define GIMP_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH, GimpBrush)) diff --git a/app/core/gimppattern-header.h b/app/core/gimppattern-header.h index 2d8fbdc039..37dbc983b3 100644 --- a/app/core/gimppattern-header.h +++ b/app/core/gimppattern-header.h @@ -18,16 +18,21 @@ #ifndef __GIMP_PATTERN_HEADER_H__ #define __GIMP_PATTERN_HEADER_H__ -#define GPATTERN_FILE_VERSION 1 -#define GPATTERN_MAGIC (('G' << 24) + ('P' << 16) + ('A' << 8) + ('T' << 0)) + +#define GIMP_PATTERN_FILE_VERSION 1 +#define GIMP_PATTERN_MAGIC (('G' << 24) + ('P' << 16) + \ + ('A' << 8) + ('T' << 0)) +#define GIMP_PATTERN_MAX_SIZE 10000 /* Max size in either dimension in px */ +#define GIMP_PATTERN_MAX_NAME 256 /* Max length of the pattern's name */ + /* All field entries are MSB */ -typedef struct _PatternHeader PatternHeader; +typedef struct _GimpPatternHeader GimpPatternHeader; -struct _PatternHeader +struct _GimpPatternHeader { - guint32 header_size; /* header_size = sizeof(PatternHeader) + pattern name */ + guint32 header_size; /* = sizeof (GimpPatternHeader) + pattern name */ guint32 version; /* pattern file version # */ guint32 width; /* width of pattern */ guint32 height; /* height of pattern */ @@ -39,4 +44,5 @@ struct _PatternHeader * comes the pattern data--width * height * bytes bytes of it... */ + #endif /* __GIMP_PATTERN_HEADER_H__ */ diff --git a/app/core/gimppattern-load.c b/app/core/gimppattern-load.c index e8ca58f949..85729bf17a 100644 --- a/app/core/gimppattern-load.c +++ b/app/core/gimppattern-load.c @@ -40,13 +40,13 @@ gimp_pattern_load (GimpContext *context, GInputStream *input, GError **error) { - GimpPattern *pattern = NULL; - const Babl *format = NULL; - PatternHeader header; - gsize size; - gsize bytes_read; - gint bn_size; - gchar *name = NULL; + GimpPattern *pattern = NULL; + const Babl *format = NULL; + GimpPatternHeader header; + gsize size; + gsize bytes_read; + gsize bn_size; + gchar *name = NULL; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); @@ -70,8 +70,9 @@ gimp_pattern_load (GimpContext *context, header.magic_number = g_ntohl (header.magic_number); /* Check for correct file format */ - if (header.magic_number != GPATTERN_MAGIC || header.version != 1 || - header.header_size <= sizeof (header)) + if (header.magic_number != GIMP_PATTERN_MAGIC || + header.version != 1 || + header.header_size <= sizeof (header)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Unknown pattern format version %d."), @@ -90,16 +91,16 @@ gimp_pattern_load (GimpContext *context, } /* Validate dimensions */ - if ((header.width == 0) || (header.width > GIMP_MAX_IMAGE_SIZE) || - (header.height == 0) || (header.height > GIMP_MAX_IMAGE_SIZE) || + if ((header.width == 0) || (header.width > GIMP_PATTERN_MAX_SIZE) || + (header.height == 0) || (header.height > GIMP_PATTERN_MAX_SIZE) || (G_MAXSIZE / header.width / header.height / header.bytes < 1)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Invalid header data in '%s': width=%lu, height=%lu, " "bytes=%lu"), gimp_file_get_utf8_name (file), - (unsigned long int)header.width, - (unsigned long int)header.height, - (unsigned long int)header.bytes); + (gulong) header.width, + (gulong) header.height, + (gulong) header.bytes); goto error; } @@ -108,7 +109,17 @@ gimp_pattern_load (GimpContext *context, { gchar *utf8; - name = g_new (gchar, bn_size); + if (bn_size > GIMP_PATTERN_MAX_NAME) + { + g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, + _("Invalid header data in '%s': " + "Pattern name is too long: %lu"), + gimp_file_get_utf8_name (file), + (gulong) bn_size); + goto error; + } + + name = g_new0 (gchar, bn_size + 1); if (! g_input_stream_read_all (input, name, bn_size, &bytes_read, NULL, error) || diff --git a/app/paint/gimpbrushcore.c b/app/paint/gimpbrushcore.c index f16f0f8d45..15dfa19434 100644 --- a/app/paint/gimpbrushcore.c +++ b/app/paint/gimpbrushcore.c @@ -30,7 +30,7 @@ #include "gegl/gimp-babl.h" -#include "core/gimpbrush.h" +#include "core/gimpbrush-header.h" #include "core/gimpbrushgenerated.h" #include "core/gimpdrawable.h" #include "core/gimpdynamics.h" diff --git a/app/paint/gimppaintoptions.c b/app/paint/gimppaintoptions.c index b56b13b47e..7653af022f 100644 --- a/app/paint/gimppaintoptions.c +++ b/app/paint/gimppaintoptions.c @@ -27,6 +27,7 @@ #include "paint-types.h" #include "core/gimp.h" +#include "core/gimpbrush-header.h" #include "core/gimpbrushgenerated.h" #include "core/gimpimage.h" #include "core/gimpdynamics.h" diff --git a/app/paint/gimpsmudge.c b/app/paint/gimpsmudge.c index b8e108e4b3..1b3d125cd1 100644 --- a/app/paint/gimpsmudge.c +++ b/app/paint/gimpsmudge.c @@ -29,6 +29,7 @@ #include "core/gimp-palettes.h" #include "core/gimpbrush.h" +#include "core/gimpbrush-header.h" #include "core/gimpdrawable.h" #include "core/gimpdynamics.h" #include "core/gimpimage.h" diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c index 92fbcfcc48..67473a4145 100644 --- a/plug-ins/common/file-gbr.c +++ b/plug-ins/common/file-gbr.c @@ -348,7 +348,7 @@ load_image (GFile *file, { GInputStream *input; gchar *name; - BrushHeader bh; + GimpBrushHeader bh; guchar *brush_buf = NULL; gint32 image_ID; gint32 layer_ID; @@ -368,7 +368,7 @@ load_image (GFile *file, if (! input) return -1; - size = G_STRUCT_OFFSET (BrushHeader, magic_number); + size = G_STRUCT_OFFSET (GimpBrushHeader, magic_number); if (! g_input_stream_read_all (input, &bh, size, &bytes_read, NULL, error) || @@ -386,8 +386,8 @@ load_image (GFile *file, bh.bytes = g_ntohl (bh.bytes); /* Sanitize values */ - if ((bh.width == 0) || (bh.width > GIMP_MAX_IMAGE_SIZE) || - (bh.height == 0) || (bh.height > GIMP_MAX_IMAGE_SIZE) || + if ((bh.width == 0) || (bh.width > GIMP_BRUSH_MAX_SIZE) || + (bh.height == 0) || (bh.height > GIMP_BRUSH_MAX_SIZE) || ((bh.bytes != 1) && (bh.bytes != 2) && (bh.bytes != 4) && (bh.bytes != 18)) || (G_MAXSIZE / bh.width / bh.height / MAX (4, bh.bytes) < 1)) @@ -395,8 +395,9 @@ load_image (GFile *file, g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Invalid header data in '%s': width=%lu, height=%lu, " "bytes=%lu"), g_file_get_parse_name (file), - (unsigned long int)bh.width, (unsigned long int)bh.height, - (unsigned long int)bh.bytes); + (gulong) bh.width, + (gulong) bh.height, + (gulong) bh.bytes); return -1; } @@ -406,7 +407,7 @@ load_image (GFile *file, /* Version 1 didn't have a magic number and had no spacing */ bh.spacing = 25; bh.header_size += 8; - if (bh.header_size < sizeof (BrushHeader)) + if (bh.header_size < sizeof (GimpBrushHeader)) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unsupported brush format")); @@ -421,7 +422,7 @@ load_image (GFile *file, if (! g_input_stream_read_all (input, (guchar *) &bh + - G_STRUCT_OFFSET (BrushHeader, + G_STRUCT_OFFSET (GimpBrushHeader, magic_number), size, &bytes_read, NULL, error) || bytes_read != size) @@ -447,8 +448,8 @@ load_image (GFile *file, } } - if (bh.magic_number == GBRUSH_MAGIC && - bh.header_size > sizeof (BrushHeader)) + if (bh.magic_number == GIMP_BRUSH_MAGIC && + bh.header_size > sizeof (GimpBrushHeader)) break; default: @@ -457,9 +458,21 @@ load_image (GFile *file, return -1; } - if ((size = (bh.header_size - sizeof (BrushHeader))) > 0) + if ((size = (bh.header_size - sizeof (GimpBrushHeader))) > 0) { - gchar *temp = g_new (gchar, size); + gchar *temp; + + if (size > GIMP_BRUSH_MAX_NAME) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + _("Invalid header data in '%s': " + "Brush name is too long: %lu"), + gimp_file_get_utf8_name (file), + (gulong) size); + return -1; + } + + temp = g_new0 (gchar, size + 1); if (! g_input_stream_read_all (input, temp, size, &bytes_read, NULL, error) || @@ -502,15 +515,15 @@ load_image (GFile *file, { case 1: { - PatternHeader ph; + GimpPatternHeader ph; /* For backwards-compatibility, check if a pattern follows. * The obsolete .gpb format did it this way. */ - if (g_input_stream_read_all (input, &ph, sizeof (PatternHeader), + if (g_input_stream_read_all (input, &ph, sizeof (GimpPatternHeader), &bytes_read, NULL, NULL) && - bytes_read == sizeof (PatternHeader)) + bytes_read == sizeof (GimpPatternHeader)) { /* rearrange the bytes in each unsigned int */ ph.header_size = g_ntohl (ph.header_size); @@ -520,16 +533,16 @@ load_image (GFile *file, ph.bytes = g_ntohl (ph.bytes); ph.magic_number = g_ntohl (ph.magic_number); - if (ph.magic_number == GPATTERN_MAGIC && - ph.version == 1 && - ph.header_size > sizeof (PatternHeader) && - ph.bytes == 3 && - ph.width == bh.width && - ph.height == bh.height && + if (ph.magic_number == GIMP_PATTERN_MAGIC && + ph.version == 1 && + ph.header_size > sizeof (GimpPatternHeader) && + ph.bytes == 3 && + ph.width == bh.width && + ph.height == bh.height && g_input_stream_skip (input, - ph.header_size - sizeof (PatternHeader), + ph.header_size - sizeof (GimpPatternHeader), NULL, NULL) == - ph.header_size - sizeof (PatternHeader)) + ph.header_size - sizeof (GimpPatternHeader)) { guchar *plain_brush = brush_buf; gint i; @@ -660,18 +673,18 @@ save_image (GFile *file, gint32 drawable_ID, GError **error) { - GOutputStream *output; - BrushHeader bh; - guchar *brush_buf; - GeglBuffer *buffer; - const Babl *format; - gint line; - gint x; - gint bpp; - gint file_bpp; - gint width; - gint height; - GimpRGB gray, white; + GOutputStream *output; + GimpBrushHeader bh; + guchar *brush_buf; + GeglBuffer *buffer; + const Babl *format; + gint line; + gint x; + gint bpp; + gint file_bpp; + gint width; + gint height; + GimpRGB gray, white; gimp_rgba_set_uchar (&white, 255, 255, 255, 255); @@ -709,16 +722,16 @@ save_image (GFile *file, width = gimp_drawable_width (drawable_ID); height = gimp_drawable_height (drawable_ID); - bh.header_size = g_htonl (sizeof (BrushHeader) + + bh.header_size = g_htonl (sizeof (GimpBrushHeader) + strlen (info.description) + 1); bh.version = g_htonl (2); bh.width = g_htonl (width); bh.height = g_htonl (height); bh.bytes = g_htonl (file_bpp); - bh.magic_number = g_htonl (GBRUSH_MAGIC); + bh.magic_number = g_htonl (GIMP_BRUSH_MAGIC); bh.spacing = g_htonl (info.spacing); - if (! g_output_stream_write_all (output, &bh, sizeof (BrushHeader), + if (! g_output_stream_write_all (output, &bh, sizeof (GimpBrushHeader), NULL, NULL, error)) { g_object_unref (output); diff --git a/plug-ins/common/file-gih.c b/plug-ins/common/file-gih.c index ff6b1c5f7f..e2b65177a1 100644 --- a/plug-ins/common/file-gih.c +++ b/plug-ins/common/file-gih.c @@ -452,15 +452,15 @@ gih_load_one_brush (GInputStream *input, gint32 image_ID, GError **error) { - gchar *name = NULL; - BrushHeader bh; - guchar *brush_buf = NULL; - gint32 layer_ID; - gsize size; - GimpImageType image_type; - gint width, height; - gint new_width, new_height; - gsize bytes_read; + gchar *name = NULL; + GimpBrushHeader bh; + guchar *brush_buf = NULL; + gint32 layer_ID; + gsize size; + GimpImageType image_type; + gint width, height; + gint new_width, new_height; + gsize bytes_read; if (! g_input_stream_read_all (input, &bh, sizeof (bh), &bytes_read, NULL, error) || @@ -479,15 +479,16 @@ gih_load_one_brush (GInputStream *input, bh.spacing = g_ntohl (bh.spacing); /* Sanitize values */ - if ((bh.width == 0) || (bh.width > GIMP_MAX_IMAGE_SIZE) || - (bh.height == 0) || (bh.height > GIMP_MAX_IMAGE_SIZE) || + if ((bh.width == 0) || (bh.width > GIMP_BRUSH_MAX_SIZE) || + (bh.height == 0) || (bh.height > GIMP_BRUSH_MAX_SIZE) || ((bh.bytes != 1) && (bh.bytes != 4)) || (G_MAXSIZE / bh.width / bh.height / bh.bytes < 1)) { return FALSE; } - if ((bh.magic_number != GBRUSH_MAGIC || bh.version != 2) || + if ((bh.magic_number != GIMP_BRUSH_MAGIC || + bh.version != 2) || bh.header_size <= sizeof (bh)) { return FALSE; @@ -495,6 +496,14 @@ gih_load_one_brush (GInputStream *input, if ((size = (bh.header_size - sizeof (bh))) > 0) { + if (size > GIMP_BRUSH_MAX_NAME) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + _("Brush name is too long: %lu"), + (gulong) size); + return FALSE; + } + name = g_new0 (gchar, size + 1); if (! g_input_stream_read_all (input, name, size, @@ -526,15 +535,15 @@ gih_load_one_brush (GInputStream *input, if (bh.bytes == 1) { - PatternHeader ph; + GimpPatternHeader ph; /* For backwards-compatibility, check if a pattern follows. * The obsolete .gpb format did it this way. */ - if (g_input_stream_read_all (input, &ph, sizeof (PatternHeader), + if (g_input_stream_read_all (input, &ph, sizeof (GimpPatternHeader), &bytes_read, NULL, error) && - bytes_read == sizeof (PatternHeader)) + bytes_read == sizeof (GimpPatternHeader)) { /* rearrange the bytes in each unsigned int */ ph.header_size = g_ntohl (ph.header_size); @@ -544,16 +553,16 @@ gih_load_one_brush (GInputStream *input, ph.bytes = g_ntohl (ph.bytes); ph.magic_number = g_ntohl (ph.magic_number); - if (ph.magic_number == GPATTERN_MAGIC && - ph.version == 1 && - ph.header_size > sizeof (PatternHeader) && - ph.bytes == 3 && - ph.width == bh.width && - ph.height == bh.height && + if (ph.magic_number == GIMP_PATTERN_MAGIC && + ph.version == 1 && + ph.header_size > sizeof (GimpPatternHeader) && + ph.bytes == 3 && + ph.width == bh.width && + ph.height == bh.height && g_input_stream_skip (input, - ph.header_size - sizeof (PatternHeader), + ph.header_size - sizeof (GimpPatternHeader), NULL, NULL) == - ph.header_size - sizeof (PatternHeader)) + ph.header_size - sizeof (GimpPatternHeader)) { guchar *plain_brush = brush_buf; gint i; @@ -580,7 +589,7 @@ gih_load_one_brush (GInputStream *input, g_free (plain_brush); } else if (! g_seekable_seek (G_SEEKABLE (input), - - sizeof (PatternHeader), G_SEEK_CUR, + - sizeof (GimpPatternHeader), G_SEEK_CUR, NULL, NULL)) { g_message (_("GIMP brush file appears to be corrupted.")); @@ -703,7 +712,7 @@ gih_load_image (GFile *file, g_string_free (buffer, FALSE); - if (!name) + if (! name) { g_message ("Couldn't read name for brush pipe from '%s'", g_file_get_parse_name (file)); @@ -1193,13 +1202,13 @@ gih_save_one_brush (GOutputStream *output, const gchar *name, GError **error) { - GeglBuffer *buffer; - const Babl *format; - BrushHeader bh; - guchar *data; - GimpImageType drawable_type; - gint bpp; - gint y; + GeglBuffer *buffer; + const Babl *format; + GimpBrushHeader bh; + guchar *data; + GimpImageType drawable_type; + gint bpp; + gint y; buffer = gimp_drawable_get_buffer (drawable_ID); @@ -1232,7 +1241,7 @@ gih_save_one_brush (GOutputStream *output, bh.width = g_htonl (rect->width); bh.height = g_htonl (rect->height); bh.bytes = g_htonl (bpp); - bh.magic_number = g_htonl (GBRUSH_MAGIC); + bh.magic_number = g_htonl (GIMP_BRUSH_MAGIC); bh.spacing = g_htonl (info.spacing); if (! g_output_stream_write_all (output, &bh, sizeof (bh), diff --git a/plug-ins/common/file-pat.c b/plug-ins/common/file-pat.c index 8e70a32477..74eb8a47ad 100644 --- a/plug-ins/common/file-pat.c +++ b/plug-ins/common/file-pat.c @@ -318,20 +318,21 @@ static gint32 load_image (GFile *file, GError **error) { - GInputStream *input; - PatternHeader ph; - gchar *name; - gchar *temp; - guchar *buf; - gint32 image_ID; - gint32 layer_ID; - GimpParasite *parasite; - GeglBuffer *buffer; - const Babl *file_format; - gint line; - GimpImageBaseType base_type; - GimpImageType image_type; - gsize bytes_read; + GInputStream *input; + GimpPatternHeader ph; + gchar *name; + gchar *temp; + guchar *buf; + gint32 image_ID; + gint32 layer_ID; + GimpParasite *parasite; + GeglBuffer *buffer; + const Babl *file_format; + gint line; + GimpImageBaseType base_type; + GimpImageType image_type; + gsize bytes_read; + gsize size; gimp_progress_init_printf (_("Opening '%s'"), g_file_get_parse_name (file)); @@ -340,9 +341,9 @@ load_image (GFile *file, if (! input) return -1; - if (! g_input_stream_read_all (input, &ph, sizeof (PatternHeader), + if (! g_input_stream_read_all (input, &ph, sizeof (GimpPatternHeader), &bytes_read, NULL, error) || - bytes_read != sizeof (PatternHeader)) + bytes_read != sizeof (GimpPatternHeader)) { g_object_unref (input); return -1; @@ -356,30 +357,45 @@ load_image (GFile *file, ph.bytes = g_ntohl (ph.bytes); ph.magic_number = g_ntohl (ph.magic_number); - if (ph.magic_number != GPATTERN_MAGIC || - ph.version != 1 || - ph.header_size <= sizeof (PatternHeader)) + if (ph.magic_number != GIMP_PATTERN_MAGIC || + ph.version != 1 || + ph.header_size <= sizeof (GimpPatternHeader)) { g_object_unref (input); return -1; } - temp = g_new (gchar, ph.header_size - sizeof (PatternHeader)); - - if (! g_input_stream_read_all (input, - temp, ph.header_size - sizeof (PatternHeader), - &bytes_read, NULL, error) || - bytes_read != ph.header_size - sizeof (PatternHeader)) + if ((size = (ph.header_size - sizeof (GimpPatternHeader))) > 0) { + if (size > GIMP_PATTERN_MAX_NAME) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + _("Invalid header data in '%s': " + "Pattern name is too long: %lu"), + gimp_file_get_utf8_name (file), + (gulong) size); + return -1; + } + + temp = g_new0 (gchar, size + 1); + + if (! g_input_stream_read_all (input, temp, size, + &bytes_read, NULL, error) || + bytes_read != size) + { + g_free (temp); + g_object_unref (input); + return -1; + } + + name = gimp_any_to_utf8 (temp, size - 1, + _("Invalid UTF-8 string in pattern file '%s'."), + g_file_get_parse_name (file)); g_free (temp); - g_object_unref (input); - return -1; } - name = gimp_any_to_utf8 (temp, ph.header_size - sizeof (PatternHeader) - 1, - _("Invalid UTF-8 string in pattern file '%s'."), - g_file_get_parse_name (file)); - g_free (temp); + if (! name) + name = g_strdup (_("Unnamed")); /* Now there's just raw data left. */ @@ -417,15 +433,16 @@ load_image (GFile *file, } /* Sanitize input dimensions and guard against overflows. */ - if ((ph.width == 0) || (ph.width > GIMP_MAX_IMAGE_SIZE) || - (ph.height == 0) || (ph.height > GIMP_MAX_IMAGE_SIZE) || + if ((ph.width == 0) || (ph.width > GIMP_PATTERN_MAX_SIZE) || + (ph.height == 0) || (ph.height > GIMP_PATTERN_MAX_SIZE) || (G_MAXSIZE / ph.width / ph.bytes < 1)) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Invalid header data in '%s': width=%lu, height=%lu, " "bytes=%lu"), g_file_get_parse_name (file), - (unsigned long int)ph.width, (unsigned long int)ph.height, - (unsigned long int)ph.bytes); + (gulong) ph.width, + (gulong) ph.height, + (gulong) ph.bytes); g_object_unref (input); return -1; } @@ -449,7 +466,7 @@ load_image (GFile *file, buffer = gimp_drawable_get_buffer (layer_ID); - /* this can't overflow because ph.width is <= GIMP_MAX_IMAGE_SIZE */ + /* this can't overflow because ph.width is <= GIMP_PATTERN_MAX_SIZE */ buf = g_malloc (ph.width * ph.bytes); for (line = 0; line < ph.height; line++) @@ -495,15 +512,15 @@ save_image (GFile *file, gint32 drawable_ID, GError **error) { - GOutputStream *output; - PatternHeader ph; - GeglBuffer *buffer; - const Babl *file_format; - guchar *buf; - gint width; - gint height; - gint line_size; - gint line; + GOutputStream *output; + GimpPatternHeader ph; + GeglBuffer *buffer; + const Babl *file_format; + guchar *buf; + gint width; + gint height; + gint line_size; + gint line; switch (gimp_drawable_type (drawable_ID)) { @@ -546,14 +563,14 @@ save_image (GFile *file, width = gegl_buffer_get_width (buffer); height = gegl_buffer_get_height (buffer); - ph.header_size = g_htonl (sizeof (PatternHeader) + strlen (description) + 1); + ph.header_size = g_htonl (sizeof (GimpPatternHeader) + strlen (description) + 1); ph.version = g_htonl (1); ph.width = g_htonl (width); ph.height = g_htonl (height); ph.bytes = g_htonl (babl_format_get_bytes_per_pixel (file_format)); - ph.magic_number = g_htonl (GPATTERN_MAGIC); + ph.magic_number = g_htonl (GIMP_PATTERN_MAGIC); - if (! g_output_stream_write_all (output, &ph, sizeof (PatternHeader), + if (! g_output_stream_write_all (output, &ph, sizeof (GimpPatternHeader), NULL, NULL, error)) { g_object_unref (output); @@ -570,7 +587,7 @@ save_image (GFile *file, line_size = width * babl_format_get_bytes_per_pixel (file_format); - /* this can't overflow because drawable->width is <= GIMP_MAX_IMAGE_SIZE */ + /* this can't overflow because drawable->width is <= GIMP_PATTERN_MAX_SIZE */ buf = g_alloca (line_size); for (line = 0; line < height; line++)