[Swfdec] 6 commits - libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_color_as.c libswfdec/swfdec_graphic_movie.c libswfdec/swfdec_image_decoder.c libswfdec/swfdec_morph_movie.c libswfdec/swfdec_movie_as_drawing.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_player.c libswfdec/swfdec_resource.c libswfdec/swfdec_sprite_movie_as.c libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_field_movie.c libswfdec/swfdec_video_movie.c test/dump.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Mon Dec 10 01:56:36 PST 2007


 libswfdec/Makefile.am                              |   14 +-
 libswfdec/swfdec_as_interpret.c                    |    4 
 libswfdec/swfdec_color_as.c                        |    4 
 libswfdec/swfdec_graphic_movie.c                   |   16 ++
 libswfdec/swfdec_image_decoder.c                   |    8 +
 libswfdec/swfdec_morph_movie.c                     |   14 ++
 libswfdec/swfdec_movie.c                           |  130 ++++++++++++++++-----
 libswfdec/swfdec_movie.h                           |   14 +-
 libswfdec/swfdec_movie_as_drawing.c                |    7 -
 libswfdec/swfdec_movie_asprops.c                   |   20 +--
 libswfdec/swfdec_player.c                          |   39 ++++--
 libswfdec/swfdec_resource.c                        |    9 -
 libswfdec/swfdec_sprite_movie_as.c                 |   14 +-
 libswfdec/swfdec_text_field_movie.c                |   19 ++-
 libswfdec/swfdec_text_field_movie_as.c             |   18 +-
 libswfdec/swfdec_video_movie.c                     |    8 -
 test/dump.c                                        |    3 
 test/trace/Makefile.am                             |    3 
 test/trace/crash-0.5.4-13379-catch-in-register.swf |binary
 test/trace/crash-0.5.4-13379-catch-in-register.xml |   60 +++++++++
 20 files changed, 308 insertions(+), 96 deletions(-)

New commits:
commit 2834170dc1d8acbae5ae5a32653b34f88952167e
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Dec 9 22:53:34 2007 +0100

    don't crash when loading images > 65kB (fixes #13529)

diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 887c102..027027a 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -287,11 +287,11 @@ swfdec_resource_loader_target_parse (SwfdecLoaderTarget *target, SwfdecLoader *l
       }
       parsed += buffer->length;
       if (dec) {
-	status = swfdec_decoder_parse (dec, buffer);
+	status |= swfdec_decoder_parse (dec, buffer);
       } else {
 	swfdec_buffer_unref (buffer);
       }
-    } while ((status & (SWFDEC_STATUS_ERROR | SWFDEC_STATUS_NEEDBITS | SWFDEC_STATUS_EOF)) == 0);
+    } while (parsed < 65536 && (status & (SWFDEC_STATUS_ERROR | SWFDEC_STATUS_EOF)) == 0);
     if (status & SWFDEC_STATUS_ERROR) {
       SWFDEC_ERROR ("parsing error");
       swfdec_loader_set_target (loader, NULL);
commit 6e3d2284c46bf35e36cabf0b3c50b0dc0cd218fc
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Dec 7 16:53:27 2007 +0100

    rework invalidation handling again
    
    This should lead to less redraws again.
    But it doesn't seem to yet :o
    And it doesn't fix all existing bugs either...

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index d5cf0da..471f2c6 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -70,13 +70,6 @@ libswfdec_source_files = \
 	swfdec_displacement_map_filter.c \
 	swfdec_draw.c \
 	swfdec_drop_shadow_filter.c \
-	swfdec_text_field.c \
-	swfdec_text_field_movie.c \
-	swfdec_text_field_movie_as.c \
-	swfdec_text_field_movie_html.c \
-	swfdec_text_renderer.c \
-	swfdec_text_snapshot.c \
-	swfdec_transform.c \
 	swfdec_event.c \
 	swfdec_external_interface.c \
 	swfdec_file_loader.c \
@@ -146,7 +139,14 @@ libswfdec_source_files = \
 	swfdec_system_security.c \
 	swfdec_tag.c \
 	swfdec_text.c \
+	swfdec_text_field.c \
+	swfdec_text_field_movie.c \
+	swfdec_text_field_movie_as.c \
+	swfdec_text_field_movie_html.c \
 	swfdec_text_format.c \
+	swfdec_text_renderer.c \
+	swfdec_text_snapshot.c \
+	swfdec_transform.c \
 	swfdec_url.c \
 	swfdec_utils.c \
 	swfdec_video.c \
diff --git a/libswfdec/swfdec_color_as.c b/libswfdec/swfdec_color_as.c
index aece489..35a8304 100644
--- a/libswfdec/swfdec_color_as.c
+++ b/libswfdec/swfdec_color_as.c
@@ -131,7 +131,7 @@ swfdec_movie_color_setRGB (SwfdecAsContext *cx, SwfdecAsObject *obj,
   movie->color_transform.gb = (color & 0xFF00) >> 8;
   movie->color_transform.ba = 0;
   movie->color_transform.bb = color & 0xFF;
-  swfdec_movie_invalidate (movie);
+  swfdec_movie_invalidate_last (movie);
 }
 
 static inline void
@@ -177,5 +177,5 @@ swfdec_movie_color_setTransform (SwfdecAsContext *cx, SwfdecAsObject *obj,
   parse_property (parse, SWFDEC_AS_STR_gb, &movie->color_transform.gb, FALSE);
   parse_property (parse, SWFDEC_AS_STR_bb, &movie->color_transform.bb, FALSE);
   parse_property (parse, SWFDEC_AS_STR_ab, &movie->color_transform.ab, FALSE);
-  swfdec_movie_invalidate (movie);
+  swfdec_movie_invalidate_last (movie);
 }
diff --git a/libswfdec/swfdec_graphic_movie.c b/libswfdec/swfdec_graphic_movie.c
index ce9e67d..24e8a77 100644
--- a/libswfdec/swfdec_graphic_movie.c
+++ b/libswfdec/swfdec_graphic_movie.c
@@ -24,13 +24,14 @@
 #include "swfdec_graphic_movie.h"
 #include "swfdec_button.h"
 #include "swfdec_debug.h"
-#include "swfdec_text_field.h"
 #include "swfdec_movie.h"
+#include "swfdec_player_internal.h"
 #include "swfdec_shape.h"
 #include "swfdec_sprite.h"
 #include "swfdec_swf_decoder.h"
 #include "swfdec_resource.h"
 #include "swfdec_text.h"
+#include "swfdec_text_field.h"
 
 G_DEFINE_TYPE (SwfdecGraphicMovie, swfdec_graphic_movie, SWFDEC_TYPE_MOVIE)
 
@@ -49,6 +50,15 @@ swfdec_graphic_movie_render (SwfdecMovie *movie, cairo_t *cr,
   swfdec_graphic_render (movie->graphic, cr, trans, inval);
 }
 
+static void
+swfdec_graphic_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
+{
+  SwfdecRect rect;
+
+  swfdec_rect_transform (&rect, &movie->graphic->extents, matrix);
+  swfdec_player_invalidate (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
+}
+
 static SwfdecMovie *
 swfdec_graphic_movie_contains (SwfdecMovie *movie, double x, double y, 
     gboolean events)
@@ -76,9 +86,10 @@ swfdec_graphic_movie_replace (SwfdecMovie *movie, SwfdecGraphic *graphic)
   }
   if (movie->graphic == graphic)
     return;
+  swfdec_movie_invalidate_next (movie);
   SWFDEC_LOG ("replacing %u with %u", SWFDEC_CHARACTER (movie->graphic)->id,
       SWFDEC_CHARACTER (graphic)->id);
-  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_CONTENTS);
+  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_EXTENTS);
   g_object_unref (movie->graphic);
   movie->graphic = g_object_ref (graphic);
 }
@@ -91,6 +102,7 @@ swfdec_graphic_movie_class_init (SwfdecGraphicMovieClass * g_class)
   movie_class->update_extents = swfdec_graphic_movie_update_extents;
   movie_class->replace = swfdec_graphic_movie_replace;
   movie_class->render = swfdec_graphic_movie_render;
+  movie_class->invalidate = swfdec_graphic_movie_invalidate;
   movie_class->contains = swfdec_graphic_movie_contains;
 }
 
diff --git a/libswfdec/swfdec_morph_movie.c b/libswfdec/swfdec_morph_movie.c
index 7997827..e53f881 100644
--- a/libswfdec/swfdec_morph_movie.c
+++ b/libswfdec/swfdec_morph_movie.c
@@ -24,6 +24,7 @@
 #include "swfdec_morph_movie.h"
 #include "swfdec_debug.h"
 #include "swfdec_draw.h"
+#include "swfdec_player_internal.h"
 #include "swfdec_stroke.h"
 
 G_DEFINE_TYPE (SwfdecMorphMovie, swfdec_morph_movie, SWFDEC_TYPE_MOVIE)
@@ -47,10 +48,11 @@ swfdec_morph_movie_set_ratio (SwfdecMovie *movie)
 {
   SwfdecMorphMovie *mmovie = SWFDEC_MORPH_MOVIE (movie);
 
+  swfdec_movie_invalidate_next (movie);
   g_slist_foreach (mmovie->draws, (GFunc) g_object_unref, NULL);
   g_slist_free (mmovie->draws);
   mmovie->draws = NULL;
-  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_CONTENTS);
+  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_EXTENTS);
 }
 
 static void
@@ -87,6 +89,15 @@ swfdec_morph_movie_render (SwfdecMovie *movie, cairo_t *cr,
 }
 
 static void
+swfdec_morph_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
+{
+  SwfdecRect rect;
+  
+  swfdec_rect_transform (&rect, &movie->original_extents, matrix);
+  swfdec_player_invalidate (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
+}
+
+static void
 swfdec_morph_movie_dispose (GObject *object)
 {
   SwfdecMorphMovie *morph = SWFDEC_MORPH_MOVIE (object);
@@ -109,6 +120,7 @@ swfdec_morph_movie_class_init (SwfdecMorphMovieClass * g_class)
 
   movie_class->update_extents = swfdec_morph_movie_update_extents;
   movie_class->render = swfdec_morph_movie_render;
+  movie_class->invalidate = swfdec_morph_movie_invalidate;
   movie_class->set_ratio = swfdec_morph_movie_set_ratio;
   /* FIXME */
   //movie_class->handle_mouse = swfdec_morph_movie_handle_mouse;
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 567da71..cf6786a 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -70,34 +70,87 @@ swfdec_movie_init (SwfdecMovie * movie)
   swfdec_color_transform_init_identity (&movie->original_ctrans);
 
   movie->visible = TRUE;
-  movie->cache_state = SWFDEC_MOVIE_INVALID_CONTENTS;
+  movie->cache_state = SWFDEC_MOVIE_INVALID_EXTENTS;
+  movie->invalidate_last = TRUE;
+  movie->invalidate_next = TRUE;
 
   swfdec_rect_init_empty (&movie->extents);
 }
 
 /**
  * swfdec_movie_invalidate:
- * @movie: movie to invalidate
+ * @movie: a #SwfdecMovie
+ * @parent_to_global: This is the matrix from the parent to the global matrix.
+ *                    It is only used for caching reasons
+ * @new_contents: %TRUE if this is the invalidation of the new contents, %FALSE 
+ *                if the old contents are invalidated.
  *
- * Invalidates the area currently occupied by movie. If the area this movie
- * occupies has changed, call swfdec_movie_queue_update () instead.
+ * Performs an instant invalidation on @movie. You most likely don't want to
+ * call this function directly, but use swfdec_movie_invalidate_last_last() or
+ * swfdec_movie_invalidate_next() instead.
  **/
 void
-swfdec_movie_invalidate (SwfdecMovie *movie)
+swfdec_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *parent_to_global,
+    gboolean new_contents)
 {
-  SwfdecRect rect = movie->extents;
+  SwfdecMovieClass *klass;
+  cairo_matrix_t matrix;
 
-  SWFDEC_LOG ("%s invalidating %g %g  %g %g", movie->name, 
-      rect.x0, rect.y0, rect.x1, rect.y1);
-  if (swfdec_rect_is_empty (&rect))
-    return;
-  while (movie->parent) {
-    movie = movie->parent;
-    if (movie->cache_state > SWFDEC_MOVIE_INVALID_EXTENTS)
+  if (new_contents) {
+    movie->invalidate_next = FALSE;
+  } else {
+    if (movie->invalidate_last)
       return;
-    swfdec_rect_transform (&rect, &rect, &movie->matrix);
+    movie->invalidate_last = TRUE;
   }
-  swfdec_player_invalidate (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
+  g_assert (movie->cache_state <= SWFDEC_MOVIE_INVALID_CHILDREN);
+  SWFDEC_LOG ("invalidating %s %s at %s", G_OBJECT_TYPE_NAME (movie), 
+      movie->name, new_contents ? "end" : "start");
+  cairo_matrix_multiply (&matrix, &movie->matrix, parent_to_global);
+  klass = SWFDEC_MOVIE_GET_CLASS (movie);
+  klass->invalidate (movie, &matrix, new_contents);
+}
+
+/**
+ * swfdec_movie_invalidate_last:
+ * @movie: a #SwfdecMovie
+ *
+ * Ensures the movie's contents are invalidated. This function must be called
+ * before changing the movie or the output will have artifacts.
+ **/
+void
+swfdec_movie_invalidate_last (SwfdecMovie *movie)
+{
+  cairo_matrix_t matrix;
+
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+
+  if (movie->invalidate_last)
+    return;
+
+  if (movie->parent)
+    swfdec_movie_local_to_global_matrix (movie->parent, &matrix);
+  else
+    cairo_matrix_init_identity (&matrix);
+  swfdec_movie_invalidate (movie, &matrix, FALSE);
+  g_assert (movie->invalidate_last);
+}
+
+/**
+ * swfdec_movie_invalidate_last_next:
+ * @movie: a #SwfdecMovie
+ *
+ * Ensures the movie will be invalidated after script execution is done. So
+ * after calling this function you can modify position and contents of the 
+ * @movie in any way.
+ **/
+void
+swfdec_movie_invalidate_next (SwfdecMovie *movie)
+{
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+
+  swfdec_movie_invalidate_last (movie);
+  movie->invalidate_next = TRUE;
 }
 
 /**
@@ -112,9 +165,9 @@ swfdec_movie_queue_update (SwfdecMovie *movie, SwfdecMovieCacheState state)
 {
   g_return_if_fail (SWFDEC_IS_MOVIE (movie));
 
-  if (movie->cache_state < SWFDEC_MOVIE_INVALID_EXTENTS &&
-      state >= SWFDEC_MOVIE_INVALID_EXTENTS)
-    swfdec_movie_invalidate (movie);
+  if (state > SWFDEC_MOVIE_INVALID_EXTENTS) {
+    swfdec_movie_invalidate_next (movie);
+  }
   while (movie && movie->cache_state < state) {
     movie->cache_state = state;
     movie = movie->parent;
@@ -195,13 +248,9 @@ swfdec_movie_do_update (SwfdecMovie *movie)
     case SWFDEC_MOVIE_INVALID_MATRIX:
       swfdec_movie_update_matrix (movie);
       /* fall through */
-    case SWFDEC_MOVIE_INVALID_CONTENTS:
-      swfdec_movie_update_extents (movie);
-      swfdec_movie_invalidate (movie);
-      break;
     case SWFDEC_MOVIE_INVALID_EXTENTS:
       swfdec_movie_update_extents (movie);
-      break;
+      /* fall through */
     case SWFDEC_MOVIE_INVALID_CHILDREN:
       break;
     case SWFDEC_MOVIE_UP_TO_DATE:
@@ -274,7 +323,7 @@ swfdec_movie_do_remove (SwfdecMovie *movie, gboolean destroy)
     player->mouse_grab = NULL;
   if (player->mouse_drag == movie)
     player->mouse_drag = NULL;
-  swfdec_movie_invalidate (movie);
+  swfdec_movie_invalidate_last (movie);
   movie->state = SWFDEC_MOVIE_STATE_REMOVED;
 
   if ((movie->events && 
@@ -1355,6 +1404,28 @@ swfdec_movie_mouse_move (SwfdecMovie *movie, double x, double y)
 }
 
 static void
+swfdec_movie_do_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
+{
+  GList *walk;
+  SwfdecRect rect;
+
+  if (movie->image) {
+    rect.x0 = rect.y0 = 0;
+    rect.x1 = movie->image->width * SWFDEC_TWIPS_SCALE_FACTOR;
+    rect.y1 = movie->image->height * SWFDEC_TWIPS_SCALE_FACTOR;
+  } else {
+    swfdec_rect_init_empty (&rect);
+  }
+  swfdec_rect_union (&rect, &rect, &movie->draw_extents);
+  swfdec_rect_transform (&rect, &rect, matrix);
+  swfdec_player_invalidate (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
+
+  for (walk = movie->list; walk; walk = walk->next) {
+    swfdec_movie_invalidate (walk->data, matrix, last);
+  }
+}
+
+static void
 swfdec_movie_class_init (SwfdecMovieClass * movie_class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (movie_class);
@@ -1374,6 +1445,7 @@ swfdec_movie_class_init (SwfdecMovieClass * movie_class)
 	  G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   movie_class->render = swfdec_movie_do_render;
+  movie_class->invalidate = swfdec_movie_do_invalidate;
   movie_class->contains = swfdec_movie_do_contains;
   movie_class->iterate_end = swfdec_movie_iterate_end;
   movie_class->mouse_events = swfdec_movie_mouse_events;
@@ -1404,7 +1476,7 @@ swfdec_movie_set_depth (SwfdecMovie *movie, int depth)
   if (movie->depth == depth)
     return;
 
-  swfdec_movie_invalidate (movie);
+  swfdec_movie_invalidate_last (movie);
   movie->depth = depth;
   if (movie->parent) {
     movie->parent->list = g_list_sort (movie->parent->list, swfdec_movie_compare_depths);
@@ -1523,17 +1595,17 @@ swfdec_movie_set_static_properties (SwfdecMovie *movie, const cairo_matrix_t *tr
     return;
   }
   if (transform) {
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->original_transform = *transform;
     movie->matrix.x0 = movie->original_transform.x0;
     movie->matrix.y0 = movie->original_transform.y0;
     movie->xscale = swfdec_matrix_get_xscale (&movie->original_transform);
     movie->yscale = swfdec_matrix_get_yscale (&movie->original_transform);
     movie->rotation = swfdec_matrix_get_rotation (&movie->original_transform);
-    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
   }
   if (ctrans) {
     movie->original_ctrans = *ctrans;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
   if (ratio >= 0 && (guint) ratio != movie->original_ratio) {
     SwfdecMovieClass *klass;
@@ -1545,11 +1617,11 @@ swfdec_movie_set_static_properties (SwfdecMovie *movie, const cairo_matrix_t *tr
   if (clip_depth && clip_depth != movie->clip_depth) {
     movie->clip_depth = clip_depth;
     /* FIXME: is this correct? */
-    swfdec_movie_invalidate (movie->parent ? movie->parent : movie);
+    swfdec_movie_invalidate_last (movie->parent ? movie->parent : movie);
   }
   if (blend_mode != movie->blend_mode) {
     movie->blend_mode = blend_mode;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
   if (events) {
     if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 6ecc285..6b5b001 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -74,7 +74,6 @@ typedef enum {
   SWFDEC_MOVIE_UP_TO_DATE = 0,		/* everything OK */
   SWFDEC_MOVIE_INVALID_CHILDREN,	/* call update on children */
   SWFDEC_MOVIE_INVALID_EXTENTS,		/* recalculate extents */
-  SWFDEC_MOVIE_INVALID_CONTENTS,	/* trigger an invalidation */
   SWFDEC_MOVIE_INVALID_MATRIX		/* matrix is invalid, recalculate */
 } SwfdecMovieCacheState;
 
@@ -136,6 +135,10 @@ struct _SwfdecMovie {
   SwfdecDraw *		draw_line;	      	/* current line style or NULL */
   int			draw_x;			/* current x position for drawing */
   int			draw_y;			/* current y position for drawing */
+  
+  /* invalidatation state */
+  gboolean		invalidate_last;	/* TRUE if this movie's previous contents are already invalidated */
+  gboolean		invalidate_next;	/* TRUE if this movie should be invalidated before unlocking */
 
   /* leftover unimplemented variables from the Actionscript spec */
 #if 0
@@ -158,6 +161,9 @@ struct _SwfdecMovieClass {
 						 cairo_t *		cr,
 						 const SwfdecColorTransform *trans,
 						 const SwfdecRect *	inval);
+  void			(* invalidate)		(SwfdecMovie *		movie,
+						 const cairo_matrix_t *	movie_to_global,
+						 gboolean		new_contents);
 
   SwfdecMovie *		(* contains)		(SwfdecMovie *		movie,
 						 double			x,
@@ -220,7 +226,11 @@ void		swfdec_movie_set_static_properties
 						 int			clip_depth,
 						 guint			blend_mode,
 						 SwfdecEventList *	events);
-void		swfdec_movie_invalidate		(SwfdecMovie *		movie);
+void		swfdec_movie_invalidate_last	(SwfdecMovie *		movie);
+void		swfdec_movie_invalidate_next	(SwfdecMovie *		movie);
+void		swfdec_movie_invalidate		(SwfdecMovie *		movie,
+						 const cairo_matrix_t *	parent_to_global,
+						 gboolean		last);
 void		swfdec_movie_queue_update	(SwfdecMovie *		movie,
 						 SwfdecMovieCacheState	state);
 void		swfdec_movie_update		(SwfdecMovie *		movie);
diff --git a/libswfdec/swfdec_movie_as_drawing.c b/libswfdec/swfdec_movie_as_drawing.c
index f11810f..599a553 100644
--- a/libswfdec/swfdec_movie_as_drawing.c
+++ b/libswfdec/swfdec_movie_as_drawing.c
@@ -288,10 +288,11 @@ swfdec_spite_movie_recompute_draw (SwfdecMovie *movie, SwfdecDraw *draw)
 {
   swfdec_draw_recompute (draw);
   if (swfdec_rect_inside (&movie->draw_extents, &draw->extents)) {
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   } else {
+    swfdec_movie_invalidate_next (movie);
     swfdec_rect_union (&movie->draw_extents, &movie->draw_extents, &draw->extents);
-    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_CONTENTS);
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_EXTENTS);
   }
 }
 
@@ -399,7 +400,7 @@ swfdec_sprite_movie_clear (SwfdecAsContext *cx, SwfdecAsObject *object,
   SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE, &movie, "");
   if (movie->draws == NULL)
     return;
-  swfdec_movie_invalidate (movie);
+  swfdec_movie_invalidate_last (movie);
   swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_EXTENTS);
   swfdec_rect_init_empty (&movie->draw_extents);
   g_slist_foreach (movie->draws, (GFunc) g_object_unref, NULL);
diff --git a/libswfdec/swfdec_movie_asprops.c b/libswfdec/swfdec_movie_asprops.c
index 6456aa9..c2985a5 100644
--- a/libswfdec/swfdec_movie_asprops.c
+++ b/libswfdec/swfdec_movie_asprops.c
@@ -58,8 +58,8 @@ mc_x_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   movie->modified = TRUE;
   d = SWFDEC_DOUBLE_TO_TWIPS (d);
   if (d != movie->matrix.x0) {
-    movie->matrix.x0 = d;
     swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
+    movie->matrix.x0 = d;
   }
 }
 
@@ -86,8 +86,8 @@ mc_y_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   movie->modified = TRUE;
   d = SWFDEC_DOUBLE_TO_TWIPS (d);
   if (d != movie->matrix.y0) {
-    movie->matrix.y0 = d;
     swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
+    movie->matrix.y0 = d;
   }
 }
 
@@ -109,8 +109,8 @@ mc_xscale_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   }
   movie->modified = TRUE;
   if (movie->xscale != d) {
-    movie->xscale = d;
     swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
+    movie->xscale = d;
   }
 }
 
@@ -132,8 +132,8 @@ mc_yscale_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   }
   movie->modified = TRUE;
   if (movie->yscale != d) {
-    movie->yscale = d;
     swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
+    movie->yscale = d;
   }
 }
 
@@ -195,7 +195,7 @@ mc_alpha_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   alpha = d * 256.0 / 100.0;
   if (alpha != movie->color_transform.aa) {
     movie->color_transform.aa = alpha;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
 }
 
@@ -213,7 +213,7 @@ mc_visible_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   b = swfdec_as_value_to_boolean (SWFDEC_AS_OBJECT (movie)->context, val);
   if (b != movie->visible) {
     movie->visible = b;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
 }
 
@@ -249,12 +249,13 @@ mc_width_set (SwfdecMovie *movie, const SwfdecAsValue *val)
     d = 100 * d / cur;
     if (d == movie->xscale)
       return;
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->xscale = d;
   } else {
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->xscale = 0;
     movie->yscale = 0;
   }
-  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
 }
 
 static void
@@ -289,12 +290,13 @@ mc_height_set (SwfdecMovie *movie, const SwfdecAsValue *val)
     d = 100 * d / cur;
     if (d == movie->yscale)
       return;
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->yscale = d;
   } else {
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->xscale = 0;
     movie->yscale = 0;
   }
-  swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
 }
 
 static void
@@ -326,8 +328,8 @@ mc_rotation_set (SwfdecMovie *movie, const SwfdecAsValue *val)
   }
   movie->modified = TRUE;
   if (movie->rotation != d) {
-    movie->rotation = d;
     swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
+    movie->rotation = d;
   }
 }
 
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 60f1af9..62c3e38 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -961,9 +961,9 @@ swfdec_player_update_drag_movie (SwfdecPlayer *player)
   y = CLAMP (y, player->mouse_drag_rect.y0, player->mouse_drag_rect.y1);
   SWFDEC_LOG ("mouse is at %g %g, originally (%g %g)", x, y, player->mouse_x, player->mouse_y);
   if (x != movie->matrix.x0 || y != movie->matrix.y0) {
+    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
     movie->matrix.x0 = x;
     movie->matrix.y0 = y;
-    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);
   }
 }
 
@@ -1350,14 +1350,9 @@ swfdec_player_do_advance (SwfdecPlayer *player, gulong msecs, guint audio_sample
 void
 swfdec_player_perform_actions (SwfdecPlayer *player)
 {
-  GList *walk;
-
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
   while (swfdec_player_do_action (player));
-  for (walk = player->roots; walk; walk = walk->next) {
-    swfdec_movie_update (walk->data);
-  }
 }
 
 /* used for breakpoints */
@@ -1389,6 +1384,31 @@ swfdec_player_lock (SwfdecPlayer *player)
   return TRUE;
 }
 
+/* runs queued invalidations for all movies and resets the movies */
+static void
+swfdec_player_update_movies (SwfdecPlayer *player)
+{
+  SwfdecMovie *movie;
+  GList *walk;
+
+  /* FIXME: This g_list_last could be slow */
+  for (walk = g_list_last (player->movies); walk; walk = walk->prev) {
+    movie = walk->data;
+
+    swfdec_movie_update (movie);
+    if (movie->invalidate_last) {
+      cairo_matrix_t matrix;
+
+      if (movie->parent)
+	swfdec_movie_local_to_global_matrix (movie->parent, &matrix);
+      else
+	cairo_matrix_init_identity (&matrix);
+      swfdec_movie_invalidate (movie, &matrix, TRUE);
+      movie->invalidate_last = FALSE;
+    }
+  }
+}
+
 /* used for breakpoints */
 void
 swfdec_player_unlock_soft (SwfdecPlayer *player)
@@ -1397,6 +1417,7 @@ swfdec_player_unlock_soft (SwfdecPlayer *player)
 
   SWFDEC_DEBUG ("UNLOCK");
   g_timer_stop (player->runtime);
+  swfdec_player_update_movies (player);
   swfdec_player_update_mouse_cursor (player);
   g_object_thaw_notify (G_OBJECT (player));
   swfdec_player_emit_signals (player);
@@ -1746,11 +1767,8 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
   SwfdecRect tmp;
   guint i;
 
-  if (swfdec_rect_is_empty (rect)) {
-    SWFDEC_ERROR ("called with an empty rectanle. In theory this shouldn't happen.");
-    SWFDEC_ERROR ("  However, degenerate matrixes can cause this. We need a fix for that.");
+  if (swfdec_rect_is_empty (rect))
     return;
-  }
 
   tmp = *rect;
   swfdec_player_global_to_stage (player, &tmp.x0, &tmp.y0);
@@ -1763,6 +1781,7 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
   if (swfdec_rectangle_is_empty (&r))
     return;
 
+  SWFDEC_LOG ("  invalidating %d %d  %d %d", r.x, r.y, r.width, r.height);
   /* FIXME: get region code into swfdec? */
   for (i = 0; i < player->invalidations->len; i++) {
     SwfdecRectangle *cur = &g_array_index (player->invalidations, SwfdecRectangle, i);
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 88783b5..887c102 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -94,7 +94,7 @@ swfdec_resource_loader_target_image (SwfdecResource *instance)
     movie->sprite = dec->main_sprite;
     g_assert (movie->sprite->parse_frame > 0);
     movie->n_frames = movie->sprite->n_frames;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
     swfdec_resource_check_rights (instance);
     if (swfdec_resource_is_root (instance)) {
       swfdec_movie_initialize (SWFDEC_MOVIE (movie));
@@ -561,8 +561,9 @@ swfdec_resource_emit_on_load_init (SwfdecResource *resource)
   if (resource->movie && SWFDEC_IS_IMAGE_DECODER (resource->decoder)) {
     SwfdecImage *image = SWFDEC_IMAGE_DECODER (resource->decoder)->image;
     if (image) {
+      swfdec_movie_invalidate_next (SWFDEC_MOVIE (resource->movie));
+      swfdec_movie_queue_update (SWFDEC_MOVIE (resource->movie), SWFDEC_MOVIE_INVALID_EXTENTS);
       SWFDEC_MOVIE (resource->movie)->image = g_object_ref (image);
-      swfdec_movie_queue_update (SWFDEC_MOVIE (resource->movie), SWFDEC_MOVIE_INVALID_CONTENTS);
     }
   }
   swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadInit, FALSE, NULL, 0);
diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index baacfad..b4b5774 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -214,7 +214,7 @@ swfdec_sprite_movie_set_blendMode (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   if ((guint)blend_mode != movie->blend_mode) {
     movie->blend_mode = blend_mode;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
 }
 
@@ -600,9 +600,9 @@ swfdec_sprite_movie_createEmptyMovieClip (SwfdecAsContext *cx, SwfdecAsObject *o
 static void
 swfdec_sprite_movie_copy_props (SwfdecMovie *target, SwfdecMovie *src)
 {
+  swfdec_movie_queue_update (target, SWFDEC_MOVIE_INVALID_MATRIX);
   target->matrix = src->matrix;
   target->color_transform = src->color_transform;
-  swfdec_movie_queue_update (target, SWFDEC_MOVIE_INVALID_MATRIX);
 }
 
 static gboolean
@@ -799,10 +799,10 @@ swfdec_sprite_movie_setMask (SwfdecAsContext *cx, SwfdecAsObject *object,
   movie->mask_of = NULL;
   if (movie->clip_depth) {
     g_assert (movie->parent);
-    swfdec_movie_invalidate (movie->parent);
+    swfdec_movie_invalidate_last (movie->parent);
     movie->clip_depth = 0;
   } else {
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
   if (mask) {
     if (mask->masked_by)
@@ -811,13 +811,13 @@ swfdec_sprite_movie_setMask (SwfdecAsContext *cx, SwfdecAsObject *object,
       mask->mask_of->masked_by = NULL;
     mask->masked_by = NULL;
     mask->mask_of = movie;
-    swfdec_movie_invalidate (mask);
+    swfdec_movie_invalidate_last (mask);
     if (mask->clip_depth) {
       g_assert (mask->parent);
-      swfdec_movie_invalidate (mask->parent);
+      swfdec_movie_invalidate_last (mask->parent);
       mask->clip_depth = 0;
     } else {
-      swfdec_movie_invalidate (mask);
+      swfdec_movie_invalidate_last (mask);
     }
   }
 }
diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c
index 3dba372..50b7a57 100644
--- a/libswfdec/swfdec_text_field_movie.c
+++ b/libswfdec/swfdec_text_field_movie.c
@@ -49,6 +49,16 @@ swfdec_text_field_movie_update_extents (SwfdecMovie *movie,
 }
 
 static void
+swfdec_text_field_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
+{
+  SwfdecRect rect;
+  
+  swfdec_rect_transform (&rect, 
+    &SWFDEC_GRAPHIC (SWFDEC_TEXT_FIELD_MOVIE (movie)->text)->extents, matrix);
+  swfdec_player_invalidate (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context), &rect);
+}
+
+static void
 swfdec_text_field_movie_ensure_asterisks (SwfdecTextFieldMovie *text,
     guint length)
 {
@@ -1002,7 +1012,7 @@ swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
       graphic->extents.y1 - graphic->extents.y0 == height)
     return FALSE;
 
-  swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+  swfdec_movie_invalidate_next (SWFDEC_MOVIE (text));
 
   if (!text->text->word_wrap && graphic->extents.x1 -
       graphic->extents.x0 != width)
@@ -1031,7 +1041,7 @@ swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
   }
 
   swfdec_movie_queue_update (SWFDEC_MOVIE (text),
-      SWFDEC_MOVIE_INVALID_CONTENTS);
+      SWFDEC_MOVIE_INVALID_EXTENTS);
 
   return TRUE;
 }
@@ -1204,6 +1214,7 @@ swfdec_text_field_movie_class_init (SwfdecTextFieldMovieClass * g_class)
   movie_class->iterate_start = swfdec_text_field_movie_iterate;
   movie_class->update_extents = swfdec_text_field_movie_update_extents;
   movie_class->render = swfdec_text_field_movie_render;
+  movie_class->invalidate = swfdec_text_field_movie_invalidate;
 }
 
 static void
@@ -1536,7 +1547,7 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text,
       end_index - start_index);
   text->input = g_string_insert (text->input, start_index, str);
 
-  swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   swfdec_text_field_movie_auto_size (text);
   swfdec_text_field_movie_update_scroll (text, TRUE);
 }
@@ -1597,7 +1608,7 @@ swfdec_text_field_movie_set_text (SwfdecTextFieldMovie *text, const char *str,
     }
   }
 
-  swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   swfdec_text_field_movie_auto_size (text);
   swfdec_text_field_movie_update_scroll (text, TRUE);
 }
diff --git a/libswfdec/swfdec_text_field_movie_as.c b/libswfdec/swfdec_text_field_movie_as.c
index 7687280..33578b3 100644
--- a/libswfdec/swfdec_text_field_movie_as.c
+++ b/libswfdec/swfdec_text_field_movie_as.c
@@ -473,7 +473,7 @@ swfdec_text_field_movie_set_background (SwfdecAsContext *cx,
 
   if (text->text->background != value) {
     text->text->background = value;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -506,7 +506,7 @@ swfdec_text_field_movie_set_backgroundColor (SwfdecAsContext *cx,
   color = swfdec_text_field_movie_int_to_color (cx, value);
   if (text->background_color != color) {
     text->background_color = color;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -536,7 +536,7 @@ swfdec_text_field_movie_set_border (SwfdecAsContext *cx,
 
   if (text->text->border != value) {
     text->text->border = value;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -570,7 +570,7 @@ swfdec_text_field_movie_set_borderColor (SwfdecAsContext *cx,
   color = swfdec_text_field_movie_int_to_color (cx, value);
   if (text->border_color != color) {
     text->border_color = color;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -615,7 +615,7 @@ swfdec_text_field_movie_do_set_hscroll (SwfdecAsContext *cx,
   if (value != text->hscroll) {
     text->hscroll = value;
     text->scroll_changed = TRUE;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -701,7 +701,7 @@ swfdec_text_field_movie_do_set_scroll (SwfdecAsContext *cx,
     text->scroll_bottom += value - text->scroll;
     text->scroll = value;
     text->scroll_changed = TRUE;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -809,7 +809,7 @@ swfdec_text_field_movie_set_password (SwfdecAsContext *cx,
       text->asterisks = NULL;
       text->asterisks_length = 0;
     }
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   }
 }
 
@@ -839,7 +839,7 @@ swfdec_text_field_movie_set_wordWrap (SwfdecAsContext *cx,
 
   if (text->text->word_wrap != value) {
     text->text->word_wrap = value;
-    swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
     swfdec_text_field_movie_auto_size (text);
     // special case: don't set scrolling
   }
@@ -1140,7 +1140,7 @@ swfdec_text_field_movie_setTextFormat (SwfdecAsContext *cx,
       g_utf8_offset_to_pointer (text->input->str, end_index) -
       text->input->str);
 
-  swfdec_movie_invalidate (SWFDEC_MOVIE (text));
+  swfdec_movie_invalidate_last (SWFDEC_MOVIE (text));
   swfdec_text_field_movie_auto_size (text);
   // special case: update the max values, not the current values
   swfdec_text_field_movie_update_scroll (text, FALSE);
diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c
index a3ebd75..7ee48cf 100644
--- a/libswfdec/swfdec_video_movie.c
+++ b/libswfdec/swfdec_video_movie.c
@@ -110,7 +110,7 @@ swfdec_video_movie_set_ratio (SwfdecMovie *movie)
 
   if (video->input->set_ratio) {
     video->needs_update = TRUE;
-    swfdec_movie_invalidate (movie);
+    swfdec_movie_invalidate_last (movie);
   }
 }
 
@@ -151,7 +151,7 @@ swfdec_video_movie_set_input (SwfdecVideoMovie *movie, SwfdecVideoMovieInput *in
   if (input == NULL)
     return;
   if (movie->input->set_ratio) {
-    swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+    swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
   }
   movie->needs_update = TRUE;
   if (input->connect)
@@ -167,7 +167,7 @@ swfdec_video_movie_clear (SwfdecVideoMovie *movie)
     cairo_surface_destroy (movie->image);
     movie->image = NULL;
   }
-  swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+  swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
 }
 
 void
@@ -180,6 +180,6 @@ swfdec_video_movie_new_image (SwfdecVideoMovie *movie)
     movie->image = NULL;
   }
   movie->needs_update = TRUE;
-  swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+  swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
 }
 
commit 6f3ebc54441b16e203ed0da9cbfd98a286634c93
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Dec 6 15:32:30 2007 +0100

    handle ExportAssets tag in sprites

diff --git a/test/dump.c b/test/dump.c
index 77bd382..01a1776 100644
--- a/test/dump.c
+++ b/test/dump.c
@@ -150,6 +150,9 @@ dump_sprite (SwfdecSwfDecoder *dec, SwfdecSprite *s)
 	  /* FIXME add info about what sound etc */
 	  g_print ("   %4u start sound\n", j);
 	  break;
+	case SWFDEC_TAG_EXPORTASSETS:
+	  g_print ("   %4u export\n", j);
+	  break;
 	default:
 	  g_assert_not_reached ();
       }
commit 48b4a9806f044140b8ab8dca6a962649b1f626b5
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Dec 4 13:11:46 2007 +0100

    be paranoid about empty buffers
    
    This shouldn't happen in theory, because empty files aren't detected as images,
    but who knows...

diff --git a/libswfdec/swfdec_image_decoder.c b/libswfdec/swfdec_image_decoder.c
index 49443c9..522859b 100644
--- a/libswfdec/swfdec_image_decoder.c
+++ b/libswfdec/swfdec_image_decoder.c
@@ -82,10 +82,16 @@ swfdec_image_decoder_eof (SwfdecDecoder *dec)
 {
   SwfdecImageDecoder *image = SWFDEC_IMAGE_DECODER (dec);
   SwfdecBuffer *buffer;
+  guint depth;
 
   if (image->queue == NULL)
     return 0;
-  /* FIXME: size checking */
+  depth = swfdec_buffer_queue_get_depth (image->queue);
+  if (depth == 0) {
+    swfdec_buffer_queue_unref (image->queue);
+    image->queue = NULL;
+    return SWFDEC_STATUS_ERROR;
+  }
   buffer = swfdec_buffer_queue_pull (image->queue,
       swfdec_buffer_queue_get_depth (image->queue));
   swfdec_buffer_queue_unref (image->queue);
commit e02f745d8268b7b3c61688d1202ef8372bfdf2a3
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Dec 4 12:30:23 2007 +0100

    add test for just-fixed crash

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index ac51ffa..b8231c0 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -613,6 +613,9 @@ EXTRA_DIST = \
 	crash-0.5.3-text-field-root-variable-7.swf.trace \
 	crash-0.5.3-text-field-root-variable-8.swf \
 	crash-0.5.3-text-field-root-variable-8.swf.trace \
+	crash-0.5.4-13379-catch-in-register.swf \
+	crash-0.5.4-13379-catch-in-register.swf.trace \
+	crash-0.5.4-13379-catch-in-register.xml \
 	crash-0.5.4-goto-in-constructor.c \
 	crash-0.5.4-goto-in-constructor-5.swf \
 	crash-0.5.4-goto-in-constructor-5.swf.trace \
diff --git a/test/trace/crash-0.5.4-13379-catch-in-register.swf b/test/trace/crash-0.5.4-13379-catch-in-register.swf
new file mode 100644
index 0000000..56dcafc
Binary files /dev/null and b/test/trace/crash-0.5.4-13379-catch-in-register.swf differ
diff --git a/test/trace/crash-0.5.4-13379-catch-in-register.swf.trace b/test/trace/crash-0.5.4-13379-catch-in-register.swf.trace
new file mode 100644
index 0000000..e69de29
diff --git a/test/trace/crash-0.5.4-13379-catch-in-register.xml b/test/trace/crash-0.5.4-13379-catch-in-register.xml
new file mode 100644
index 0000000..50fa8c8
--- /dev/null
+++ b/test/trace/crash-0.5.4-13379-catch-in-register.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <Header framerate="1" frames="1">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" useNetwork="1"/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="hi"/>
+              <String value="foo"/>
+              <String value="fscommand:quit"/>
+              <String value=""/>
+            </strings>
+          </Dictionary>
+          <DeclareFunction2 name="foo" argc="0" regc="0" preloadThis="0" suppressThis="0" preloadArguments="0" suppressArguments="0" preloadSuper="0" suppressSuper="0" preloadRoot="0" preloadParent="0" reserved="0" preloadGlobal="0">
+            <args/>
+            <actions>
+              <Try doFinally="0" doCatch="1" trySize="11" catchSize="1" finallySize="0" reg="0"/>
+              <PushData>
+                <items>
+                  <StackUndefined/>
+                </items>
+              </PushData>
+              <Return/>
+              <PushData>
+                <items>
+                  <StackDictionaryLookup index="0"/>
+                </items>
+              </PushData>
+              <Trace/>
+              <Trace/>
+            </actions>
+          </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackDictionaryLookup index="1"/>
+            </items>
+          </PushData>
+          <CallFunction/>
+          <Throw/>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="2"/>
+              <StackDictionaryLookup index="3"/>
+            </items>
+          </PushData>
+          <GetURL2 method="64"/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit d95178f58e7095e8d95756baaf5f2b3fe1d1d937
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Dec 4 12:26:39 2007 +0100

    Don't segfault during frame cleanup when exceptions are present (fixes #13379)

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 639018c..c37b2bf 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2634,8 +2634,8 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
 
     if (try_data->use_register)
     {
-      if (swfdec_action_has_register (cx, try_data->register_number)) {
-	cx->frame->registers[try_data->register_number] = val;
+      if (try_data->register_number < frame->n_registers) {
+	frame->registers[try_data->register_number] = val;
       } else {
 	SWFDEC_ERROR ("cannot set Error to register %u: not enough registers",
 	    try_data->register_number);


More information about the Swfdec mailing list