Bug 480521 - Update libfishsound to e98a05 and liboggz to ef3b0e. rs=roc
authorChris Double <chris.double@double.co.nz>
Sun, 05 Apr 2009 11:17:48 +1200
changeset 26921 d65a87f103d2530e4d95a522fd5b7dd9fe5fa93f
parent 26920 d8d2c0480c77b59f39be83d7012a2936c4fd5494
child 26922 d0de9c05aad3828ef41a3f1660104e87a0e9c790
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs480521
milestone1.9.2a1pre
Bug 480521 - Update libfishsound to e98a05 and liboggz to ef3b0e. rs=roc
media/libfishsound/AUTHORS
media/libfishsound/README_MOZILLA
media/libfishsound/include/fishsound/config.h
media/libfishsound/include/fishsound/constants.h
media/libfishsound/include/fishsound/decode.h
media/libfishsound/include/fishsound/deprecated.h
media/libfishsound/include/fishsound/fishsound.h
media/libfishsound/src/libfishsound/config.h
media/libfishsound/src/libfishsound/fishsound.c
media/libfishsound/src/libfishsound/fishsound_comments.c
media/libfishsound/src/libfishsound/fishsound_decode.c
media/libfishsound/src/libfishsound/fishsound_flac.c
media/libfishsound/src/libfishsound/fishsound_speex.c
media/libfishsound/src/libfishsound/fishsound_vorbis.c
media/libfishsound/src/libfishsound/fs_vector.c
media/libfishsound/update.sh
media/liboggz/README
media/liboggz/README_MOZILLA
media/liboggz/include/oggz/config_win32.h
media/liboggz/include/oggz/oggz_read.h
media/liboggz/seek-error-fix.patch
media/liboggz/src/liboggz/oggz.c
media/liboggz/src/liboggz/oggz_auto.c
media/liboggz/src/liboggz/oggz_comments.c
media/liboggz/update.sh
--- a/media/libfishsound/AUTHORS
+++ b/media/libfishsound/AUTHORS
@@ -1,14 +1,17 @@
 Conrad Parker <conrad@metadecks.org>
         - Design, implementation.
 	- Vorbis, Speex support
 
 Tobias Gehrig
 	- FLAC support
+
+Michel Salim
+	- libFLAC 1.1.3 support
   
 Silvia Pfeiffer <silvia@annodex.net>
         - MS Windows porting, general packaging.
 
 Zentaro Kavanagh <ogg@illiminable.com>
 	- Windows porting and packaging.
 
 
--- a/media/libfishsound/README_MOZILLA
+++ b/media/libfishsound/README_MOZILLA
@@ -1,10 +1,11 @@
-The source from this directory was copied from the libfishsound-0.9.1
-source distribution using the update.sh script. The only changes made
+The source from this directory was copied from the libfishsound git
+distribution using the update.sh script. The only changes made
 were those applied by update.sh and the addition/upate of Makefile.in
 files for the Mozilla build system.
 
 Some files are renamed during the copy to prevent clashes with object
 file names with other Mozilla libraries.
 
+The git commit id used was e98a05 from git://git.xiph.org/libfishsound.git
+
 endian.patch is applied to fix Bug 45269.
-bu481601.patch is applied to fix bug 481601.
--- a/media/libfishsound/include/fishsound/config.h
+++ b/media/libfishsound/include/fishsound/config.h
@@ -30,17 +30,17 @@
 
 /* Define to 1 if you have libspeex */
 #define HAVE_SPEEX 0
 
 /* Define to 1 if you have libspeex 1.1.x */
 /* #undef HAVE_SPEEX_1_1 */
 
 /* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
+/* #define HAVE_STDINT_H 1 */
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
 /* Define to 1 if you have the <string.h> header file. */
--- a/media/libfishsound/include/fishsound/constants.h
+++ b/media/libfishsound/include/fishsound/constants.h
@@ -101,16 +101,19 @@ typedef enum _FishSoundError {
   FISH_SOUND_ERR_GENERIC                = -1,
 
   /** Not a valid FishSound* handle */
   FISH_SOUND_ERR_BAD                    = -2,
 
   /** The requested operation is not suitable for this FishSound* handle */
   FISH_SOUND_ERR_INVALID                = -3,
 
+  /** Out of memory */
+  FISH_SOUND_ERR_OUT_OF_MEMORY          = -4,
+
   /** Functionality disabled at build time */
   FISH_SOUND_ERR_DISABLED               = -10,
 
   /** Too few bytes passed to fish_sound_identify() */
   FISH_SOUND_ERR_SHORT_IDENTIFY         = -20,
 
   /** Comment violates VorbisComment restrictions */
   FISH_SOUND_ERR_COMMENT_INVALID        = -21
--- a/media/libfishsound/include/fishsound/decode.h
+++ b/media/libfishsound/include/fishsound/decode.h
@@ -74,29 +74,33 @@ typedef int (*FishSoundDecoded_FloatIlv)
 					  long frames, void * user_data);
 
 /**
  * Set the callback for libfishsound to call when it has a block of decoded
  * PCM audio ready, and you want this provided as non-interleaved floats.
  * \param fsound A FishSound* handle (created with mode FISH_SOUND_DECODE)
  * \param decoded The callback to call
  * \param user_data Arbitrary user data to pass to the callback
- * \returns 0 on success, -1 on failure
+ * \retval 0 Success
+ * \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
+ * \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
  */
 int fish_sound_set_decoded_float (FishSound * fsound,
 				  FishSoundDecoded_Float decoded,
 				  void * user_data);
 
 /**
  * Set the callback for libfishsound to call when it has a block of decoded
  * PCM audio ready, and you want this provided as interleaved floats.
  * \param fsound A FishSound* handle (created with mode FISH_SOUND_DECODE)
  * \param decoded The callback to call
  * \param user_data Arbitrary user data to pass to the callback
- * \returns 0 on success, -1 on failure
+ * \retval 0 Success
+ * \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
+ * \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
  */
 int fish_sound_set_decoded_float_ilv (FishSound * fsound,
 				      FishSoundDecoded_FloatIlv decoded,
 				      void * user_data);
 
 /**
  * Decode a block of compressed data.
  * No internal buffering is done, so a complete compressed audio packet
@@ -108,16 +112,18 @@ int fish_sound_set_decoded_float_ilv (Fi
  * \retval FISH_SOUND_ERR_STOP_OK Decoding was stopped by a FishSoundDecode*
  * callback returning FISH_SOUND_STOP_OK before any input bytes were consumed.
  * This will occur when PCM is decoded from previously buffered input, and
  * stopping is immediately requested.
  * \retval FISH_SOUND_ERR_STOP_ERR Decoding was stopped by a FishSoundDecode*
  * callback returning FISH_SOUND_STOP_ERR before any input bytes were consumed.
  * This will occur when PCM is decoded from previously buffered input, and
  * stopping is immediately requested.
+ * \retval FISH_SOUND_ERR_BAD Not a valid FishSound* handle
+ * \retval FISH_SOUND_ERR_OUT_OF_MEMORY Out of memory
  */
 long fish_sound_decode (FishSound * fsound, unsigned char * buf, long bytes);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __FISH_SOUND_DECODE_H__ */
--- a/media/libfishsound/include/fishsound/deprecated.h
+++ b/media/libfishsound/include/fishsound/deprecated.h
@@ -37,37 +37,16 @@
  * Deprecated interfaces
  */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * DEPRECATED FUNCTION.
- * Set the PCM format used by a FishSound object. The default value is
- * non-interleaved.
- * Prior to libfishsound 0.7.0, you would (optionally) specify whether you
- * wanted to receive interleaved or per-channel PCM data using
- * fish_sound_set_interleave(), the default being per-channel
- * (non-interleaved) PCM.
- * Whether or not your decoded callback expects interleaved or
- * non-interleaved data is now implied by the particular
- * fish_sound_set_decoded_TYPE() method you use to set it, such as
- * fish_sound_set_decoded_float() or fish_sound_set_decode_float_ilv().
- *
- * \param fsound A FishSound* handle
- * \param interleave Whether to use interleaved PCM or not. Valid values are
- * 0 for non-interleaved, and 1 for interleaved.
- * \retval 0 Success
- * \retval -1 Invalid \a fsound
- */
-int fish_sound_set_interleave (FishSound * fsound, int interleave);
-
-/**
  * DEPRECATED TYPE.
  * Signature of a callback for libfishsound to call when it has decoded
  * PCM audio data, and you want this provided as floats using the current
  * interleave method as set by fish_sound_set_interleave().
  */
 typedef FishSoundDecoded_Float FishSoundDecoded;
 
 /**
@@ -94,17 +73,17 @@ int fish_sound_set_decoded_callback (Fis
  * non-interleaved.
  * Prior to libfishsound 0.7.0, you would (optionally) specify whether you
  * wanted to receive interleaved or per-channel PCM data using
  * fish_sound_set_interleave(), the default being per-channel
  * (non-interleaved) PCM.
  * Whether or not your decoded callback expects interleaved or
  * non-interleaved data is now implied by the particular
  * fish_sound_set_decoded_TYPE() method you use to set it, such as
- * fish_sound_set_decoded_float() or fish_sound_set_decode_float_ilv().
+ * fish_sound_set_decoded_float() or fish_sound_set_decoded_float_ilv().
  *
  * \param fsound A FishSound* handle
  * \param interleave Whether to use interleaved PCM or not. Valid values are
  * 0 for non-interleaved, and 1 for interleaved.
  * \retval 0 Success
  * \retval -1 Invalid \a fsound
  */
 int fish_sound_set_interleave (FishSound * fsound, int interleave);
--- a/media/libfishsound/include/fishsound/fishsound.h
+++ b/media/libfishsound/include/fishsound/fishsound.h
@@ -500,17 +500,17 @@ int fish_sound_delete (FishSound * fsoun
 int fish_sound_command (FishSound * fsound, int command, void * data,
 			int datasize);
 
 /**
  * Query whether a FishSound object is using interleaved PCM
  * \param fsound A FishSound* handle
  * \retval 0 \a fsound uses non-interleaved PCM
  * \retval 1 \a fsound uses interleaved PCM
- * \retval -1 Invalid \a fsound
+ * \retval -1 Invalid \a fsound, or out of memory.
  */
 int fish_sound_get_interleave (FishSound * fsound);
 
 /**
  * Query the current frame number of a FishSound object.
  *
  * For decoding, this is the greatest frame index that has been decoded and
  * made available to a FishSoundDecoded callback. This function is safe to
--- a/media/libfishsound/src/libfishsound/config.h
+++ b/media/libfishsound/src/libfishsound/config.h
@@ -30,17 +30,17 @@
 
 /* Define to 1 if you have libspeex */
 #define HAVE_SPEEX 0
 
 /* Define to 1 if you have libspeex 1.1.x */
 /* #undef HAVE_SPEEX_1_1 */
 
 /* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
+/* #define HAVE_STDINT_H 1 */
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
 /* Define to 1 if you have the <string.h> header file. */
--- a/media/libfishsound/src/libfishsound/fishsound.c
+++ b/media/libfishsound/src/libfishsound/fishsound.c
@@ -65,17 +65,17 @@ fish_sound_set_format (FishSound * fsoun
     fsound->codec = fish_sound_speex_codec ();
   } else if (format == FISH_SOUND_FLAC) {
     fsound->codec = fish_sound_flac_codec ();
    } else {
     return -1;
   }
 
   if (fsound->codec && fsound->codec->init)
-    fsound->codec->init (fsound);
+    if (fsound->codec->init (fsound) == NULL) return -1;
 
   fsound->info.format = format;
 
   return format;
 }
 
 FishSound *
 fish_sound_new (int mode, FishSoundInfo * fsinfo)
@@ -100,16 +100,17 @@ fish_sound_new (int mode, FishSoundInfo 
         if (fsinfo->format == FISH_SOUND_FLAC) return NULL;
       }
     }
   } else if (mode != FISH_SOUND_DECODE) {
     return NULL;
   }
 
   fsound = fs_malloc (sizeof (FishSound));
+  if (fsound == NULL) return NULL;
 
   fsound->mode = mode;
   fsound->interleave = 0;
   fsound->frameno = 0;
   fsound->next_granulepos = -1;
   fsound->next_eos = 0;
   fsound->codec = NULL;
   fsound->codec_data = NULL;
--- a/media/libfishsound/src/libfishsound/fishsound_comments.c
+++ b/media/libfishsound/src/libfishsound/fishsound_comments.c
@@ -30,37 +30,60 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include "config.h"
 
 #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
+ * including space for the trailing NUL */
+#define MAX_COMMENT_LENGTH 0xFFFFFFFE
+#define fs_comment_clamp(c) MIN((c),MAX_COMMENT_LENGTH)
+
+static size_t
+fs_comment_len (const char * s)
+{
+  size_t len;
+
+  if (s == NULL) return 0;
+
+  len = strlen (s);
+  return fs_comment_clamp(len);
+}
+
 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);
 }
 
 static char *
-fs_strdup_len (const char * s, int len)
+fs_strdup_len (const char * s, size_t len)
 {
   char * ret;
   if (s == NULL) return NULL;
   if (len == 0) return NULL;
+  len = fs_comment_clamp(len);
   ret = fs_malloc (len + 1);
+  if (ret == NULL) return NULL;
   if (strncpy (ret, s, len) == NULL) {
     fs_free (ret);
     return NULL;
   }
 
   ret[len] = '\0';
   return ret;
 }
@@ -74,21 +97,16 @@ fs_index_len (const char * s, char c, in
     if (*s == c) return (char *)s;
   }
 
   if (i < len) return (char *)s;
 
   return NULL;
 }
 
-#if 0
-static void comment_init(char **comments, int* length, char *vendor_string);
-static void comment_add(char **comments, int* length, char *tag, char *val);
-#endif
-
 /*                 
  Comments will be stored in the Vorbis style.            
  It is describled in the "Structure" section of
     http://www.xiph.org/ogg/vorbis/doc/v-comment.html
 
 The comment header is decoded as follows:
   1) [vendor_length] = read an unsigned integer of 32 bits
   2) [vendor_string] = read a UTF-8 vector as [vendor_length] octets
@@ -109,57 +127,16 @@ The comment header is decoded as follows
                            ((buf[base+1]<<8)&0xff00)| \
   	           	    (buf[base]&0xff))
 #define writeint(buf, base, val) do{ buf[base+3]=((val)>>24)&0xff; \
                                      buf[base+2]=((val)>>16)&0xff; \
                                      buf[base+1]=((val)>>8)&0xff; \
                                      buf[base]=(val)&0xff; \
                                  }while(0)
 
-#if 0
-static void
-comment_init(char **comments, int* length, char *vendor_string)
-{
-  int vendor_length=strlen(vendor_string);
-  int user_comment_list_length=0;
-  int len=4+vendor_length+4;
-  char *p=(char*)fs_malloc(len);
-  if(p==NULL){
-  }
-  writeint(p, 0, vendor_length);
-  memcpy(p+4, vendor_string, vendor_length);
-  writeint(p, 4+vendor_length, user_comment_list_length);
-  *length=len;
-  *comments=p;
-}
-
-static void
-comment_add(char **comments, int* length, char *tag, char *val)
-{
-  char* p=*comments;
-  int vendor_length=readint(p, 0);
-  int user_comment_list_length=readint(p, 4+vendor_length);
-  int tag_len=(tag?strlen(tag):0);
-  int val_len=strlen(val);
-  int len=(*length)+4+tag_len+val_len;
-
-  p=(char*)fs_realloc(p, len);
-  if(p==NULL){
-  }
-
-  writeint(p, *length, tag_len+val_len);      /* length of comment */
-  if(tag) memcpy(p+*length+4, tag, tag_len);  /* comment */
-  memcpy(p+*length+4+tag_len, val, val_len);  /* comment */
-  writeint(p, 4+vendor_length, user_comment_list_length+1);
-
-  *comments=p;
-  *length=len;
-}
-#endif
-
 static int
 fs_comment_validate_byname (const char * name, const char * value)
 {
   const char * c;
 
   if (!name || !value) return 0;
 
   for (c = name; *c; c++) {
@@ -177,20 +154,33 @@ fs_comment_validate_byname (const char *
 }
 
 static FishSoundComment *
 fs_comment_new (const char * name, const char * value)
 {
   FishSoundComment * comment;
 
   if (!fs_comment_validate_byname (name, value)) return NULL;
+  /* Ensures that name != NULL, value != NULL, and validates strings */
 
   comment = fs_malloc (sizeof (FishSoundComment));
+  if (comment == NULL) return NULL;
+
   comment->name = fs_strdup (name);
+  if (comment->name == NULL) {
+    fs_free (comment);
+    return NULL;
+  }
+
   comment->value = fs_strdup (value);
+  if (comment->value == NULL) {
+    fs_free (comment->name);
+    fs_free (comment);
+    return NULL;
+  }
 
   return comment;
 }
 
 static void
 fs_comment_free (FishSoundComment * comment)
 {
   if (!comment) return;
@@ -206,38 +196,39 @@ fs_comment_cmp (const FishSoundComment *
   if (!comment1 || !comment2) return 0;
 
   if (strcasecmp (comment1->name, comment2->name)) return 0;
   if (strcmp (comment1->value, comment2->value)) return 0;
 
   return 1;
 }
 
+int
+fish_sound_comment_set_vendor (FishSound * fsound, const char * vendor_string)
+{
+  if (fsound == NULL) return FISH_SOUND_ERR_BAD;
+
+  if (fsound->vendor) fs_free (fsound->vendor);
+
+  if ((fsound->vendor = fs_strdup (vendor_string)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  return 0;
+}
+
 /* Public API */
 
 const char *
 fish_sound_comment_get_vendor (FishSound * fsound)
 {
   if (fsound == NULL) return NULL;
 
   return fsound->vendor;
 }
 
-int
-fish_sound_comment_set_vendor (FishSound * fsound, const char * vendor_string)
-{
-  if (fsound == NULL) return FISH_SOUND_ERR_BAD;
-
-  if (fsound->vendor) fs_free (fsound->vendor);
-
-  fsound->vendor = fs_strdup (vendor_string);
-
-  return 0;
-}
-
 const FishSoundComment *
 fish_sound_comment_first (FishSound * fsound)
 {
   if (fsound == NULL) return NULL;
 
   return fs_vector_nth (fsound->comments, 0);
 }
 
@@ -306,21 +297,23 @@ fish_sound_comment_add (FishSound * fsou
 
   if (fsound->mode != FISH_SOUND_ENCODE)
     return FISH_SOUND_ERR_INVALID;
 
 #if FS_ENCODE
   if (!fs_comment_validate_byname (comment->name, comment->value))
     return FISH_SOUND_ERR_COMMENT_INVALID;
 
-  new_comment = fs_comment_new (comment->name, comment->value);
+  if ((new_comment = fs_comment_new (comment->name, comment->value)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
 
-  _fs_comment_add (fsound, new_comment);
+  if (_fs_comment_add (fsound, new_comment) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
 
-  return 0;
+  return FISH_SOUND_OK;
 #else
   return FISH_SOUND_ERR_DISABLED;
 #endif
 }
 
 int
 fish_sound_comment_add_byname (FishSound * fsound, const char * name,
 			       const char * value)
@@ -331,19 +324,23 @@ fish_sound_comment_add_byname (FishSound
 
   if (fsound->mode != FISH_SOUND_ENCODE)
     return FISH_SOUND_ERR_INVALID;
 
 #if FS_ENCODE
   if (!fs_comment_validate_byname (name, value))
     return FISH_SOUND_ERR_COMMENT_INVALID;
 
-  comment = fs_comment_new (name, value);
+  if ((comment = fs_comment_new (name, value)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
 
-  _fs_comment_add (fsound, comment);
+  if (_fs_comment_add (fsound, comment) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  return FISH_SOUND_OK;
 
   return 0;
 
 #else
   return FISH_SOUND_ERR_DISABLED;
 #endif
 }
 
@@ -424,168 +421,224 @@ fish_sound_comments_free (FishSound * fs
   return 0;
 }
 
 int
 fish_sound_comments_decode (FishSound * fsound, unsigned char * comments,
 			    long length)
 {
    char *c= (char *)comments;
-   int len, i, nb_fields, n;
+   int i, nb_fields, n;
+   size_t len;
    char *end;
    char * name, * value, * nvalue = NULL;
    FishSoundComment * comment;
    
    if (length<8)
       return -1;
 
    end = c+length;
    len=readint(c, 0);
+   if (len<0) return -1; 
 
    c+=4;
-   if (c+len>end) return -1;
+   if (len>end-c) return -1;
 
    /* Vendor */
-   nvalue = fs_strdup_len (c, len);
-   fish_sound_comment_set_vendor (fsound, nvalue);
-   if (nvalue) fs_free (nvalue);
+   if (len > 0) {
+     if ((nvalue = fs_strdup_len (c, len)) == NULL)
+       return FISH_SOUND_ERR_OUT_OF_MEMORY;
+     if (fish_sound_comment_set_vendor (fsound, nvalue) == FISH_SOUND_ERR_OUT_OF_MEMORY)
+       return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+     fs_free (nvalue);
+   }
 #ifdef DEBUG
    fwrite(c, 1, len, stderr); fputc ('\n', stderr);
 #endif
    c+=len;
 
    if (c+4>end) return -1;
 
+   /* This value gets checked effectively by the 'for' condition
+      and the checks within the loop for c running off the end.  */
    nb_fields=readint(c, 0);
 #ifdef DEBUG
    printf ("fish_sound_comments_decode: %d comments\n", nb_fields);
 #endif
 
    c+=4;
    for (i=0;i<nb_fields;i++)
    {
       if (c+4>end) return -1;
 
       len=readint(c, 0);
 #ifdef DEBUG
       printf ("fish_sound_comments_decode: [%d] len %d\n", i, len);
 #endif
+      if (len<0) return -1;
 
       c+=4;
-      if (c+len>end) return -1;
+      if (len>end-c) return -1;
 
       name = c;
       value = fs_index_len (c, '=', len);
       if (value) {
 	*value = '\0';
 	value++;
 
 	n = c+len - value;
-	nvalue = fs_strdup_len (value, n);
+	if ((nvalue = fs_strdup_len (value, n)) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
 #ifdef DEBUG
 	printf ("fish_sound_comments_decode: %s -> %s (length %d)\n",
 		name, nvalue, n);
 #endif
-	comment = fs_comment_new (name, nvalue);
-	_fs_comment_add (fsound, comment);
+	if ((comment = fs_comment_new (name, nvalue)) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+	if (_fs_comment_add (fsound, comment) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
 	fs_free (nvalue);
       } else {
 #ifdef DEBUG
         printf ("fish_sound_comments_decode: [%d] %s (no value)\n",
                 i, name, len);
 #endif
-	nvalue = fs_strdup_len (name, len);
-	comment = fs_comment_new (nvalue, NULL);
-	_fs_comment_add (fsound, comment);
+	if ((nvalue = fs_strdup_len (name, len)) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+	if ((comment = fs_comment_new (nvalue, NULL)) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+	if (_fs_comment_add (fsound, comment) == NULL)
+          return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
 	fs_free (nvalue);
       }
 
       c+=len;
    }
 
 #ifdef DEBUG
    printf ("fish_sound_comments_decode: done\n");
 #endif
 
-   return 0;
+   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",
 	    comment->name, comment->value);
 #endif
 
     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;
   if (remaining <= 0) return actual_length;
   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;
   writeint (c, 0, nb_fields);
   c += 4;
 
   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;
 
     if (comment->value) {
       remaining --;
       if (remaining <= 0) return actual_length;
       *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;
     }
   }
 
   if (remaining <= 0) return actual_length;
   *c = 0x01;
--- a/media/libfishsound/src/libfishsound/fishsound_decode.c
+++ b/media/libfishsound/src/libfishsound/fishsound_decode.c
@@ -53,17 +53,17 @@ fs_decode_update (FishSound * fsound, in
 }
 
 int fish_sound_set_decoded_float (FishSound * fsound,
 				  FishSoundDecoded_Float decoded,
 				  void * user_data)
 {
   int ret = 0;
 
-  if (fsound == NULL) return -1;
+  if (fsound == NULL) return FISH_SOUND_ERR_BAD;
 
 #if FS_DECODE
   ret = fs_decode_update (fsound, 0);
 
   if (ret >= 0) {
     fsound->callback.decoded_float = decoded;
     fsound->user_data = user_data;
   }
@@ -75,17 +75,17 @@ int fish_sound_set_decoded_float (FishSo
 }
 
 int fish_sound_set_decoded_float_ilv (FishSound * fsound,
 				      FishSoundDecoded_FloatIlv decoded,
 				      void * user_data)
 {
   int ret = 0;
 
-  if (fsound == NULL) return -1;
+  if (fsound == NULL) return FISH_SOUND_ERR_BAD;
 
 #if FS_DECODE
   ret = fs_decode_update (fsound, 1);
 
   if (ret >= 0) {
     fsound->callback.decoded_float_ilv = decoded;
     fsound->user_data = user_data;
   }
@@ -96,17 +96,17 @@ int fish_sound_set_decoded_float_ilv (Fi
   return ret;
 }
 
 long
 fish_sound_decode (FishSound * fsound, unsigned char * buf, long bytes)
 {
   int format;
 
-  if (fsound == NULL) return -1;
+  if (fsound == NULL) return FISH_SOUND_ERR_BAD;
 
 #if FS_DECODE
   if (fsound->info.format == FISH_SOUND_UNKNOWN) {
     format = fish_sound_identify (buf, bytes);
     if (format == FISH_SOUND_UNKNOWN) return -1;
 
     fish_sound_set_format (fsound, format);
   }
--- a/media/libfishsound/src/libfishsound/fishsound_flac.c
+++ b/media/libfishsound/src/libfishsound/fishsound_flac.c
@@ -136,16 +136,17 @@ static FLAC__StreamDecoderWriteStatus
 fs_flac_write_callback(const FLAC__StreamDecoder *decoder,
                        const FLAC__Frame *frame,
                        const FLAC__int32 * const buffer[],
                        void *client_data)
 {
   FishSound* fsound = (FishSound*)client_data;
   FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data;
   int i, j, channels, blocksize, offset;
+  float * ipcm;
 
   channels = frame->header.channels;
   blocksize = frame->header.blocksize;
 
 #ifdef DEBUG_VERBOSE
   printf("fs_flac_write_callback: IN, blocksize %d\n", blocksize);
 #endif
 
@@ -153,32 +154,37 @@ fs_flac_write_callback(const FLAC__Strea
 
   if (fsound->callback.decoded_float) {
     float norm = 1.0 / ((1 << (frame->header.bits_per_sample - 1)));
 
     if (fsound->interleave) {
 	FishSoundDecoded_FloatIlv dfi;
 	float* retpcm;
 
-	fi->ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize);
+        if ((ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize)) == NULL)
+          return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+
+	fi->ipcm = ipcm;
 	retpcm = (float*) fi->ipcm;
 	for (i = 0; i < blocksize; i++) {
 	  offset = i * channels;
 	  for (j = 0; j < channels; j++)
 	    retpcm[offset + j] = buffer[j][i] * norm;
 	}
 	dfi = (FishSoundDecoded_FloatIlv)fsound->callback.decoded_float_ilv;
 	dfi (fsound, (float **)retpcm, blocksize, fsound->user_data);
       } else {
 	FishSoundDecoded_Float df;
         FLAC__int32 * s = (FLAC__int32 *)buffer; /* de-interleave source */
 	float *d; /* de-interleave dest */
 
         for (j = 0; j < channels; j++) {
-	  fi->pcm_out[j] = realloc(fi->pcm_out[j], sizeof(float) * blocksize);
+          if ((ipcm = realloc(fi->pcm_out[j], sizeof(float) * blocksize)) == NULL)
+            return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+	  fi->pcm_out[j] = ipcm;
         }
 	for (i = 0; i < blocksize; i++)
 	  for (j = 0; j < channels; j++) {
 	    d = fi->pcm_out[j];
 	    d[i] = s[i*channels + j] * norm;
 	  }
       	df = (FishSoundDecoded_Float)fsound->callback.decoded_float;
 	df (fsound, fi->pcm_out, blocksize, fsound->user_data);
@@ -226,16 +232,18 @@ fs_flac_error_callback(const FLAC__Strea
   fprintf(stderr, "FLAC ERROR: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
 }
 #endif
 #if FS_DECODE
 static void*
 fs_flac_decode_header (FishSound * fsound, unsigned char *buf, long bytes)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
+
+  if (bytes < 9) return NULL;
   if (buf[0] != 0x7f) return NULL;
   if (strncmp((char *)buf+1, "FLAC", 4) != 0) return NULL;
   fi->version.major = buf[5];
   fi->version.minor = buf[6];
 #ifdef DEBUG
   printf("fs_flac_decode_header : Flac Ogg Mapping Version: %d.%d\n",
          fi->version.major, fi->version.minor);
 #endif
@@ -247,24 +255,40 @@ fs_flac_decode_header (FishSound * fsoun
 
   if ((fi->fsd = FLAC__stream_decoder_new()) == NULL) {
 #ifdef DEBUG
     printf ("fs_flac_decode_header: unable to create new stream_decoder\n");
 #endif
     return NULL;
   }
 
+#if defined (HAVE_FLAC_1_1_2)
   FLAC__stream_decoder_set_read_callback(fi->fsd, fs_flac_read_callback);
   FLAC__stream_decoder_set_write_callback(fi->fsd, fs_flac_write_callback);
   FLAC__stream_decoder_set_metadata_callback(fi->fsd, fs_flac_meta_callback);
   FLAC__stream_decoder_set_error_callback(fi->fsd, fs_flac_error_callback);
   FLAC__stream_decoder_set_client_data(fi->fsd, fsound);
 
   if (FLAC__stream_decoder_init(fi->fsd) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
     return NULL;
+#elif defined (HAVE_FLAC_1_1_3)
+  if (FLAC__stream_decoder_init_stream
+      (fi->fsd,
+       fs_flac_read_callback,
+       NULL, /* seek callback */
+       NULL, /* tell callback */
+       NULL, /* length callback */
+       NULL, /* EOF callback */
+       fs_flac_write_callback,
+       fs_flac_meta_callback,
+       fs_flac_error_callback,
+       fsound
+       ) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
+     return NULL;
+#endif
 
   return fi->fsd;
 }
 
 static long
 fs_flac_decode (FishSound * fsound, unsigned char * buf, long bytes)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
@@ -275,56 +299,76 @@ fs_flac_decode (FishSound * fsound, unsi
 
   if (fi->packetno == 0) {
     if (fs_flac_decode_header (fsound, buf, bytes) == NULL) {
 #ifdef DEBUG
       printf("fs_flac_decode: Error reading header\n");
 #endif
       return -1;
     }
-    fi->buffer = fs_malloc(sizeof(unsigned char)*bytes);
+    if ((fi->buffer = fs_malloc(sizeof(unsigned char)*bytes)) == NULL)
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
     memcpy(fi->buffer, buf+9, bytes-9);
     fi->bufferlength = bytes-9;
   }
   else if (fi->packetno <= fi->header_packets){
-    unsigned char* tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes));
+    unsigned char* tmp;
 #ifdef DEBUG
     printf("fs_flac_decode: handling header (fi->header_packets = %d)\n",
            fi->header_packets);
 #endif
 
 #if 0
     if (fi->packetno ==  1) fish_sound_comments_decode (fsound, buf, bytes);
 #endif
 
     if ((buf[0] & 0x7) == 4) {
       int len = (buf[1]<<16) + (buf[2]<<8) + buf[3];
 #ifdef DEBUG
       printf ("fs_flac_decode: got vorbiscomments len %d\n", len);
 #endif
-      fish_sound_comments_decode (fsound, buf+4, len);
+      if (fish_sound_comments_decode (fsound, buf+4, len) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
+        fi->packetno++;
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
     }
 
+    if ((tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes))) == NULL)
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
     memcpy(tmp, fi->buffer, fi->bufferlength);
     memcpy(tmp+fi->bufferlength, buf, bytes);
     fi->bufferlength += bytes;
     fs_free(fi->buffer);
     fi->buffer = tmp;
     if (fi->packetno == fi->header_packets) {
-      FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
+      if (FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd) == false) {
+        goto dec_err;
+      }
       fs_free(fi->buffer);
     }
   } else {
     fi->buffer = buf;
     fi->bufferlength = bytes;
-    FLAC__stream_decoder_process_single(fi->fsd);
+    if (FLAC__stream_decoder_process_single(fi->fsd) == false) {
+      goto dec_err;
+    }
   }
   fi->packetno++;
 
   return 0;
+
+dec_err:
+    switch (FLAC__stream_decoder_get_state(fi->fsd)) {
+    case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+    default:
+      return FISH_SOUND_ERR_GENERIC;
+    }
 }
 #else /* !FS_DECODE */
 
 #define fs_flac_decode NULL
 
 #endif
 
 
@@ -348,17 +392,19 @@ fs_flac_enc_write_callback(const FLAC__S
         /* libFLAC has called us with data containing the normal fLaC header
          * and a STREAMINFO block. Prepend the FLAC Ogg mapping header,
          * as described in http://flac.sourceforge.net/ogg_mapping.html.
          */
 #ifdef DEBUG
         printf("fs_flac_enc_write_callback: generating FLAC header packet: "
                "%c%c%c%c\n", buffer[0], buffer[1], buffer[2], buffer[3]);
 #endif
-	fi->buffer = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+9));
+	if ((fi->buffer = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+9))) == NULL)
+          return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+
 	fi->buffer[0] = 0x7f;
 	fi->buffer[1] = 0x46; /* 'F' */
 	fi->buffer[2] = 0x4c; /* 'L' */
 	fi->buffer[3] = 0x41; /* 'A' */
 	fi->buffer[4] = 0x43; /* 'C' */
 	fi->buffer[5] = 1;    /* Version major generated by this file */
 	fi->buffer[6] = 0;    /* Version minor generated by this file */
 	fi->buffer[7] = 0;    /* MSB(be): Nr. other non-audio header packets */
@@ -366,17 +412,21 @@ fs_flac_enc_write_callback(const FLAC__S
 	memcpy (fi->buffer+9, buffer, bytes); /* fLaC header ++ STREAMINFO */
         fi->bufferlength = bytes+9;
 
 	fi->header++;
       } else {
         /* Make a temporary copy of the metadata header to pass to the user
          * callback.
          */
-	unsigned char* tmp = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+fi->bufferlength));
+	unsigned char* tmp;
+
+        if ((tmp = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+fi->bufferlength))) == NULL)
+          return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+
 	memcpy (tmp, fi->buffer, fi->bufferlength);
 	memcpy (tmp+fi->bufferlength, buffer, bytes);
 	fs_free(fi->buffer);
 	fi->buffer = tmp;
 	fi->bufferlength += bytes;
 	fi->header++;
 	encoded (fsound, (unsigned char *)fi->buffer, (long)fi->bufferlength,
 		 fsound->user_data);
@@ -457,17 +507,18 @@ fs_flac_encode_vcentry (const FishSoundC
   name_len = strlen(comment->name);
   length = name_len + 1;
 
   if (comment->value) {
     value_len = strlen (comment->value);
     length += value_len + 1;
   }
 
-  entry = fs_malloc (length);
+  if ((entry = fs_malloc (length)) == NULL)
+    return NULL;
 
   /* We assume that comment->name, value are NUL terminated, as they were
    * produced by our own comments.c */
   strcpy ((char *)entry, comment->name);
 
   if (comment->value) {
     entry[name_len] = '=';
     strcpy ((char *)&entry[name_len+1], comment->value);
@@ -477,17 +528,17 @@ fs_flac_encode_vcentry (const FishSoundC
 
   return entry;
 }
 
 static FLAC__StreamMetadata *
 fs_flac_encode_vorbiscomments (FishSound * fsound)
 {
   FishSoundFlacInfo * fi = fsound->codec_data;
-  FLAC__StreamMetadata * metadata;
+  FLAC__StreamMetadata * metadata = NULL;
   const FishSoundComment * comment;
   unsigned int i=0, length=0, total_length;
   FLAC__VCEntry * comments;
 
   /* libFLAC seems to require us to know the total length of the generated
    * vorbiscomment packet, even though it will silently generate the
    * vendor string. Hence, this value was determined by inspection for
    * the version "reference libFLAC 1.1.2"
@@ -497,123 +548,193 @@ fs_flac_encode_vorbiscomments (FishSound
   /* Count the number of comments */
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
     length++;
   }
 
   if (length == 0) return NULL;
 
-  comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length);
+  if ((comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length)) == NULL)
+    goto encode_vc_oom;
   
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
-    comments[i].entry = fs_flac_encode_vcentry (comment);
+    if ((comments[i].entry = fs_flac_encode_vcentry (comment)) == NULL) {
+    }
     comments[i].length = strlen((char *)comments[i].entry);
 
     /* In the generated vorbiscomment data, each entry is preceded by a
      * 32bit length specifier. */
     total_length += 4 + comments[i].length;
     i++;
   }
 
-  metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata));
+  if ((metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata))) == NULL)
+    goto encode_vc_oom;
+
   metadata->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
   metadata->is_last = true;
   metadata->length = total_length;
   /* Don't bother setting the vendor_string, as libFLAC ignores it */
   metadata->data.vorbis_comment.num_comments = length;
   metadata->data.vorbis_comment.comments = comments;
 
   /* Remember the allocated metadata */
   fi->enc_vc_metadata = metadata;
 
   return metadata;
+
+encode_vc_oom:
+  if (metadata != NULL)
+    fs_free (metadata);
+
+  /* Unwind allocated comment entries */
+  for (i--; i >= 0; i--) {
+    if (comments[i].entry != NULL)
+      fs_free (comments[i].entry);
+  }
+
+  if (comments != NULL)
+    fs_free (comments);
+
+  return NULL;
 }
 
 static FishSound *
 fs_flac_enc_headers (FishSound * fsound)
 {
   FishSoundFlacInfo * fi = fsound->codec_data;
   FLAC__StreamMetadata * metadata;
 
   fi->fse = FLAC__stream_encoder_new();
   FLAC__stream_encoder_set_channels(fi->fse, fsound->info.channels);
   FLAC__stream_encoder_set_sample_rate(fi->fse, fsound->info.samplerate);
   FLAC__stream_encoder_set_bits_per_sample(fi->fse, BITS_PER_SAMPLE);
+
+#if defined (HAVE_FLAC_1_1_2)
   FLAC__stream_encoder_set_write_callback(fi->fse, fs_flac_enc_write_callback);
   FLAC__stream_encoder_set_metadata_callback(fi->fse, fs_flac_enc_meta_callback);
   FLAC__stream_encoder_set_client_data(fi->fse, fsound);
+#endif
 
   metadata = fs_flac_encode_vorbiscomments (fsound);
   if (metadata != NULL)
     FLAC__stream_encoder_set_metadata (fi->fse, &metadata, 1);
 
   /* FLAC__stream_encoder_set_total_samples_estimate(fi->fse, ...);*/
+
+#if defined (HAVE_FLAC_1_1_2)
   if (FLAC__stream_encoder_init(fi->fse) != FLAC__STREAM_ENCODER_OK)
     return NULL;
+#elif defined (HAVE_FLAC_1_1_3)
+  if (FLAC__stream_encoder_init_stream
+      (fi->fse,
+       fs_flac_enc_write_callback,
+       NULL, /* seek callback */
+       NULL, /* tell callback */
+       fs_flac_enc_meta_callback,
+       fsound
+       ) != FLAC__STREAM_ENCODER_OK)
+     return NULL;
+
+#endif
 
   return fsound;
 }
 
 static long
+fs_flac_encode_fatal (FishSoundFlacInfo *fi, long err)
+{
+  FLAC__stream_encoder_delete (fi->fse);
+  fi->fse = NULL;
+  return err;
+}
+
+static long
 fs_flac_encode_f (FishSound * fsound, float * pcm[], long frames)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
-  FLAC__int32 *buffer;
+  FLAC__int32 *buffer, *ipcm;
   float * p, norm = (1 << (BITS_PER_SAMPLE - 1));
   long i;
   int j, channels = fsound->info.channels;
 
 #ifdef DEBUG
   printf("fs_flac_encode_f: IN, frames = %ld\n", frames);
 #endif
 
-  fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames);
+  if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  fi->ipcm = ipcm;
   buffer = (FLAC__int32*) fi->ipcm;
   for (i = 0; i < frames; i++) {
     for (j = 0; j < channels; j++) {
       p = pcm[j];
       buffer[i*channels + j] = (FLAC__int32) (p[i] * norm);
     }
   }
 
   if (fi->packetno == 0)
     fs_flac_enc_headers (fsound);
 
   /* We could have used FLAC__stream_encoder_process() and a more direct
    * conversion loop above, rather than converting and interleaving. */
-  FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
+  if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
+    switch (FLAC__stream_encoder_get_state (fi->fse)) {
+    case FLAC__STREAM_ENCODER_OK:
+    case FLAC__STREAM_ENCODER_UNINITIALIZED:
+      break;
+    case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
+    default:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
+    }
+  }
 
   fi->packetno++;
 
   return frames;
 }
 
 static long
 fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
-  FLAC__int32 *buffer;
+  FLAC__int32 *buffer, *ipcm;
   float * p = (float*)pcm, norm = (1 << (BITS_PER_SAMPLE - 1));
   long i, length = frames * fsound->info.channels;
 
 #ifdef DEBUG
   printf("fs_flac_encode_f_ilv: IN, frames = %ld\n", frames);
 #endif
 
-  fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames);
+  if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  fi->ipcm = ipcm;
   buffer = (FLAC__int32*) fi->ipcm;
   for (i=0; i<length; i++)
     buffer[i] = p[i] * norm;
 
   if (fi->packetno == 0)
     fs_flac_enc_headers (fsound);
 
-  FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
+  if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
+    switch (FLAC__stream_encoder_get_state (fi->fse)) {
+    case FLAC__STREAM_ENCODER_OK:
+    case FLAC__STREAM_ENCODER_UNINITIALIZED:
+      break;
+    case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
+    default:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
+    }
+  }
 
   fi->packetno++;
 
   return frames;
 }
 #else /* ! FS_ENCODE */
 
 #define fs_flac_encode_f NULL
@@ -733,16 +854,17 @@ fs_flac_init (FishSound * fsound)
 }
 
 FishSoundCodec *
 fish_sound_flac_codec (void)
 {
   FishSoundCodec * codec;
 
   codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
+  if (codec == NULL) return NULL;
 
   codec->format.format = FISH_SOUND_FLAC;
   codec->format.name = "Flac (Xiph.Org)";
   codec->format.extension = "ogg";
 
   codec->init = fs_flac_init;
   codec->del = fs_flac_delete;
   codec->reset = fs_flac_reset;
--- a/media/libfishsound/src/libfishsound/fishsound_speex.c
+++ b/media/libfishsound/src/libfishsound/fishsound_speex.c
@@ -31,16 +31,20 @@
 */
 
 #include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
 #include <ctype.h>
 
 #include "private.h"
 #include "convert.h"
 
 /*#define DEBUG*/
 
 #if HAVE_SPEEX
@@ -127,69 +131,56 @@ process_header(unsigned char * buf, long
   void *st;
   SpeexMode *mode;
   SpeexHeader *header;
   int modeID;
   SpeexCallback callback;
 
   header = speex_packet_to_header((char*)buf, (int)bytes);
   if (!header) {
-    /*info_dialog_new ("Speex error", NULL, "Speex: cannot read header");*/
+    /* cannot read header */
     return NULL;
   }
 
   if (header->mode >= SPEEX_NB_MODES || header->mode < 0) {
-    /*
-    info_dialog_new ("Speex error", NULL,
-		     "Mode number %d does not (any longer) exist in this version\n",
-		     header->mode);
-    */
+    /* Mode number does not (any longer) exist in this version */
     return NULL;
   }
 
   modeID = header->mode;
   if (forceMode!=-1)
     modeID = forceMode;
+
+#if HAVE_SPEEX_LIB_GET_MODE
+  mode = (SpeexMode *) speex_lib_get_mode (modeID);
+#else
   /* speex_mode_list[] is declared const in speex 1.1.x, hence the cast */
   mode = (SpeexMode *)speex_mode_list[modeID];
+#endif
 
   if (header->speex_version_id > 1) {
-    /*
-    info_dialog_new ("Speex error", NULL,
-		     "This file was encoded with Speex bit-stream version %d, "
-		     "which I don't know how to decode\n",
-		     header->speex_version_id);
-    */
+    /* Unknown bitstream version */
     return NULL;
   }
 
   if (mode->bitstream_version < header->mode_bitstream_version) {
-    /*
-    info_dialog_new ("Speex error", NULL,
-		     "The file was encoded with a newer version of Speex. "
-		     "You need to upgrade in order to play it.\n");
-    */
+    /* The file was encoded with a newer version of Speex,
+     * need to upgrade in order to play it */
     return NULL;
   }
 
   if (mode->bitstream_version > header->mode_bitstream_version) {
-    /*
-    info_dialog_new ("Speex error", NULL,
-		     "The file was encoded with an older version of Speex. "
-		     "You would need to downgrade the version in order to play it.\n");
-    */
+    /* The file was encoded with an older version of Speex.
+     * You would need to downgrade the version in order to play it */
     return NULL;
   }
 
   st = speex_decoder_init(mode);
   if (!st) {
-    /*
-      info_dialog_new ("Speex error", NULL,
-      "Decoder initialization failed.\n");
-    */
+    /* Decoder initialization failed */
     return NULL;
   }
 
   speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
   speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
 
   if (!(*channels==1))
     {
@@ -287,40 +278,71 @@ fs_speex_decode (FishSound * fsound, uns
   if (fss->packetno == 0) {
     fss->st = process_header (buf, bytes, enh_enabled,
 			      &fss->frame_size, &rate,
 			      &fss->nframes, forceMode, &channels,
 			      &fss->stereo,
 			      &fss->extra_headers);
 
     if (fss->st == NULL) {
-      /* XXX: error */
+      /* TODO: Return more specific error identifiers for invalid header fields */
+      return FISH_SOUND_ERR_GENERIC;
     }
 
 #ifdef DEBUG
     printf ("speex: got %d channels, %d Hz\n", channels, rate);
 #endif
 
     fsound->info.samplerate = rate;
     fsound->info.channels = channels;
 
+    /* Sanity check the channels value, as we will use it to determine buffer
+       sizes below.
+     */
+    if (channels < 1 || channels > 2)
+      return FISH_SOUND_ERR_GENERIC;
+
+#if HAVE_UINTPTR_T
+    /* Sanity check: frame_size is not so large that the buffer size calculations
+     * would wrap. In reality, frame_size is set by libspeex according to the
+     * mode index specified in the file header, and is usually equal to 320.
+     */
+    if (fss->frame_size > UINTPTR_MAX / (sizeof(float) * channels))
+      return FISH_SOUND_ERR_GENERIC;
+#endif
+
     fss->ipcm = fs_malloc (sizeof (float) * fss->frame_size * channels);
+    if (fss->ipcm == NULL) {
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+    }
 
     if (channels == 1) {
       fss->pcm[0] = fss->ipcm;
     } else if (channels == 2) {
       fss->pcm[0] = fs_malloc (sizeof (float) * fss->frame_size);
+      if (fss->pcm[0] == NULL) {
+        fs_free (fss->ipcm);
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
       fss->pcm[1] = fs_malloc (sizeof (float) * fss->frame_size);
+      if (fss->pcm[1] == NULL) {
+        fs_free (fss->pcm[0]);
+        fs_free (fss->ipcm);
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
     }
 
     if (fss->nframes == 0) fss->nframes = 1;
 
   } else if (fss->packetno == 1) {
     /* Comments */
-    fish_sound_comments_decode (fsound, buf, bytes);
+    if (fish_sound_comments_decode (fsound, buf, bytes) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
+      fss->packetno++;
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+    }
   } else if (fss->packetno <= 1+fss->extra_headers) {
     /* Unknown extra headers */
   } else {
     speex_bits_read_from (&fss->bits, (char *)buf, (int)bytes);
 
     for (i = 0; i < fss->nframes; i++) {
       /* Decode frame */
       speex_decode (fss->st, &fss->bits, fss->ipcm);
@@ -358,69 +380,98 @@ fs_speex_decode (FishSound * fsound, uns
 #endif
 
 
 #if FS_ENCODE
 static FishSound *
 fs_speex_enc_headers (FishSound * fsound)
 {
   FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
+  int modeID;
   SpeexMode * mode = NULL;
   SpeexHeader header;
-  unsigned char * buf;
-  int bytes;
+  unsigned char * header_buf = NULL, * comments_buf = NULL;
+  int header_bytes, comments_bytes;
   size_t buflen;
 
-  /* XXX: set wb, nb, uwb modes */
-  /* These modes are declared const in speex 1.1.x, hence the explicit cast */
-  mode = (SpeexMode *)&speex_wb_mode;
+  modeID = 1;
+
+#if HAVE_SPEEX_LIB_GET_MODE
+  mode = (SpeexMode *) speex_lib_get_mode (modeID);
+#else
+  /* speex_mode_list[] is declared const in speex 1.1.x, hence the cast */
+  mode = (SpeexMode *)speex_mode_list[modeID];
+#endif
 
   speex_init_header (&header, fsound->info.samplerate, 1, mode);
   header.frames_per_packet = fss->nframes; /* XXX: frames per packet */
   header.vbr = 1; /* XXX: VBR */
   header.nb_channels = fsound->info.channels;
 
   fss->st = speex_encoder_init (mode);
 
   if (fsound->callback.encoded) {
-    FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback.encoded;
     char vendor_string[128];
 
-    /* header */
-    buf = (unsigned char *) speex_header_to_packet (&header, &bytes);
-    encoded (fsound, buf, (long)bytes, fsound->user_data);
-    fss->packetno++;
-    fs_free (buf);
+    /* Allocate and create header */
+    header_buf = (unsigned char *) speex_header_to_packet (&header, &header_bytes);
+    if (header_buf == NULL) {
+      return NULL;
+    }
 
-    /* comments */
+    /* Allocate and create comments */
     snprintf (vendor_string, 128, VENDOR_FORMAT, header.speex_version);
-    fish_sound_comment_set_vendor (fsound, vendor_string);
-    bytes = fish_sound_comments_encode (fsound, NULL, 0);
-    buf = fs_malloc (bytes);
-    bytes = fish_sound_comments_encode (fsound, buf, bytes);
-    encoded (fsound, buf, (long)bytes, fsound->user_data);
-    fss->packetno++;
-    fs_free (buf);
+    if (fish_sound_comment_set_vendor (fsound, vendor_string) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
+      fs_free (header_buf);
+      return NULL;
+    }
+    comments_bytes = fish_sound_comments_encode (fsound, NULL, 0);
+    comments_buf = fs_malloc (comments_bytes);
+    if (comments_buf == NULL) {
+      fs_free (header_buf);
+      return NULL;
+    }
   }
 
   speex_encoder_ctl (fss->st, SPEEX_SET_SAMPLING_RATE,
 		     &fsound->info.samplerate);
 
   speex_encoder_ctl (fss->st, SPEEX_GET_FRAME_SIZE, &fss->frame_size);
 
 #ifdef DEBUG
   printf ("got frame size %d\n", fss->frame_size);
 #endif
 
-  /* XXX: blah blah blah ... set VBR etc. */
+  /* XXX: set VBR etc. */
 
   buflen = fss->frame_size * fsound->info.channels * sizeof (float);
   fss->ipcm = fs_malloc (buflen);
+  if (fss->ipcm == NULL) {
+    if (comments_buf) fs_free (comments_buf);
+    if (header_buf) fs_free (header_buf);
+    return NULL;
+  }
   memset (fss->ipcm, 0, buflen);
 
+  /* Allocations succeeded, actually call encoded callback for headers */
+  if (fsound->callback.encoded) {
+    FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback.encoded;
+
+    /* header */
+    encoded (fsound, header_buf, (long)header_bytes, fsound->user_data);
+    fss->packetno++;
+    fs_free (header_buf);
+
+    /* comments */
+    comments_bytes = fish_sound_comments_encode (fsound, comments_buf, comments_bytes);
+    encoded (fsound, comments_buf, (long)comments_bytes, fsound->user_data);
+    fss->packetno++;
+    fs_free (comments_buf);
+  }
+
   return fsound;
 }
 
 static long
 fs_speex_encode_write (FishSound * fsound)
 {
   FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
   FishSoundSpeexEnc * fse = (FishSoundSpeexEnc *)fss->enc;
@@ -588,36 +639,59 @@ fs_speex_reset (FishSound * fsound)
   return 0;
 }
 
 static int
 fs_speex_update (FishSound * fsound, int interleave)
 {
   FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
   size_t pcm_size = sizeof (float);
+  float *ipcm_new, *pcm0, *pcm1;
 
-  fss->ipcm = (float *)
-    fs_realloc (fss->ipcm,
-		pcm_size * fss->frame_size * fsound->info.channels);
+  ipcm_new = (float *)fs_realloc (fss->ipcm,
+		  pcm_size * fss->frame_size * fsound->info.channels);
+  if (ipcm_new == NULL) return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  fss->ipcm = ipcm_new;
 
   if (interleave) {
     /* if transitioning from non-interleave to interleave,
        free non-ilv buffers */
     if (!fsound->interleave && fsound->info.channels == 2) {
       if (fss->pcm[0]) fs_free (fss->pcm[0]);
       if (fss->pcm[1]) fs_free (fss->pcm[1]);
       fss->pcm[0] = NULL;
       fss->pcm[1] = NULL;
     }
   } else {
     if (fsound->info.channels == 1) {
       fss->pcm[0] = (float *) fss->ipcm;
     } else if (fsound->info.channels == 2) {
-      fss->pcm[0] = fs_realloc (fss->pcm[0], pcm_size * fss->frame_size);
-      fss->pcm[1] = fs_realloc (fss->pcm[1], pcm_size * fss->frame_size);
+#if HAVE_UINTPTR_T
+      /* Sanity check: frame_size is not so large that the buffer size calculations
+       * would wrap. In reality, frame_size is set by libspeex according to the
+       * mode index specified in the file header, and is usually equal to 320.
+       */
+      if (fss->frame_size > UINTPTR_MAX / pcm_size)
+        return FISH_SOUND_ERR_GENERIC;
+#endif
+
+      pcm0 = fs_realloc (fss->pcm[0], pcm_size * fss->frame_size);
+      if (pcm0 == NULL) {
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
+
+      pcm1 = fs_realloc (fss->pcm[1], pcm_size * fss->frame_size);
+      if (pcm1 == NULL) {
+        fs_free (pcm0);
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
+
+      fss->pcm[0] = pcm0;
+      fss->pcm[1] = pcm1;
     }
   }
 
   return 0;
 }
 
 static FishSound *
 fs_speex_enc_init (FishSound * fsound)
@@ -689,16 +763,17 @@ fs_speex_delete (FishSound * fsound)
 }
 
 FishSoundCodec *
 fish_sound_speex_codec (void)
 {
   FishSoundCodec * codec;
 
   codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
+  if (codec == NULL) return NULL;
 
   codec->format.format = FISH_SOUND_SPEEX;
   codec->format.name = "Speex (Xiph.Org)";
   codec->format.extension = "spx";
 
   codec->init = fs_speex_init;
   codec->del = fs_speex_delete;
   codec->reset = fs_speex_reset;
--- a/media/libfishsound/src/libfishsound/fishsound_vorbis.c
+++ b/media/libfishsound/src/libfishsound/fishsound_vorbis.c
@@ -110,16 +110,17 @@ fs_vorbis_command (FishSound * fsound, i
 
 #if FS_DECODE
 static long
 fs_vorbis_decode (FishSound * fsound, unsigned char * buf, long bytes)
 {
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
   ogg_packet op;
   long samples;
+  float * pcm_new;
   int ret;
 
   /* Make an ogg_packet structure to pass the data to libvorbis */
   op.packet = buf;
   op.bytes = bytes;
   op.b_o_s = (fsv->packetno == 0) ? 1 : 0;
   op.e_o_s = fsound->next_eos;
   op.granulepos = fsound->next_granulepos;
@@ -137,17 +138,20 @@ fs_vorbis_decode (FishSound * fsound, un
 	fsound->info.channels = fsv->vi.channels;
       }
     }
 
     /* Decode comments from packet 1. Vorbis has 7 bytes of marker at the
      * start of vorbiscomment packet. */
     if (fsv->packetno == 1 && bytes > 7 && buf[0] == 0x03 &&
 	!strncmp ((char *)&buf[1], "vorbis", 6)) {
-      fish_sound_comments_decode (fsound, buf+7, bytes-7);
+      if (fish_sound_comments_decode (fsound, buf+7, bytes-7) == FISH_SOUND_ERR_OUT_OF_MEMORY) {
+        fsv->packetno++;
+        return FISH_SOUND_ERR_OUT_OF_MEMORY;
+      }
     } else if (fsv->packetno == 2) {
       vorbis_synthesis_init (&fsv->vd, &fsv->vi);
       vorbis_block_init (&fsv->vd, &fsv->vb);
     }
   } else {
     FishSoundDecoded_FloatIlv df;
     FishSoundDecoded_Float dfi;
 
@@ -157,19 +161,25 @@ fs_vorbis_decode (FishSound * fsound, un
     while ((samples = vorbis_synthesis_pcmout (&fsv->vd, &fsv->pcm)) > 0) {
       vorbis_synthesis_read (&fsv->vd, samples);
 
       if (fsound->frameno != -1)
 	fsound->frameno += samples;
 
       if (fsound->interleave) {
 	if (samples > fsv->max_pcm) {
-	  fsv->ipcm = realloc (fsv->ipcm, sizeof(float) * samples *
-			       fsound->info.channels);
-	  fsv->max_pcm = samples;
+          pcm_new = realloc (fsv->ipcm, sizeof(float) * samples *
+			     fsound->info.channels);
+          if (pcm_new == NULL) {
+            /* Allocation failure; just truncate here, fail gracefully elsewhere */
+            samples = fsv->max_pcm;
+          } else {
+	    fsv->ipcm = pcm_new;
+	    fsv->max_pcm = samples;
+          }
 	}
 	_fs_interleave (fsv->pcm, (float **)fsv->ipcm, samples,
 			fsound->info.channels, 1.0);
 
 	dfi = (FishSoundDecoded_FloatIlv)fsound->callback.decoded_float_ilv;
 	dfi (fsound, (float **)fsv->ipcm, samples, fsound->user_data);
       } else {
 	df = (FishSoundDecoded_Float)fsound->callback.decoded_float;
@@ -199,22 +209,24 @@ static FishSound *
 fs_vorbis_enc_headers (FishSound * fsound)
 {
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
   const FishSoundComment * comment;
   ogg_packet header;
   ogg_packet header_comm;
   ogg_packet header_code;
 
-  /* Vorbis streams begin with three headers; the initial header (with
-     most of the codec setup parameters) which is mandated by the Ogg
-     bitstream spec.  The second header holds any comment fields.  The
-     third header holds the bitstream codebook.  We merely need to
-     make the headers, then pass them to libvorbis one at a time;
-     libvorbis handles the additional Ogg bitstream constraints */
+  /* Vorbis streams begin with three headers:
+   *   1. The initial header (with most of the codec setup parameters),
+   *      which is mandated by the Ogg bitstream spec,
+   *   2. The second header which holds any comment fields,
+   *   3. The third header which contains the bitstream codebook.
+   * We merely need to make the headers, then pass them to libvorbis one at
+   * a time; libvorbis handles the additional Ogg bitstream constraints.
+   */
 
   /* Update the comments */
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
 #ifdef DEBUG
     fprintf (stderr, "fs_vorbis_enc_headers: %s = %s\n",
 	     comment->name, comment->value);
 #endif
@@ -328,43 +340,38 @@ fs_vorbis_encode_f_ilv (FishSound * fsou
 
 static long
 fs_vorbis_encode_f (FishSound * fsound, float * pcm[], long frames)
 {
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
   float ** vpcm;
   long len, remaining = frames;
   int i;
-  float ** ppcm = alloca (sizeof (float *) * fsound->info.channels);
 
   if (fsv->packetno == 0) {
     fs_vorbis_enc_headers (fsound);
   }
 
   if (frames == 0) {
     fs_vorbis_finish (fsound);
     return 0;
   }
 
-  for (i = 0; i < fsound->info.channels; i++) {
-    ppcm[i] = pcm[i];
-  }
-
   while (remaining > 0) {
     len = MIN (1024, remaining);
 
 #ifdef DEBUG
     printf ("fs_vorbis_encode: processing %ld frames\n", len);
 #endif
 
     /* expose the buffer to submit data */
     vpcm = vorbis_analysis_buffer (&fsv->vd, 1024);
 
     for (i = 0; i < fsound->info.channels; i++) {
-      memcpy (vpcm[i], ppcm[i], sizeof (float) * len);
+      memcpy (vpcm[i], pcm[i], sizeof (float) * len);
     }
 
     fs_vorbis_encode_write (fsound, len);
 
     remaining -= len;
   }
 
   /**
@@ -423,17 +430,17 @@ fs_vorbis_init (FishSound * fsound)
 
   fsv = fs_malloc (sizeof (FishSoundVorbisInfo));
   if (fsv == NULL) return NULL;
 
   fsv->packetno = 0;
   fsv->finished = 0;
   vorbis_info_init (&fsv->vi);
   vorbis_comment_init (&fsv->vc);
-  vorbis_dsp_init (&fsv->vd);
+  memset(&fsv->vd, 0, sizeof(fsv->vd));
   vorbis_block_init (&fsv->vd, &fsv->vb);
   fsv->pcm = NULL;
   fsv->ipcm = NULL;
   fsv->max_pcm = 0;
 
   fsound->codec_data = fsv;
 
 #if FS_ENCODE && HAVE_VORBISENC
@@ -470,16 +477,17 @@ fs_vorbis_delete (FishSound * fsound)
 }
 
 FishSoundCodec *
 fish_sound_vorbis_codec (void)
 {
   FishSoundCodec * codec;
 
   codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
+  if (codec == NULL) return NULL;
 
   codec->format.format = FISH_SOUND_VORBIS;
   codec->format.name = "Vorbis (Xiph.Org)";
   codec->format.extension = "ogg";
 
   codec->init = fs_vorbis_init;
   codec->del = fs_vorbis_delete;
   codec->reset = fs_vorbis_reset;
--- a/media/libfishsound/src/libfishsound/fs_vector.c
+++ b/media/libfishsound/src/libfishsound/fs_vector.c
@@ -53,16 +53,17 @@ struct _FishSoundVector {
  */
 
 FishSoundVector *
 fs_vector_new (FishSoundCmpFunc cmp)
 {
   FishSoundVector * vector;
 
   vector = fs_malloc (sizeof (FishSoundVector));
+  if (vector == NULL) return NULL;
 
   vector->max_elements = 0;
   vector->nr_elements = 0;
   vector->cmp = cmp;
   vector->data = NULL;
 
   return vector;
 }
@@ -171,16 +172,18 @@ fs_vector_grow (FishSoundVector * vector
   }
 
   return vector;
 }
 
 void *
 fs_vector_insert (FishSoundVector * vector, void * data)
 {
+  if (vector == NULL) return NULL;
+
   if (fs_vector_grow (vector) == NULL)
     return NULL;
 
   vector->data[vector->nr_elements-1] = data;
 
   return data;
 
 }
--- a/media/libfishsound/update.sh
+++ b/media/libfishsound/update.sh
@@ -33,10 +33,9 @@ cp $1/src/libfishsound/comments.c ./src/
 cp $1/src/libfishsound/private.h ./src/libfishsound/private.h
 cp $1/src/libfishsound/fs_compat.h ./src/libfishsound/fs_compat.h
 cp $1/src/libfishsound/speex.c ./src/libfishsound/fishsound_speex.c
 cp $1/src/libfishsound/encode.c ./src/libfishsound/fishsound_encode.c
 cp $1/src/libfishsound/fs_vector.h ./src/libfishsound/fs_vector.h
 cp $1/src/libfishsound/fs_vector.c ./src/libfishsound/fs_vector.c
 cp $1/src/libfishsound/convert.h ./src/libfishsound/convert.h
 cp $1/AUTHORS ./AUTHORS
-patch -p4 <endian.patch
-patch -p3 <bug481601.patch
+patch -p3 <endian.patch
--- a/media/liboggz/README
+++ b/media/liboggz/README
@@ -99,46 +99,51 @@ presenting the following API niceties:
     that need to parse and seek within Ogg files, but do not need to do
     a full media decode.
 
 Full documentation of the liboggz API, customization and installation,
 and mux and demux examples can be read online at:
 
     http://www.annodex.net/software/liboggz/html/
 
-Tools
------
+oggz tool
+---------
 
-The Oggz source tarball also contains the following command-line tools,
-which are useful for debugging and testing Ogg bitstreams:
+Usage: oggz <subcommand> [options] filename ...
 
-    * oggz-chop: Extract the part of an Ogg file between given start
-    and/or end times.
+oggz is a commandline tool for manipulating Ogg files. It supports
+multiplexed files conformant with RFC3533. Oggz can parse headers for
+CELT, CMML, FLAC, Kate, PCM, Speex, Theora and Vorbis, and can read and write
+Ogg Skeleton logical bitstreams.
 
-    * oggz-comment: List or edit comments in an Ogg file.
-
-    * oggz-diff: Hexdump the packets of two Ogg files and output
-    differences.
+Commands:
+  help          Display help for a specific subcommand (eg. "oggz help chop")
 
-    * oggz-dump: Hexdump packets of an Ogg file, or revert an Ogg file
-    from such a hexdump.
-
-    * oggz-info: Display information about one or more Ogg files and
-    their bitstreams.
+Reporting:
+  diff          Hexdump the packets of two Ogg files and output differences.
+  dump          Hexdump packets of an Ogg file, or revert an Ogg file from
+                such a hexdump.
+  info          Display information about one or more Ogg files and their
+                bitstreams.
+  scan          Scan an Ogg file and output characteristic landmarks.
+  validate      Validate the Ogg framing of one or more files.
 
-    * oggz-merge: Merge Ogg files together, interleaving pages in order
-    of presentation time.
-
-    * oggz-rip: Extract one or more logical bitstreams from an Ogg file.
+Extraction:
+  rip           Extract one or more logical bitstreams from an Ogg file.
 
-    * oggz-scan: Scan an Ogg file and output characteristic landmarks.
+Editing:
+  chop          Extract the part of an Ogg file between given start and/or
+                end times.
+  comment       List or edit comments in an Ogg file.
+  merge         Merge Ogg files together, interleaving pages in order of
+                presentation time.
+  sort          Sort the pages of an Ogg file in order of presentation time.
 
-    * oggz-sort: Sort the pages of an Ogg file in order of presentation time.
-
-    * oggz-validate: Validate the Ogg framing of one or more files.
+Miscellaneous:
+  known-codecs  List codecs known by this version of oggz
 
 The script bash-completion/oggz enables completion of tool options and codec
 names when using the bash shell. Source it from your .profile, or install it
 in /etc/bash_completion.d to enable it system-wide.
 
 
 oggz-chop: General usage and CGI installation
 ---------------------------------------------
--- a/media/liboggz/README_MOZILLA
+++ b/media/liboggz/README_MOZILLA
@@ -1,15 +1,12 @@
-The source from this directory was copied from the liboggz svn 
+The source from this directory was copied from the liboggz git 
 source repository using the update.sh script. The only changes made
 were those applied by update.sh, which applies patches described
 below, and the addition/upate of Makefile.in files for the
 Mozilla build system.
 
-The svn revision number used was r3867.
+The git commit id used was ef3b0e from git://git.xiph.org/liboggz.git
 
 The wince.patch addresses the lack of posix file IO support on windows ce,
 see bug 461844 for details.
 
 endian.patch is applied to fix bug 452698.
-
-oggz-seek-crash-fix.patch is applied to fix the crash reported in
-bug 475441 comment #44.
--- a/media/liboggz/include/oggz/config_win32.h
+++ b/media/liboggz/include/oggz/config_win32.h
@@ -130,10 +130,9 @@
 #undef realloc
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
 #undef size_t
 
 /* Define for MSVC as <stdint.h> is unavailable there */
 typedef unsigned char uint8_t;
 
-#define inline __inline // MSVC
-#undef DEBUG
+#define inline __inline // MSVC#undef DEBUG
--- a/media/liboggz/include/oggz/oggz_read.h
+++ b/media/liboggz/include/oggz/oggz_read.h
@@ -153,32 +153,35 @@ int oggz_set_read_page (OGGZ * oggz, lon
  * \retval 0 End of file
  * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
  * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
  * \retval OGGZ_ERR_SYSTEM System error; check errno for details
  * \retval OGGZ_ERR_STOP_OK Reading was stopped by a user callback
  * returning OGGZ_STOP_OK
  * \retval OGGZ_ERR_STOP_ERR Reading was stopped by a user callback
  * returning OGGZ_STOP_ERR
+ * \retval OGGZ_ERR_HOLE_IN_DATA Hole (sequence number gap) detected in input data
  * \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
  */
 long oggz_read (OGGZ * oggz, long n);
 
 /**
  * Input data into \a oggz.
  * \param oggz An OGGZ handle previously opened for reading
  * \param buf A memory buffer
  * \param n A count of bytes to input
  * \retval ">  0" The number of bytes successfully ingested.
  * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ
  * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ
  * \retval OGGZ_ERR_STOP_OK Reading was stopped by a user callback
  * returning OGGZ_STOP_OK
  * \retval OGGZ_ERR_STOP_ERR Reading was stopped by a user callback
  * returning OGGZ_STOP_ERR
+ * \retval OGGZ_ERR_HOLE_IN_DATA Hole (sequence number gap) detected in input data
+ * \retval OGGZ_ERR_OUT_OF_MEMORY Out of memory
  */
 long oggz_read_input (OGGZ * oggz, unsigned char * buf, long n);
 
 /** \}
  */
 
 /**
  * Erase any input buffered in Oggz. This discards any input read from the
deleted file mode 100644
--- a/media/liboggz/seek-error-fix.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/media/liboggz/src/liboggz/oggz_seek.c b/media/liboggz/src/liboggz/oggz_seek.c
---- a/media/liboggz/src/liboggz/oggz_seek.c
-+++ b/media/liboggz/src/liboggz/oggz_seek.c
-@@ -717,17 +717,17 @@ oggz_seek_set (OGGZ * oggz, ogg_int64_t 
- 					      &serialno);
-       unit_end = oggz_get_unit (oggz, serialno, granule_at);
- #ifdef DEBUG
-       printf ("oggz_seek_set: [C] offset_next @%" PRI_OGGZ_OFF_T "d, g%lld, (s%ld)\n",
- 	      offset_next, granule_at, serialno);
-       printf ("oggz_seek_set: [c] u%lld\n",
- 	      oggz_get_unit (oggz, serialno, granule_at));
- #endif
--    } else {
-+    } else if (offset_next >= 0) {
-       serialno = ogg_page_serialno (og);
-       granule_at = ogg_page_granulepos (og);
-     }
- 
-     if (offset_next < 0) {
-       goto notfound;
-     }
- 
--- a/media/liboggz/src/liboggz/oggz.c
+++ b/media/liboggz/src/liboggz/oggz.c
@@ -633,17 +633,17 @@ oggz_map_return_value_to_error (int cb_r
   switch (cb_ret) {
   case OGGZ_CONTINUE:
     return OGGZ_ERR_OK;
   case OGGZ_STOP_OK:
     return OGGZ_ERR_STOP_OK;
   case OGGZ_STOP_ERR:
     return OGGZ_ERR_STOP_ERR;
   default:
-    return OGGZ_ERR_STOP_ERR;
+    return cb_ret;
   }
 }
 
 const char *
 oggz_content_type (OggzStreamContent content)
 {
   /* 20080805:
    * Re: http://lists.xiph.org/pipermail/ogg-dev/2008-July/001108.html
--- a/media/liboggz/src/liboggz/oggz_auto.c
+++ b/media/liboggz/src/liboggz/oggz_auto.c
@@ -370,21 +370,16 @@ auto_dirac (OGGZ * oggz, long serialno, 
   int granule_shift = 22; /* not a typo */
   dirac_info *info;
 
   info = oggz_malloc(sizeof(dirac_info));
   if (info == NULL) return -1;
 
   dirac_parse_info(info, data, length);
 
-#ifdef DEBUG
-  printf ("Got dirac fps %d/%d granule_shift %d\n",
-    fps_numerator, fps_denominator, granule_shift);
-#endif
-
   /* the granulerate is twice the frame rate (in order to handle interlace) */
   oggz_set_granulerate (oggz, serialno,
 	2 * (ogg_int64_t)info->fps_numerator,
 	OGGZ_AUTO_MULT * (ogg_int64_t)info->fps_denominator);
   oggz_set_granuleshift (oggz, serialno, granule_shift);
 
   oggz_stream_set_numheaders (oggz, serialno, 0);
 
@@ -553,18 +548,17 @@ auto_calc_celt (ogg_int64_t now, oggz_st
   return 0;
 
 }
 /*
  * Header packets are marked by a set MSB in the first byte.  Inter packets
  * are marked by a set 2MSB in the first byte.  Intra packets (keyframes)
  * are any that are left over ;-)
  *
- * (see http://www.theora.org/doc/Theora_I_spec.pdf for the theora
- * specification)
+ * (see http://theora.org/doc/Theora.pdf for the theora specification)
  */
 
 typedef struct {
   int encountered_first_data_packet;
 } auto_calc_theora_info_t;
 
 
 static ogg_int64_t
@@ -690,16 +684,17 @@ typedef struct {
   int mode_sizes[1];
 } auto_calc_vorbis_info_t;
 
 
 static ogg_int64_t
 auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) {
 
   auto_calc_vorbis_info_t *info;
+  int ii;
 
   if (stream->calculate_data == NULL) {
     /*
      * on the first (b_o_s) packet, determine the long and short sizes,
      * and then calculate l/2, l/4 - s/4, 3 * l/4 - s/4, l/2 - s/2 and s/2
      */
     int short_size;
     int long_size;
@@ -825,29 +820,42 @@ auto_calc_vorbis(ogg_int64_t now, oggz_s
         }
 
         size += 1;
 
         current_pos -= 5;
 
       }
 
-      if (offset > 4) {
-        size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
-      } else {
-        /* mask part of byte from current_pos */
-        size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
-        /* shift to appropriate position */
-        size_check <<= (5 - offset);
-        /* or in part of byte from current_pos - 1 */
-        size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
-                (offset + 3);
+      /* Give ourselves a chance to recover if we went back too far by using
+       * the size check. */
+      for (ii=0; ii < 2; ii++) {
+       if (offset > 4) {
+         size_check = (current_pos[0] >> (offset - 5)) & 0x3F;
+       } else {
+         /* mask part of byte from current_pos */
+         size_check = (current_pos[0] & ((1 << (offset + 1)) - 1));
+         /* shift to appropriate position */
+         size_check <<= (5 - offset);
+         /* or in part of byte from current_pos - 1 */
+         size_check |= (current_pos[-1] & ~((1 << (offset + 3)) - 1)) >>
+           (offset + 3);
+       }
+
+       size_check += 1;
+       if (size_check == size) {
+         break;
+       }
+        offset = (offset + 1) % 8;
+        if (offset == 0)
+          current_pos += 1;
+       current_pos += 5;
+       size -= 1;
       }
 
-      size_check += 1;
 #ifdef DEBUG
       if (size_check != size)
       {
         printf("WARNING: size parsing failed for VORBIS mode packets\n");
       }
 #endif
 
       /* Check that size to be realloc'd doesn't overflow */
--- a/media/liboggz/src/liboggz/oggz_comments.c
+++ b/media/liboggz/src/liboggz/oggz_comments.c
@@ -52,46 +52,50 @@
 #include <oggz/oggz_stream.h>
 
 /*#define DEBUG*/
 
 #ifdef WIN32                                                                   
 #define strcasecmp _stricmp
 #endif
 
+/* Ensure comment vector length can be expressed in 32 bits
+ * including space for the trailing NUL */
+#define MAX_COMMENT_LENGTH 0xFFFFFFFE
+#define oggz_comment_clamp(c) MIN((c),MAX_COMMENT_LENGTH)
 
-/* Ensure comment vector length can be expressed in 32 bits */
-static unsigned long
+static size_t
 oggz_comment_len (const char * s)
 {
   size_t len;
 
   if (s == NULL) return 0;
 
   len = strlen (s);
-  return (unsigned long) MIN(len, 0xFFFFFFFF);
+  return oggz_comment_clamp(len);
 }
 
 static char *
 oggz_strdup (const char * s)
 {
   char * ret;
   if (s == NULL) return NULL;
   ret = oggz_malloc (oggz_comment_len(s) + 1);
   if (ret == NULL) return NULL;
 
   return strcpy (ret, s);
 }
 
 static char *
-oggz_strdup_len (const char * s, int len)
+oggz_strdup_len (const char * s, size_t len)
 {
   char * ret;
   if (s == NULL) return NULL;
   if (len == 0) return NULL;
+  len = oggz_comment_clamp(len);
   ret = oggz_malloc (len + 1);
   if (!ret) return NULL;
   if (strncpy (ret, s, len) == NULL) {
     oggz_free (ret);
     return NULL;
   }
 
   ret[len] = '\0';
@@ -168,22 +172,33 @@ oggz_comment_validate_byname (const char
 }
 
 static OggzComment *
 oggz_comment_new (const char * name, const char * value)
 {
   OggzComment * comment;
 
   if (!oggz_comment_validate_byname (name, value)) return NULL;
+  /* Ensures that name != NULL, value != NULL, and validates strings */
 
   comment = oggz_malloc (sizeof (OggzComment));
   if (comment == NULL) return NULL;
 
   comment->name = oggz_strdup (name);
+  if (comment->name == NULL) {
+    oggz_free (comment);
+    return NULL;
+  }
+
   comment->value = oggz_strdup (value);
+  if (comment->value == NULL) {
+    oggz_free (comment->name);
+    oggz_free (comment);
+    return NULL;
+  }
 
   return comment;
 }
 
 static void
 oggz_comment_free (OggzComment * comment)
 {
   if (!comment) return;
@@ -212,17 +227,18 @@ static int
 
   if (oggz == NULL) return OGGZ_ERR_BAD_OGGZ;
 
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
 
   if (stream->vendor) oggz_free (stream->vendor);
 
-  stream->vendor = oggz_strdup (vendor_string);
+  if ((stream->vendor = oggz_strdup (vendor_string)) == NULL)
+    return OGGZ_ERR_OUT_OF_MEMORY;
 
   return 0;
 }
 
 /* Public API */
 
 const char *
 oggz_comment_get_vendor (OGGZ * oggz, long serialno)
@@ -359,19 +375,21 @@ oggz_comment_add (OGGZ * oggz, long seri
     return OGGZ_ERR_OUT_OF_MEMORY;
 
   if (oggz->flags & OGGZ_WRITE) {
     if (OGGZ_CONFIG_WRITE) {
 
       if (!oggz_comment_validate_byname (comment->name, comment->value))
         return OGGZ_ERR_COMMENT_INVALID;
 
-      new_comment = oggz_comment_new (comment->name, comment->value);
+      if ((new_comment = oggz_comment_new (comment->name, comment->value)) == NULL)
+        return OGGZ_ERR_OUT_OF_MEMORY;
 
-      _oggz_comment_add (stream, new_comment);
+      if (_oggz_comment_add (stream, new_comment) == NULL)
+        return OGGZ_ERR_OUT_OF_MEMORY;
 
       return 0;
     } else {
       return OGGZ_ERR_DISABLED;
     }
   } else {
     return OGGZ_ERR_INVALID;
   }
@@ -393,19 +411,21 @@ oggz_comment_add_byname (OGGZ * oggz, lo
     return OGGZ_ERR_OUT_OF_MEMORY;
 
   if (oggz->flags & OGGZ_WRITE) {
     if (OGGZ_CONFIG_WRITE) {
 
       if (!oggz_comment_validate_byname (name, value))
         return OGGZ_ERR_COMMENT_INVALID;
 
-      new_comment = oggz_comment_new (name, value);
+      if ((new_comment = oggz_comment_new (name, value)) == NULL)
+        return OGGZ_ERR_OUT_OF_MEMORY;
 
-      _oggz_comment_add (stream, new_comment);
+      if (_oggz_comment_add (stream, new_comment) == NULL)
+        return OGGZ_ERR_OUT_OF_MEMORY;
 
       return 0;
     } else {
       return OGGZ_ERR_DISABLED;
     }
   } else {
     return OGGZ_ERR_INVALID;
   }
@@ -526,74 +546,95 @@ oggz_comments_free (oggz_stream_t * stre
 }
 
 int
 oggz_comments_decode (OGGZ * oggz, long serialno,
                       unsigned char * comments, long length)
 {
    oggz_stream_t * stream;
    char *c= (char *)comments;
-   int len, i, nb_fields, n;
+   int i, nb_fields, n;
+   size_t len;
    char *end;
    char * name, * value, * nvalue = NULL;
    OggzComment * comment;
 
    if (length<8)
       return -1;
 
    end = c+length;
    len=readint(c, 0);
 
    c+=4;
-   if (c+len>end) return -1;
+   if (len>(size_t)(end-c)) return -1;
 
    stream = oggz_get_stream (oggz, serialno);
    if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
 
    /* Vendor */
-   nvalue = oggz_strdup_len (c, len);
-   if (!nvalue) return -1;
-   _oggz_comment_set_vendor (oggz, serialno, nvalue);
-   if (nvalue) oggz_free (nvalue);
+   if (len > 0) {
+     if ((nvalue = oggz_strdup_len (c, len)) == NULL)
+       return OGGZ_ERR_OUT_OF_MEMORY;
+
+     if (_oggz_comment_set_vendor (oggz, serialno, nvalue) == OGGZ_ERR_OUT_OF_MEMORY)
+       return OGGZ_ERR_OUT_OF_MEMORY;
+
+     oggz_free (nvalue);
+   }
+
 #ifdef DEBUG
    fwrite(c, 1, len, stderr); fputc ('\n', stderr);
 #endif
    c+=len;
 
    if (c+4>end) return -1;
 
+   /* This value gets checked effectively by the 'for' condition
+      and the checks within the loop for c running off the end.  */
    nb_fields=readint(c, 0);
    c+=4;
    for (i=0;i<nb_fields;i++) {
       if (c+4>end) return -1;
 
       len=readint(c, 0);
 
       c+=4;
-      if (c+len>end) return -1;
+      if (len>(size_t)(end-c)) return -1;
 
       name = c;
       value = oggz_index_len (c, '=', len);
       if (value) {
          *value = '\0';
          value++;
 
          n = c+len - value;
-         nvalue = oggz_strdup_len (value, n);
+         if ((nvalue = oggz_strdup_len (value, n)) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
 #ifdef DEBUG
          printf ("oggz_comments_decode: %s -> %s (length %d)\n",
          name, nvalue, n);
 #endif
-         comment = oggz_comment_new (name, nvalue);
-         _oggz_comment_add (stream, comment);
+         if ((comment = oggz_comment_new (name, nvalue)) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
+         if (_oggz_comment_add (stream, comment) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
          oggz_free (nvalue);
       } else {
-         nvalue = oggz_strdup_len (name, len);
-         comment = oggz_comment_new (nvalue, NULL);
-         _oggz_comment_add (stream, comment);
+         if ((nvalue = oggz_strdup_len (name, len)) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
+         if ((comment = oggz_comment_new (nvalue, NULL)) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
+         if (_oggz_comment_add (stream, comment) == NULL)
+           return OGGZ_ERR_OUT_OF_MEMORY;
+
          oggz_free (nvalue);
       }
 
       c+=len;
    }
 
 #ifdef DEBUG
    printf ("oggz_comments_decode: done\n");
@@ -643,17 +684,19 @@ oggz_comments_encode (OGGZ * oggz, long 
     vendor_length = oggz_comment_len (stream->vendor);
   if (accum_length (&actual_length, 4 + vendor_length) == 0)
     return 0;
 #ifdef DEBUG
   printf ("oggz_comments_encode: vendor = %s\n", stream->vendor);
 #endif
 
   /* user comment list length */
-  actual_length += 4;
+  if (accum_length (&actual_length, 4) == 0)
+    return 0;
+
 
   for (comment = oggz_comment_first (oggz, serialno); comment;
        comment = oggz_comment_next (oggz, serialno, comment)) {
     /* [size]"name" */
     if (accum_length (&actual_length, 4 + oggz_comment_len (comment->name)) == 0)
       return 0;
     if (comment->value) {
       /* "=value" */
@@ -681,17 +724,17 @@ oggz_comments_encode (OGGZ * oggz, long 
   if (remaining <= 0) return actual_length;
   writeint (c, 0, vendor_length);
   c += 4;
 
   if (stream->vendor) {
     field_length = oggz_comment_len (stream->vendor);
     memcpy (c, stream->vendor, MIN (field_length, remaining));
     c += field_length; remaining -= field_length;
-    if (remaining <= 0 ) return actual_length;
+    if (remaining <= 0) return actual_length;
   }
 
   remaining -= 4;
   if (remaining <= 0) return actual_length;
   writeint (c, 0, nb_fields);
   c += 4;
 
   for (comment = oggz_comment_first (oggz, serialno); comment;
--- a/media/liboggz/update.sh
+++ b/media/liboggz/update.sh
@@ -42,9 +42,8 @@ sed s/\#include\ \"config.h\"/\#ifdef\ W
 cp $1/src/liboggz/oggz_dlist.h ./src/liboggz/oggz_dlist.h
 sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \"config.h\"\\n\#endif/g $1/src/liboggz/metric_internal.c >./src/liboggz/metric_internal.c
 cp $1/src/liboggz/dirac.h ./src/liboggz/dirac.h
 sed s/\#include\ \"config.h\"/\#ifdef\ WIN32\\n\#include\ \"config_win32.h\"\\n\#else\\n\#include\ \"config.h\"\\n\#endif/g $1/src/liboggz/dirac.c >./src/liboggz/dirac.c
 cp $1/AUTHORS ./AUTHORS
 patch -p3 <wince.patch
 patch -p3 <endian.patch
 patch -p4 <seek.patch
-patch -p3 <seek-error-fix.patch