[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