Commit da0c514a authored by conrad's avatar conrad
Browse files

comments_encode(): port pointer arith from oggz:

strlen, accum_length checks

git-svn-id: http://svn.annodex.net/libfishsound/trunk@3884 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent ee251486
...@@ -35,17 +35,33 @@ ...@@ -35,17 +35,33 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h> /* ULONG_MAX */
#ifndef WIN32
#include <strings.h>
#endif
#include "private.h" #include "private.h"
/*#define DEBUG*/ /*#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 * static char *
fs_strdup (const char * s) fs_strdup (const char * s)
{ {
char * ret; char * ret;
if (s == NULL) return NULL; if (s == NULL) return NULL;
ret = fs_malloc (strlen(s) + 1); ret = fs_malloc (fs_comment_len(s) + 1);
if (ret == NULL) return NULL; if (ret == NULL) return NULL;
return strcpy (ret, s); return strcpy (ret, s);
} }
...@@ -504,27 +520,56 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments, ...@@ -504,27 +520,56 @@ fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
return FISH_SOUND_OK; 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 long
fish_sound_comments_encode (FishSound * fsound, unsigned char * buf, fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
long length) long length)
{ {
char * c = (char *)buf; char * c = (char *)buf;
const FishSoundComment * comment; const FishSoundComment * comment;
int nb_fields = 0, vendor_length, field_length; int nb_fields = 0, vendor_length = 0;
long actual_length, remaining = length; unsigned long actual_length = 0, remaining = length, field_length;
/* Vendor string */ /* Vendor string */
vendor_length = strlen (fsound->vendor); if (fsound->vendor)
actual_length = 4 + vendor_length; vendor_length = fs_comment_len (fsound->vendor);
if (accum_length (&actual_length, 4 + vendor_length) == 0)
return 0;
/* user comment list length */ /* user comment list length */
actual_length += 4; if (accum_length (&actual_length, 4) == 0)
return 0;
for (comment = fish_sound_comment_first (fsound); comment; for (comment = fish_sound_comment_first (fsound); comment;
comment = fish_sound_comment_next (fsound, comment)) { comment = fish_sound_comment_next (fsound, comment)) {
actual_length += 4 + strlen (comment->name); /* [size]"name" */ /* [size]"name" */
if (comment->value) if (accum_length (&actual_length, 4 + fs_comment_len (comment->name)) == 0)
actual_length += 1 + strlen (comment->value); /* "=value" */ return 0;
if (comment->value) {
/* "=value" */
if (accum_length (&actual_length, 1 + fs_comment_len (comment->value)) == 0)
return 0;
}
#ifdef DEBUG #ifdef DEBUG
printf ("fish_sound_comments_encode: %s = %s\n", printf ("fish_sound_comments_encode: %s = %s\n",
...@@ -534,7 +579,11 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf, ...@@ -534,7 +579,11 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
nb_fields++; 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; if (buf == NULL) return actual_length;
...@@ -543,10 +592,12 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf, ...@@ -543,10 +592,12 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
writeint (c, 0, vendor_length); writeint (c, 0, vendor_length);
c += 4; c += 4;
field_length = strlen (fsound->vendor); if (fsound->vendor) {
memcpy (c, fsound->vendor, MIN (field_length, remaining)); field_length = fs_comment_len (fsound->vendor);
c += field_length; remaining -= field_length; memcpy (c, fsound->vendor, MIN (field_length, remaining));
if (remaining <= 0 ) return actual_length; c += field_length; remaining -= field_length;
if (remaining <= 0) return actual_length;
}
remaining -= 4; remaining -= 4;
if (remaining <= 0) return actual_length; if (remaining <= 0) return actual_length;
...@@ -556,16 +607,16 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf, ...@@ -556,16 +607,16 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
for (comment = fish_sound_comment_first (fsound); comment; for (comment = fish_sound_comment_first (fsound); comment;
comment = fish_sound_comment_next (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) if (comment->value)
field_length += 1 + strlen (comment->value); /* "=value" */ field_length += 1 + fs_comment_len (comment->value); /* "=value" */
remaining -= 4; remaining -= 4;
if (remaining <= 0) return actual_length; if (remaining <= 0) return actual_length;
writeint (c, 0, field_length); writeint (c, 0, field_length);
c += 4; c += 4;
field_length = strlen (comment->name); field_length = fs_comment_len (comment->name);
memcpy (c, comment->name, MIN (field_length, remaining)); memcpy (c, comment->name, MIN (field_length, remaining));
c += field_length; remaining -= field_length; c += field_length; remaining -= field_length;
if (remaining <= 0) return actual_length; if (remaining <= 0) return actual_length;
...@@ -576,7 +627,7 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf, ...@@ -576,7 +627,7 @@ fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
*c = '='; *c = '=';
c++; c++;
field_length = strlen (comment->value); field_length = fs_comment_len (comment->value);
memcpy (c, comment->value, MIN (field_length, remaining)); memcpy (c, comment->value, MIN (field_length, remaining));
c += field_length; remaining -= field_length; c += field_length; remaining -= field_length;
if (remaining <= 0) return actual_length; if (remaining <= 0) return actual_length;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment