[xiph-commits] r3884 - libfishsound/trunk/src/libfishsound

conrad at svn.annodex.net conrad at svn.annodex.net
Tue Mar 17 00:55:29 PDT 2009


Author: conrad
Date: 2009-03-17 00:55:28 -0700 (Tue, 17 Mar 2009)
New Revision: 3884

Modified:
   libfishsound/trunk/src/libfishsound/comments.c
Log:
comments_encode(): port pointer arith from oggz:
strlen, accum_length checks

Modified: libfishsound/trunk/src/libfishsound/comments.c
===================================================================
--- libfishsound/trunk/src/libfishsound/comments.c	2009-03-17 07:25:12 UTC (rev 3883)
+++ libfishsound/trunk/src/libfishsound/comments.c	2009-03-17 07:55:28 UTC (rev 3884)
@@ -35,17 +35,33 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h> /* ULONG_MAX */
+#ifndef WIN32
+#include <strings.h>
+#endif
 
 #include "private.h"
 
 /*#define DEBUG*/
 
+/* Ensure comment vector length can be expressed in 32 bits */
+static unsigned long
+fs_comment_len (const char * s)
+{
+  size_t len;
+
+  if (s == NULL) return 0;
+
+  len = strlen (s);
+  return (unsigned long) MIN(len, 0xFFFFFFFF);
+}
+
 static char *
 fs_strdup (const char * s)
 {
   char * ret;
   if (s == NULL) return NULL;
-  ret = fs_malloc (strlen(s) + 1);
+  ret = fs_malloc (fs_comment_len(s) + 1);
   if (ret == NULL) return NULL;
   return strcpy (ret, s);
 }
@@ -504,27 +520,56 @@
    return FISH_SOUND_OK;
 }
 
+/*
+ * Pre-condition: at least one of accum, delta are non-zero,
+ * ie. don't call accum_length (0, 0);
+ * \retval 0 Failure: integer overflow
+ */
+static unsigned long
+accum_length (unsigned long * accum, unsigned long delta)
+{
+  /* Pre-condition: don't call accum_length (0, 0) */
+  if (*accum == 0 && delta == 0)
+    return 0;
+
+  /* Check for integer overflow */
+  if (delta > ULONG_MAX - (*accum))
+    return 0;
+
+  *accum += delta;
+
+  return *accum;
+}
+
 long
 fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
 			    long length)
 {
   char * c = (char *)buf;
   const FishSoundComment * comment;
-  int nb_fields = 0, vendor_length, field_length;
-  long actual_length, remaining = length;
+  int nb_fields = 0, vendor_length = 0;
+  unsigned long actual_length = 0, remaining = length, field_length;
 
   /* Vendor string */
-  vendor_length = strlen (fsound->vendor);
-  actual_length = 4 + vendor_length;
+  if (fsound->vendor)
+    vendor_length = fs_comment_len (fsound->vendor);
+  if (accum_length (&actual_length, 4 + vendor_length) == 0)
+    return 0;
 
   /* user comment list length */
-  actual_length += 4;
+  if (accum_length (&actual_length, 4) == 0)
+    return 0;
 
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
-    actual_length += 4 + strlen (comment->name);    /* [size]"name" */
-    if (comment->value)
-      actual_length += 1 + strlen (comment->value); /* "=value" */
+    /* [size]"name" */
+    if (accum_length (&actual_length, 4 + fs_comment_len (comment->name)) == 0)
+      return 0;
+    if (comment->value) {
+      /* "=value" */
+      if (accum_length (&actual_length, 1 + fs_comment_len (comment->value)) == 0)
+        return 0;
+    }
 
 #ifdef DEBUG
     printf ("fish_sound_comments_encode: %s = %s\n",
@@ -534,8 +579,12 @@
     nb_fields++;
   }
 
-  actual_length++; /* framing bit */
+  /* framing bit */
+  if (accum_length (&actual_length, 1) == 0)
+    return 0;
 
+  /* NB. actual_length is not modified from here onwards */
+
   if (buf == NULL) return actual_length;
 
   remaining -= 4;
@@ -543,10 +592,12 @@
   writeint (c, 0, vendor_length);
   c += 4;
 
-  field_length = strlen (fsound->vendor);
-  memcpy (c, fsound->vendor, MIN (field_length, remaining));
-  c += field_length; remaining -= field_length;
-  if (remaining <= 0 ) return actual_length;
+  if (fsound->vendor) {
+    field_length = fs_comment_len (fsound->vendor);
+    memcpy (c, fsound->vendor, MIN (field_length, remaining));
+    c += field_length; remaining -= field_length;
+    if (remaining <= 0) return actual_length;
+  }
 
   remaining -= 4;
   if (remaining <= 0) return actual_length;
@@ -556,16 +607,16 @@
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
 
-    field_length = strlen (comment->name);     /* [size]"name" */
+    field_length = fs_comment_len (comment->name);     /* [size]"name" */
     if (comment->value)
-      field_length += 1 + strlen (comment->value); /* "=value" */
+      field_length += 1 + fs_comment_len (comment->value); /* "=value" */
 
     remaining -= 4;
     if (remaining <= 0) return actual_length;
     writeint (c, 0, field_length);
     c += 4;
 
-    field_length = strlen (comment->name);
+    field_length = fs_comment_len (comment->name);
     memcpy (c, comment->name, MIN (field_length, remaining));
     c += field_length; remaining -= field_length;
     if (remaining <= 0) return actual_length;
@@ -576,7 +627,7 @@
       *c = '=';
       c++;
 
-      field_length = strlen (comment->value);
+      field_length = fs_comment_len (comment->value);
       memcpy (c, comment->value, MIN (field_length, remaining));
       c += field_length; remaining -= field_length;
       if (remaining <= 0) return actual_length;



More information about the commits mailing list