Bug 852002 - Fix nestegg's handling of zero length master element. r=padenot
authorMatthew Gregan <kinetik@flim.org>
Tue, 19 Mar 2013 13:41:30 +1300
changeset 125514 0e41b1ed18c21752d09c3c0b6a02166982c81288
parent 125513 97e443115162450609702fc72c99b6d88d8703d6
child 125515 bbb0081483d995a95f9764bcf537e27170f6cb6b
push id24459
push useremorley@mozilla.com
push dateWed, 20 Mar 2013 11:46:36 +0000
treeherdermozilla-central@1d6fe70c79c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs852002
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 852002 - Fix nestegg's handling of zero length master element. r=padenot
media/libnestegg/README_MOZILLA
media/libnestegg/include/nestegg.h
media/libnestegg/src/nestegg.c
--- a/media/libnestegg/README_MOZILLA
+++ b/media/libnestegg/README_MOZILLA
@@ -1,8 +1,8 @@
 The source from this directory was copied from the nestegg
 git repository using the update.sh script.  The only changes
 made were those applied by update.sh and the addition of
 Makefile.in build files for the Mozilla build system.
 
 The nestegg git repository is: git://github.com/kinetiknz/nestegg.git
 
-The git commit ID used was 38c83d9d4c0c5c84373aa285bd30094a12d6b6f6.
+The git commit ID used was ebdbb688fb13dd315fc9d16e6897adb5ee42b7bb.
--- a/media/libnestegg/include/nestegg.h
+++ b/media/libnestegg/include/nestegg.h
@@ -1,20 +1,20 @@
 /*
  * Copyright © 2010 Mozilla Foundation
  *
  * This program is made available under an ISC-style license.  See the
  * accompanying file LICENSE for details.
  */
-#ifndef   NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
-#define   NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
+#if !defined(NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79)
+#define NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
 
 #include <nestegg/nestegg-stdint.h>
 
-#ifdef __cplusplus
+#if defined(__cplusplus)
 extern "C" {
 #endif
 
 /** @mainpage
 
     @section intro Introduction
 
     This is the documentation for the <tt>libnestegg</tt> C API.
@@ -329,13 +329,13 @@ int nestegg_has_cues(nestegg * context);
  * Try to determine if the buffer looks like the beginning of a WebM file.
  *
  * @param buffer A buffer containing the beginning of a media file.
  * @param length The size of the buffer.
  * @retval 0 The file is not a WebM file.
  * @retval 1 The file is a WebM file. */
 int nestegg_sniff(unsigned char const * buffer, size_t length);
 
-#ifdef __cplusplus
+#if defined(__cplusplus)
 }
 #endif
 
 #endif /* NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79 */
--- a/media/libnestegg/src/nestegg.c
+++ b/media/libnestegg/src/nestegg.c
@@ -270,31 +270,33 @@ struct list_node {
   unsigned char * data;
 };
 
 struct saved_state {
   int64_t stream_offset;
   struct list_node * ancestor;
   uint64_t last_id;
   uint64_t last_size;
+  int last_valid;
 };
 
 struct frame {
   unsigned char * data;
   size_t length;
   struct frame * next;
 };
 
 /* Public (opaque) Structures */
 struct nestegg {
   nestegg_io * io;
   nestegg_log log;
   struct pool_ctx * alloc_pool;
   uint64_t last_id;
   uint64_t last_size;
+  int last_valid;
   struct list_node * ancestor;
   struct ebml ebml;
   struct segment segment;
   int64_t segment_offset;
   unsigned int track_count;
 };
 
 struct nestegg_packet {
@@ -805,39 +807,41 @@ static int
 ne_ctx_save(nestegg * ctx, struct saved_state * s)
 {
   s->stream_offset = ne_io_tell(ctx->io);
   if (s->stream_offset < 0)
     return -1;
   s->ancestor = ctx->ancestor;
   s->last_id = ctx->last_id;
   s->last_size = ctx->last_size;
+  s->last_valid = ctx->last_valid;
   return 0;
 }
 
 static int
 ne_ctx_restore(nestegg * ctx, struct saved_state * s)
 {
   int r;
 
   r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET);
   if (r != 0)
     return -1;
   ctx->ancestor = s->ancestor;
   ctx->last_id = s->last_id;
   ctx->last_size = s->last_size;
+  ctx->last_valid = s->last_valid;
   return 0;
 }
 
 static int
 ne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size)
 {
   int r;
 
-  if (ctx->last_id && ctx->last_size) {
+  if (ctx->last_valid) {
     if (id)
       *id = ctx->last_id;
     if (size)
       *size = ctx->last_size;
     return 1;
   }
 
   r = ne_read_id(ctx->io, &ctx->last_id, NULL);
@@ -848,30 +852,31 @@ ne_peek_element(nestegg * ctx, uint64_t 
   if (r != 1)
     return r;
 
   if (id)
     *id = ctx->last_id;
   if (size)
     *size = ctx->last_size;
 
+  ctx->last_valid = 1;
+
   return 1;
 }
 
 static int
 ne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size)
 {
   int r;
 
   r = ne_peek_element(ctx, id, size);
   if (r != 1)
     return r;
 
-  ctx->last_id = 0;
-  ctx->last_size = 0;
+  ctx->last_valid = 0;
 
   return 1;
 }
 
 static void
 ne_read_master(nestegg * ctx, struct ebml_element_desc * desc)
 {
   struct ebml_list * list;
@@ -960,44 +965,46 @@ ne_read_simple(nestegg * ctx, struct ebm
   return r;
 }
 
 static int
 ne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset)
 {
   int r;
   int64_t * data_offset;
-  uint64_t id, size;
+  uint64_t id, size, peeked_id;
   struct ebml_element_desc * element;
 
   if (!ctx->ancestor)
     return -1;
 
   for (;;) {
     if (max_offset > 0 && ne_io_tell(ctx->io) >= max_offset) {
       /* Reached end of offset allowed for parsing - return gracefully */
       r = 1;
       break;
     }
     r = ne_peek_element(ctx, &id, &size);
     if (r != 1)
       break;
+    peeked_id = id;
 
     element = ne_find_element(id, ctx->ancestor->node);
     if (element) {
       if (element->flags & DESC_FLAG_SUSPEND) {
         assert(element->type == TYPE_BINARY);
         ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id);
         r = 1;
         break;
       }
 
       r = ne_read_element(ctx, &id, &size);
       if (r != 1)
         break;
+      assert(id == peeked_id);
 
       if (element->flags & DESC_FLAG_OFFSET) {
         data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset);
         *data_offset = ne_io_tell(ctx->io);
         if (*data_offset < 0) {
           r = -1;
           break;
         }
@@ -1460,18 +1467,17 @@ ne_init_cue_points(nestegg * ctx, int64_
     r = ne_ctx_save(ctx, &state);
     if (r != 0)
       return -1;
 
     /* Seek and set up parser state for segment-level element (Cues). */
     r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET);
     if (r != 0)
       return -1;
-    ctx->last_id = 0;
-    ctx->last_size = 0;
+    ctx->last_valid = 0;
 
     r = ne_read_element(ctx, &id, NULL);
     if (r != 1)
       return -1;
 
     if (id != ID_CUES)
       return -1;
 
@@ -1803,18 +1809,17 @@ int
 nestegg_offset_seek(nestegg * ctx, uint64_t offset)
 {
   int r;
 
   /* Seek and set up parser state for segment-level element (Cluster). */
   r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET);
   if (r != 0)
     return -1;
-  ctx->last_id = 0;
-  ctx->last_size = 0;
+  ctx->last_valid = 0;
 
   while (ctx->ancestor)
     ne_ctx_pop(ctx);
 
   ne_ctx_push(ctx, ne_top_level_elements, ctx);
   ne_ctx_push(ctx, ne_segment_elements, &ctx->segment);
 
   return 0;