Be a bit more robust in the face of out-of-memory errors.
authorDan Fandrich <dan@coneharvesters.com>
Mon, 5 Nov 2018 23:53:56 +0000 (00:53 +0100)
committerDan Fandrich <dan@coneharvesters.com>
Tue, 6 Nov 2018 00:03:49 +0000 (01:03 +0100)
Do a better job in leaving things in a more consistent state after an
allocation failure. Also, make the tests report and handle OOM
conditions cleanly.

libexif/exif-data.c
libexif/exif-entry.c
test/test-mem.c
test/test-mnote.c
test/test-parse.c
test/test-value.c

index 350a887..e35403d 100644 (file)
@@ -477,6 +477,11 @@ exif_data_load_data_content (ExifData *data, ExifIfd ifd,
                                        break;
                        }
                        entry = exif_entry_new_mem (data->priv->mem);
+                       if (!entry) {
+                                 exif_log (data->priv->log, EXIF_LOG_CODE_NO_MEMORY, "ExifData",
+                                          "Could not allocate memory");
+                                 return;
+                       }
                        if (exif_data_load_data_entry (data, entry, d, ds,
                                                   offset + 12 * i))
                                exif_content_add_entry (data->ifd[ifd], entry);
index b64f5d9..c0f219b 100644 (file)
@@ -166,6 +166,13 @@ exif_entry_free (ExifEntry *e)
        }
 }
 
+static void
+clear_entry (ExifEntry *e)
+{
+       e->components = 0;
+       e->size = 0;
+}
+
 /*! Get a value and convert it to an ExifShort.
  * \bug Not all types are converted that could be converted and no indication
  *      is made when that occurs
@@ -367,8 +374,7 @@ exif_entry_fix (ExifEntry *e)
                if (e->size < 8) {
                        e->data = exif_entry_realloc (e, e->data, 8 + e->size);
                        if (!e->data) {
-                               e->size = 0;
-                               e->components = 0;
+                               clear_entry(e);
                                return;
                        }
 
@@ -410,8 +416,7 @@ exif_entry_fix (ExifEntry *e)
                    memcmp (e->data, "\0\0\0\0\0\0\0\0", 8)) {
                        e->data = exif_entry_realloc (e, e->data, 8 + e->size);
                        if (!e->data) {
-                               e->size = 0;
-                               e->components = 0;
+                               clear_entry(e);
                                break;
                        }
 
@@ -1419,7 +1424,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_LONG;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                break;
 
        /* SHORT, 1 component, no default */
@@ -1450,7 +1455,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 0);
                break;
 
@@ -1462,7 +1467,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 1);
                break;
 
@@ -1473,7 +1478,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 2);
                break;
 
@@ -1483,7 +1488,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 3);
                break;
 
@@ -1493,7 +1498,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 0xffff);
                break;
 
@@ -1503,7 +1508,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 8);
                exif_set_short (
                        e->data + exif_format_get_size (e->format),
@@ -1519,7 +1524,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SHORT;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                exif_set_short (e->data, o, 2);
                exif_set_short (
                        e->data + exif_format_get_size (e->format),
@@ -1534,7 +1539,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_SRATIONAL;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                break;
 
        /* RATIONAL, 1 component, no default */
@@ -1555,7 +1560,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_RATIONAL;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                break;
 
        /* RATIONAL, 1 component, default 72/1 */
@@ -1565,7 +1570,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_RATIONAL;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                r.numerator = 72;
                r.denominator = 1;
                exif_set_rational (e->data, o, r);
@@ -1577,7 +1582,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_RATIONAL;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                break;
 
        /* RATIONAL, 6 components */
@@ -1586,7 +1591,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_RATIONAL;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                r.denominator = 1;
                r.numerator = 0;
                exif_set_rational (e->data, o, r);
@@ -1628,7 +1633,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_ASCII;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                snprintf ((char *) e->data, e->size,
                          "%04i:%02i:%02i %02i:%02i:%02i",
                          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
@@ -1656,7 +1661,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_ASCII;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                strncpy ((char *)e->data, _("[None]"), e->size);
                break;
        /* ASCII, default "[None]\0[None]\0" */
@@ -1665,7 +1670,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_ASCII;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                strcpy (((char *)e->data) + 0, _("[None]"));
                strcpy (((char *)e->data) + strlen (_("[None]")) + 1, _("[None]"));
                break;
@@ -1676,7 +1681,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_UNDEFINED;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                e->data[0] = 0x01;
                break;
 
@@ -1686,7 +1691,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                e->format = EXIF_FORMAT_UNDEFINED;
                e->size = exif_format_get_size (e->format) * e->components;
                e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+               if (!e->data) { clear_entry(e); break; }
                e->data[0] = 0x03;
                break;
 
@@ -1696,7 +1701,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                 e->format = EXIF_FORMAT_UNDEFINED;
                 e->size = exif_format_get_size (e->format) * e->components;
                 e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+                if (!e->data) { clear_entry(e); break; }
                 memcpy (e->data, "0100", 4);
                 break;
 
@@ -1706,7 +1711,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                 e->format = EXIF_FORMAT_UNDEFINED;
                 e->size = exif_format_get_size (e->format) * e->components;
                 e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+                if (!e->data) { clear_entry(e); break; }
                 memcpy (e->data, "0210", 4);
                 break;
 
@@ -1716,7 +1721,7 @@ exif_entry_initialize (ExifEntry *e, ExifTag tag)
                 e->format = EXIF_FORMAT_UNDEFINED;
                 e->size = exif_format_get_size (e->format) * e->components;
                 e->data = exif_entry_alloc (e, e->size);
-               if (!e->data) break;
+                if (!e->data) { clear_entry(e); break; }
                e->data[0] = 1;
                e->data[1] = 2;
                e->data[2] = 3;
index defcee9..e94df35 100644 (file)
@@ -39,6 +39,11 @@ main ()
 
        printf ("Creating EXIF data...\n");
        ed = exif_data_new ();
+       if (!ed) {
+               fprintf(stderr, "Out of memory\n");
+               exit(13);
+       }
+
        exif_data_set_data_type (ed, EXIF_DATA_TYPE_UNCOMPRESSED_CHUNKY);
 
        printf ("Fill EXIF data with all necessary entries to follow specs...\n");
@@ -47,6 +52,11 @@ main ()
        /* Add a dummy thumbnail */
        ed->size = 4;
        ed->data = calloc(1, ed->size);
+       if (!ed->data) {
+               fprintf(stderr, "Out of memory\n");
+               exif_data_unref (ed);
+               exit(13);
+       }
 
        exif_data_dump (ed);
 
@@ -56,6 +66,11 @@ main ()
 
        printf ("Writing %i byte(s) EXIF data to loader...\n", ebs);
        loader = exif_loader_new ();
+       if (!loader) {
+               fprintf(stderr, "Out of memory\n");
+               free (eb);
+               exit(13);
+       }
        size[0] = (unsigned char) ebs;
        size[1] = (unsigned char) (ebs >> 8);
        exif_loader_write (loader, size, 2);
@@ -63,6 +78,10 @@ main ()
        printf ("Wrote %i byte(s).\n", i);
        free (eb);
        ed = exif_loader_get_data (loader);
+       if (!ed) {
+               fprintf(stderr, "Out of memory\n");
+               exit(13);
+       }
        exif_loader_unref (loader);
        exif_data_dump (ed);
        exif_data_unref (ed);
index 0c85a4f..81d452c 100644 (file)
@@ -32,10 +32,10 @@ test_exif_data (ExifData *d)
        char v[1024], *p;
        ExifMnoteData *md;
 
-       fprintf (stdout, "Byte order: %s\n",
+       printf("Byte order: %s\n",
                exif_byte_order_get_name (exif_data_get_byte_order (d)));
 
-       fprintf (stdout, "Parsing maker note...\n");
+       printf("Parsing maker note...\n");
        md = exif_data_get_mnote_data (d);
        if (!md) {
                fprintf (stderr, "Could not parse maker note!\n");
@@ -43,25 +43,25 @@ test_exif_data (ExifData *d)
                return 1;
        }
 
-       fprintf (stdout, "Increasing ref-count...\n");
+       printf("Increasing ref-count...\n");
        exif_mnote_data_ref (md);
 
-       fprintf (stdout, "Decreasing ref-count...\n");
+       printf("Decreasing ref-count...\n");
        exif_mnote_data_unref (md);
 
-       fprintf (stdout, "Counting entries...\n");
+       printf("Counting entries...\n");
        c = exif_mnote_data_count (md);
-       fprintf (stdout, "Found %i entries.\n", c);
+       printf("Found %i entries.\n", c);
        for (i = 0; i < c; i++) {
-               fprintf (stdout, "Dumping entry number %i...\n", i);
-               fprintf (stdout, "  Name: '%s'\n",
+               printf("Dumping entry number %i...\n", i);
+               printf("  Name: '%s'\n",
                                exif_mnote_data_get_name (md, i));
-               fprintf (stdout, "  Title: '%s'\n",
+               printf("  Title: '%s'\n",
                                exif_mnote_data_get_title (md, i));
-               fprintf (stdout, "  Description: '%s'\n",
+               printf("  Description: '%s'\n",
                                exif_mnote_data_get_description (md, i));
                p = exif_mnote_data_get_value (md, i, v, sizeof (v));
-               if (p) { fprintf (stdout, "  Value: '%s'\n", v); }
+               if (p) { printf("  Value: '%s'\n", v); }
        }
 
        return 0;
@@ -80,28 +80,32 @@ main (int argc, char **argv)
                return 1;
        }
 
-       fprintf (stdout, "Loading '%s'...\n", argv[1]);
+       printf("Loading '%s'...\n", argv[1]);
        d = exif_data_new_from_file (argv[1]);
        if (!d) {
                fprintf (stderr, "Could not load data from '%s'!\n", argv[1]);
                return 1;
        }
-       fprintf (stdout, "Loaded '%s'.\n", argv[1]);
+       printf("Loaded '%s'.\n", argv[1]);
 
-       fprintf (stdout, "######### Test 1 #########\n");
+       printf("######### Test 1 #########\n");
        r = test_exif_data (d);
        if (r) return r;
 
        exif_data_save_data (d, &buf, &buf_size);
        exif_data_unref (d);
        d = exif_data_new_from_data (buf, buf_size);
+       if (!d) {
+               fprintf (stderr, "Could not load data from buf!\n");
+               return 1;
+       }
        free (buf);
 
-       fprintf (stdout, "######### Test 2 #########\n");
+       printf ("######### Test 2 #########\n");
        r = test_exif_data (d);
        if (r) return r;
 
-       fprintf (stdout, "Test successful!\n");
+       printf ("Test successful!\n");
 
        return 1;
 }
index c427c34..c32ab9c 100644 (file)
@@ -92,6 +92,10 @@ static void test_parse(const char *filename, void *callback_data, int swap)
   printf("File %s\n", fn);
 
   d = exif_data_new_from_file(filename);
+  if (!d) {
+      fprintf (stderr, "Could not load data from '%s'!\n", filename);
+      return;
+  }
   printf("Byte order: %s\n",
           exif_byte_order_get_name(exif_data_get_byte_order(d)));
 
index 557bb3a..860845e 100644 (file)
@@ -131,7 +131,7 @@ main ()
 
        data = exif_data_new ();
        if (!data) {
-               printf ("Error running exif_data_new()\n");
+               fprintf (stderr, "Error running exif_data_new()\n");
                exit(13);
        }
 
@@ -139,7 +139,7 @@ main ()
        for (i=0; i < sizeof(trunc_test_tags)/sizeof(trunc_test_tags[0]); ++i) {
                e = exif_entry_new ();
                if (!e) {
-                       printf ("Error running exif_entry_new()\n");
+                       fprintf (stderr, "Error running exif_entry_new()\n");
                        exit(13);
                }
                exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -154,7 +154,7 @@ main ()
                 ++i) {
                e = exif_entry_new ();
                if (!e) {
-                       printf ("Error running exif_entry_new()\n");
+                       fprintf (stderr, "Error running exif_entry_new()\n");
                        exit(13);
                }
                exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -169,7 +169,7 @@ main ()
                 ++i) {
                e = exif_entry_new ();
                if (!e) {
-                       printf ("Error running exif_entry_new()\n");
+                       fprintf (stderr, "Error running exif_entry_new()\n");
                        exit(13);
                }
                exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -186,14 +186,14 @@ main ()
        /* Create a memory allocator to manage the remaining ExifEntry structs */
        mem = exif_mem_new_default();
        if (!mem) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
 
        /* EXIF_TAG_SUB_SEC_TIME initialization/truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -203,7 +203,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        memcpy(e->data, subsec, e->size);
@@ -214,7 +214,7 @@ main ()
        /* EXIF_TAG_USER_COMMENT initialization/truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -224,7 +224,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        memcpy(e->data, user_comment, e->size);
@@ -235,7 +235,7 @@ main ()
        /* EXIF_TAG_XP_COMMENT truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -246,7 +246,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        memcpy(e->data, xp_comment, e->size);
@@ -257,7 +257,7 @@ main ()
        /* EXIF_TAG_INTEROPERABILITY_VERSION truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_INTEROPERABILITY], e);
@@ -269,7 +269,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        memcpy(e->data, interop, e->size);
@@ -280,7 +280,7 @@ main ()
        /* EXIF_TAG_GPS_VERSION_ID truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_GPS], e);
@@ -291,7 +291,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        e->data[0] = 2;
@@ -305,7 +305,7 @@ main ()
        /* EXIF_TAG_GPS_ALTITUDE_REF truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_GPS], e);
@@ -316,7 +316,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        e->data[0] = 1;
@@ -327,7 +327,7 @@ main ()
        /* EXIF_TAG_GPS_TIME_STAMP truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_GPS], e);
@@ -338,7 +338,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_set_rational(e->data, exif_data_get_byte_order (data), gpsh);
@@ -351,7 +351,7 @@ main ()
        /* EXIF_TAG_SUBJECT_AREA truncation tests */
        e = exif_entry_new_mem (mem);
        if (!e) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_content_add_entry (data->ifd[EXIF_IFD_0], e);
@@ -364,7 +364,7 @@ main ()
        /* Allocate memory to use for holding the tag data */
        e->data = exif_mem_alloc(mem, e->size);
        if (!e->data) {
-               printf ("Out of memory\n");
+               fprintf (stderr, "Out of memory\n");
                exit(13);
        }
        exif_set_short(e->data, exif_data_get_byte_order (data), 123);