Better error recovery when using bad records.
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 29 Mar 1995 16:08:56 +0000 (16:08 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 29 Mar 1995 16:08:56 +0000 (16:08 +0000)
util/iso2709.c

index 9e3f803..6e6d99d 100644 (file)
@@ -4,7 +4,10 @@
  * Europagate, 1994-1995.
  *
  * $Log: iso2709.c,v $
- * Revision 1.11  1995/03/28 16:07:07  adam
+ * Revision 1.12  1995/03/29 16:08:56  adam
+ * Better error recovery when using bad records.
+ *
+ * Revision 1.11  1995/03/28  16:07:07  adam
  * New function: iso2709_out. This function is the reverse of iso2709_cvt.
  *
  * Revision 1.10  1995/03/10  09:10:56  adam
@@ -132,9 +135,13 @@ Iso2709Rec iso2709_cvt (const char *buf)
     *dpp = NULL;
     while (buf[pos] != ISO2709_FS)
     {
-        *dpp = malloc (sizeof(**dpp));
-        assert (*dpp);
+        if (!(*dpp = malloc (sizeof(**dpp))))
+        {
+            iso2709_rm (p);
+            return NULL;
+        }
         (*dpp)->next = NULL;
+        (*dpp)->fields = NULL;
         strncpyx ((*dpp)->tag, buf+pos, 3);
         pos += 3;
         (*dpp)->length = atoin (buf+pos, p->length_data_entry);
@@ -143,6 +150,11 @@ Iso2709Rec iso2709_cvt (const char *buf)
         pos += p->length_starting + p->length_implementation;
 
         dpp = &(*dpp)->next;
+        if (pos > p->record_length)
+        {
+            iso2709_rm (p);
+            return NULL;
+        }
     }
     pos++;
     /* deal with datafields */
@@ -151,11 +163,15 @@ Iso2709Rec iso2709_cvt (const char *buf)
         int identifier_flag;
         struct iso2709_field **fpp;
         int dpos = pos+dp->offset;
+        int epos = pos+dp->offset+dp->length-1;
 
         fpp = &dp->fields;
 
-        *fpp = malloc (sizeof(**fpp));
-        assert (*fpp);
+        if (!(*fpp = malloc (sizeof(**fpp))))
+        {
+            iso2709_rm (p);
+            return NULL;
+        }
         (*fpp)->next = NULL;
 
         identifier_flag = 1;
@@ -173,8 +189,11 @@ Iso2709Rec iso2709_cvt (const char *buf)
                 identifier_flag = 0;
         if (identifier_flag && p->indicator_length)
         {
-            dp->indicator = malloc (p->indicator_length+1);
-            assert (dp->indicator);
+            if (!(dp->indicator = malloc (p->indicator_length+1)))
+            {
+                iso2709_rm (p);
+                return NULL;
+            }
             strncpyx (dp->indicator, buf+dpos, p->indicator_length);
             dpos += p->indicator_length;
         }
@@ -185,32 +204,53 @@ Iso2709Rec iso2709_cvt (const char *buf)
             int dpos_n;
             if (p->identifier_length && identifier_flag)
             {
-                (*fpp)->identifier = malloc (p->identifier_length+1);
+                if (!((*fpp)->identifier = malloc (p->identifier_length+1)))
+                {
+                    iso2709_rm (p);
+                    return NULL;
+                }
                 strncpyx ((*fpp)->identifier, buf+dpos+1,
                           p->identifier_length-1);
                 dpos_n = dpos += p->identifier_length;
                 while (buf[dpos_n] != ISO2709_FS && buf[dpos_n] != ISO2709_RS
-                       && buf[dpos_n] != ISO2709_IDFS)
+                       && buf[dpos_n] != ISO2709_IDFS && dpos_n < epos)
                     dpos_n++;
             }
             else
             {
                 (*fpp)->identifier = NULL;
                 dpos_n = dpos;
-                while (buf[dpos_n] != ISO2709_FS && buf[dpos_n] != ISO2709_RS)
+                while (buf[dpos_n] != ISO2709_FS && buf[dpos_n] != ISO2709_RS
+                       && dpos_n < epos)
                     dpos_n++;
             }
-            (*fpp)->data = malloc (dpos_n - dpos + 1);
-            assert ((*fpp)->data);
+            if (!((*fpp)->data = malloc (dpos_n - dpos + 1)))
+            {
+                iso2709_rm (p);
+                return NULL;
+            }
             strncpyx ((*fpp)->data, buf+dpos, dpos_n - dpos);
             dpos = dpos_n;
             
+            if (dpos == epos)
+            {
+                if (buf[dpos] != ISO2709_FS && buf[dpos] != ISO2709_RS)
+                    fprintf (stderr, "Missing separator at end of field "
+                             "in %s %s\n", dp->tag, (*fpp)->identifier ?
+                             (*fpp)->identifier : "");
+                break;
+            }
             if (buf[dpos] == ISO2709_FS || buf[dpos] == ISO2709_RS)
+            {
+                fprintf (stderr, "Unexpected separator inside field\n");
                 break;
-            
+            }
             fpp = &(*fpp)->next;
-            *fpp = malloc (sizeof(**fpp));
-            assert (*fpp);
+            if (!(*fpp = malloc (sizeof(**fpp))))
+            {
+                iso2709_rm (p);
+                return NULL;
+            }
             (*fpp)->next = NULL;
         }
     }