[gimp/alxsa-ani-fix: 6/6] plug-ins: Fix odd length for .ani metadata




commit ffbee517760b780acb42c7d1208ee404ba3561d0
Author: Alx Sa <cmyk student gmail com>
Date:   Mon Oct 3 12:13:06 2022 +0000

    plug-ins: Fix odd length for .ani metadata
    
    .ani files require metadata fields to be an even length. If the data
    length is odd, an extra 0x00 is added for padding.
    This patch updates the export and import code to comply with this
    requirement.

 plug-ins/file-ico/ico-load.c | 12 ++++++++++++
 plug-ins/file-ico/ico-save.c | 13 +++++++++++++
 2 files changed, 25 insertions(+)
---
diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c
index b29dab85a8..3c91ff6a0f 100644
--- a/plug-ins/file-ico/ico-load.c
+++ b/plug-ins/file-ico/ico-load.c
@@ -775,6 +775,7 @@ ani_load_image (GFile   *file,
   GimpParasite *parasite;
   gchar         id[4];
   guint32       size;
+  guint8        padding;
   gint32        file_offset;
   gint          frame = 1;
   AniFileHeader header;
@@ -825,12 +826,23 @@ ani_load_image (GFile   *file,
           fread (&size, sizeof (size), 1, fp);
           fread (&inam, sizeof (char), size, fp);
           inam[size] = '\0';
+
+          /* Metadata length must be even. If data itself is odd,
+           * then an extra 0x00 is added for padding. We read in
+           * that extra byte to keep loading properly.
+           * See discussion in #8562.
+           */
+          if (size % 2 != 0)
+            fread (&padding, sizeof (padding), 1, fp);
         }
       else if (memcmp (id, "IART", 4) == 0)
         {
           fread (&size, sizeof (size), 1, fp);
           fread (&iart, sizeof (char), size, fp);
           iart[size] = '\0';
+
+          if (size % 2 != 0)
+            fread (&padding, sizeof (padding), 1, fp);
         }
       else if (memcmp (id, "icon", 4) == 0)
         {
diff --git a/plug-ins/file-ico/ico-save.c b/plug-ins/file-ico/ico-save.c
index 915c61b373..ccfda351de 100644
--- a/plug-ins/file-ico/ico-save.c
+++ b/plug-ins/file-ico/ico-save.c
@@ -1226,8 +1226,10 @@ ani_save_image (GFile         *file,
   GimpParasite *parasite = NULL;
   gchar         id[5];
   guint32       size;
+  guint8        padding       = 0;
   gint32        offset, ofs_size_riff, ofs_size_list, ofs_size_icon;
   gint32        ofs_size_info = 0;
+  gint32        ofs_metadata  = 0;
   IcoSaveInfo   info;
 
   if (! ico_save_init (image, run_mode, &info,
@@ -1361,6 +1363,11 @@ ani_save_image (GFile         *file,
           string_size = strlen (ani_info->inam) + 1;
           fwrite (&string_size, 4, 1, fp);
           fwrite (ani_info->inam, string_size, 1, fp);
+          ofs_metadata += 4;
+
+          /* Length of metadata must be even. */
+          if (string_size % 2 != 0)
+            fwrite (&padding, sizeof (padding), 1, fp);
         }
       if (ani_info->iart && strlen (ani_info->iart) > 0) /* Author name */
         {
@@ -1369,6 +1376,10 @@ ani_save_image (GFile         *file,
           string_size = strlen (ani_info->iart) + 1;
           fwrite (&string_size, 4, 1, fp);
           fwrite (ani_info->iart, string_size, 1, fp);
+          ofs_metadata += 4;
+
+          if (string_size % 2 != 0)
+            fwrite (&padding, sizeof (padding), 1, fp);
         }
 
       /* Go back and update info list size */
@@ -1426,10 +1437,12 @@ ani_save_image (GFile         *file,
 
   fseek (fp, 0L, SEEK_END);
   size = ftell (fp);
+  size -= ofs_metadata;
   fseek (fp, ofs_size_riff, SEEK_SET);
   fwrite (&size, sizeof (size), 1, fp);
 
   size -= ofs_size_list;
+  size += (ofs_metadata - 4);
   fseek (fp, ofs_size_list, SEEK_SET);
   fwrite (&size, sizeof (size), 1, fp);
   fclose (fp);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]