[Swfdec] 8 commits - doc/swfdec-sections.txt libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_interpret.c test/trace
Pekka Lampila
medar at kemper.freedesktop.org
Fri Oct 26 16:36:19 PDT 2007
doc/swfdec-sections.txt | 2
libswfdec/swfdec_as_context.c | 54 ++++++++++++++++++-
libswfdec/swfdec_as_context.h | 9 ++-
libswfdec/swfdec_as_interpret.c | 79 ++++++++++++++--------------
test/trace/Makefile.am | 7 ++
test/trace/try-throw-in-finally-6.swf |binary
test/trace/try-throw-in-finally-6.swf.trace | 2
test/trace/try-throw-in-finally-7.swf |binary
test/trace/try-throw-in-finally-7.swf.trace | 2
test/trace/try-throw-in-finally-8.swf |binary
test/trace/try-throw-in-finally-8.swf.trace | 2
test/trace/try-throw-in-finally.as | 17 ++++++
12 files changed, 130 insertions(+), 44 deletions(-)
New commits:
commit fae96ec372e251304845515d222ee784574d1a7b
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 02:19:19 2007 +0300
Add a test to see what exception gets thrown out of Try action's finally block
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 78767a2..2ff2699 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -2054,6 +2054,13 @@ EXTRA_DIST = \
transform2.swf \
transform2.swf.trace \
transform2.swf.trace.org \
+ try-throw-in-finally.as \
+ try-throw-in-finally-6.swf \
+ try-throw-in-finally-6.swf.trace \
+ try-throw-in-finally-7.swf \
+ try-throw-in-finally-7.swf.trace \
+ try-throw-in-finally-8.swf \
+ try-throw-in-finally-8.swf.trace \
undefined-tostring.swf \
undefined-tostring.swf.trace \
undefined1.swf \
diff --git a/test/trace/try-throw-in-finally-5.swf b/test/trace/try-throw-in-finally-5.swf
new file mode 100644
index 0000000..e69de29
diff --git a/test/trace/try-throw-in-finally-6.swf b/test/trace/try-throw-in-finally-6.swf
new file mode 100644
index 0000000..99fb7d4
Binary files /dev/null and b/test/trace/try-throw-in-finally-6.swf differ
diff --git a/test/trace/try-throw-in-finally-6.swf.trace b/test/trace/try-throw-in-finally-6.swf.trace
new file mode 100644
index 0000000..d8d2aa6
--- /dev/null
+++ b/test/trace/try-throw-in-finally-6.swf.trace
@@ -0,0 +1,2 @@
+Test what exception is thrown out of finally
+finally
diff --git a/test/trace/try-throw-in-finally-7.swf b/test/trace/try-throw-in-finally-7.swf
new file mode 100644
index 0000000..85ba3ef
Binary files /dev/null and b/test/trace/try-throw-in-finally-7.swf differ
diff --git a/test/trace/try-throw-in-finally-7.swf.trace b/test/trace/try-throw-in-finally-7.swf.trace
new file mode 100644
index 0000000..d8d2aa6
--- /dev/null
+++ b/test/trace/try-throw-in-finally-7.swf.trace
@@ -0,0 +1,2 @@
+Test what exception is thrown out of finally
+finally
diff --git a/test/trace/try-throw-in-finally-8.swf b/test/trace/try-throw-in-finally-8.swf
new file mode 100644
index 0000000..7390efb
Binary files /dev/null and b/test/trace/try-throw-in-finally-8.swf differ
diff --git a/test/trace/try-throw-in-finally-8.swf.trace b/test/trace/try-throw-in-finally-8.swf.trace
new file mode 100644
index 0000000..d8d2aa6
--- /dev/null
+++ b/test/trace/try-throw-in-finally-8.swf.trace
@@ -0,0 +1,2 @@
+Test what exception is thrown out of finally
+finally
diff --git a/test/trace/try-throw-in-finally.as b/test/trace/try-throw-in-finally.as
new file mode 100644
index 0000000..b80ef4e
--- /dev/null
+++ b/test/trace/try-throw-in-finally.as
@@ -0,0 +1,17 @@
+// makeswf -v 7 -r 1 -o try-throw-in-finally-7.swf try-throw-in-finally.as
+
+trace ("Test what exception is thrown out of finally");
+
+try {
+ try {
+ throw "try";
+ } catch (exception) {
+ throw "catch";
+ } finally {
+ throw "finally";
+ };
+} catch (exception) {
+ trace (exception);
+};
+
+loadMovie ("FSCommand:quit", "");
commit 65fb16c53625ead227c6dfafd0d9da75a43b95a8
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 02:13:01 2007 +0300
Rename context->throwing to exception and throw_value to exception_value
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 403e03d..663a15c 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -361,7 +361,7 @@ static void
swfdec_as_context_do_mark (SwfdecAsContext *context)
{
swfdec_as_object_mark (context->global);
- swfdec_as_value_mark (&context->throw_value);
+ swfdec_as_value_mark (&context->exception_value);
swfdec_as_object_mark (context->Function);
swfdec_as_object_mark (context->Function_prototype);
swfdec_as_object_mark (context->Object);
@@ -685,10 +685,10 @@ swfdec_as_context_throw (SwfdecAsContext *context, const SwfdecAsValue *value)
{
g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
- g_return_if_fail (!context->throwing);
+ g_return_if_fail (!context->exception);
- context->throwing = TRUE;
- context->throw_value = *value;
+ context->exception = TRUE;
+ context->exception_value = *value;
}
/**
@@ -706,14 +706,14 @@ swfdec_as_context_catch (SwfdecAsContext *context, SwfdecAsValue *value)
{
g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
- if (!context->throwing)
+ if (!context->exception)
return FALSE;
if (value != NULL)
- *value = context->throw_value;
+ *value = context->exception_value;
- context->throwing = FALSE;
- SWFDEC_AS_VALUE_SET_UNDEFINED (&context->throw_value);
+ context->exception = FALSE;
+ SWFDEC_AS_VALUE_SET_UNDEFINED (&context->exception_value);
return TRUE;
}
@@ -858,14 +858,14 @@ start:
while (context->state < SWFDEC_AS_CONTEXT_ABORTED) {
// in case of an exception, skip blocks until exception is cleared or we
// run out of blocks
- while (context->throwing && frame->blocks->len > 0) {
+ while (context->exception && frame->blocks->len > 0) {
frame->pc = frame->block_end;
swfdec_as_frame_check_block (frame);
pc = frame->pc;
}
- if (context->throwing) {
+ if (context->exception) {
SWFDEC_ERROR ("Unhandled exception: %s",
- swfdec_as_value_to_string (context, &context->throw_value));
+ swfdec_as_value_to_string (context, &context->exception_value));
goto error;
}
if (check_block && (pc < frame->block_start || pc >= frame->block_end)) {
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 145f647..df09fa2 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -63,8 +63,8 @@ struct _SwfdecAsContext {
unsigned int call_depth; /* current depth of call stack (equals length of frame list) */
SwfdecAsFrame * frame; /* topmost stack frame */
SwfdecAsFrame * last_frame; /* last frame before calling context_run */
- gboolean throwing; /* whether we are throwing an error */
- SwfdecAsValue throw_value; /* the error object being thrown */
+ gboolean exception; /* whether we are throwing an exception */
+ SwfdecAsValue exception_value; /* value of the exception being thrown, can be anything including undefined */
/* stack */
SwfdecAsValue * base; /* stack base */
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 9155290..3defeca 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2583,17 +2583,17 @@ swfdec_action_try_data_unref (gpointer data)
static void
swfdec_action_try_end_finally (SwfdecAsFrame *frame, gpointer data)
{
- SwfdecAsValue *exception = data;
+ SwfdecAsValue *exception_value = data;
SwfdecAsContext *cx;
g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
- g_return_if_fail (SWFDEC_IS_AS_VALUE (exception));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (exception_value));
cx = SWFDEC_AS_OBJECT (frame)->context;
// finally has ended and we had exception stored, throw it
- if (!cx->throwing)
- swfdec_as_context_throw (cx, exception);
+ if (!cx->exception)
+ swfdec_as_context_throw (cx, exception_value);
swfdec_as_frame_pop_block (frame);
}
@@ -2603,7 +2603,7 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
{
TryData *try_data = data;
SwfdecAsContext *cx;
- SwfdecAsValue *exception, val;
+ SwfdecAsValue *exception_value, val;
g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
g_return_if_fail (try_data != NULL);
@@ -2619,13 +2619,13 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
// create new block for finally, passing the exception
// clear exception from the context
- exception = g_malloc (sizeof (SwfdecAsValue));
- *exception = val;
+ exception_value = g_malloc (sizeof (SwfdecAsValue));
+ *exception_value = val;
// FIXME: the exception value is not marked while finally block runs
swfdec_as_frame_push_block (frame, try_data->finally_start,
try_data->finally_start + try_data->finally_size,
- swfdec_action_try_end_finally, exception, g_free);
+ swfdec_action_try_end_finally, exception_value, g_free);
}
swfdec_action_try_data_unref (try_data);
commit 5c3f06cbeb5ee318b13b99565253b2f5ae7637ae
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 02:08:13 2007 +0300
Make Try and Throw implementations use the new throw and catch functions
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f4ecef7..9155290 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2538,8 +2538,7 @@ static void
swfdec_action_throw (SwfdecAsContext *cx, guint action, const guint8 *data,
guint len)
{
- cx->throwing = TRUE;
- cx->throw_value = *swfdec_as_stack_pop (cx);
+ swfdec_as_context_throw (cx, swfdec_as_stack_pop (cx));
}
typedef struct {
@@ -2584,19 +2583,17 @@ swfdec_action_try_data_unref (gpointer data)
static void
swfdec_action_try_end_finally (SwfdecAsFrame *frame, gpointer data)
{
- SwfdecAsValue *error = data;
+ SwfdecAsValue *exception = data;
SwfdecAsContext *cx;
g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
- g_return_if_fail (SWFDEC_IS_AS_VALUE (error));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (exception));
cx = SWFDEC_AS_OBJECT (frame)->context;
// finally has ended and we had exception stored, throw it
- if (!cx->throwing) {
- cx->throwing = TRUE;
- cx->throw_value = *error;
- }
+ if (!cx->throwing)
+ swfdec_as_context_throw (cx, exception);
swfdec_as_frame_pop_block (frame);
}
@@ -2606,7 +2603,7 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
{
TryData *try_data = data;
SwfdecAsContext *cx;
- SwfdecAsValue *error;
+ SwfdecAsValue *exception, val;
g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
g_return_if_fail (try_data != NULL);
@@ -2616,22 +2613,19 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
swfdec_action_try_data_ref (try_data);
swfdec_as_frame_pop_block (frame);
- if (cx->throwing)
+ if (swfdec_as_context_catch (cx, &val))
{
// we got an exception while in catch block:
// create new block for finally, passing the exception
// clear exception from the context
- error = g_malloc (sizeof (SwfdecAsValue));
- *error = cx->throw_value;
+ exception = g_malloc (sizeof (SwfdecAsValue));
+ *exception = val;
- // FIXME: the error value is not marked while finally block runs
+ // FIXME: the exception value is not marked while finally block runs
swfdec_as_frame_push_block (frame, try_data->finally_start,
try_data->finally_start + try_data->finally_size,
- swfdec_action_try_end_finally, error, g_free);
-
- cx->throwing = FALSE;
- SWFDEC_AS_VALUE_SET_UNDEFINED (&cx->throw_value);
+ swfdec_action_try_end_finally, exception, g_free);
}
swfdec_action_try_data_unref (try_data);
@@ -2642,6 +2636,7 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
{
TryData *try_data = data;
SwfdecAsContext *cx;
+ SwfdecAsValue val;
g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
g_return_if_fail (try_data != NULL);
@@ -2658,16 +2653,16 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
swfdec_action_try_data_ref (try_data);
swfdec_as_frame_pop_block (frame);
- if (cx->throwing)
+ if (swfdec_as_context_catch (cx, &val))
{
// we got an exception while in try block:
- // set the error variable
+ // set the exception variable
// add new block for catch
// clear exception from context
if (try_data->use_register)
{
if (swfdec_action_has_register (cx, try_data->register_number)) {
- cx->frame->registers[try_data->register_number] = cx->throw_value;
+ cx->frame->registers[try_data->register_number] = val;
} else {
SWFDEC_ERROR ("cannot set Error to register %u: not enough registers",
try_data->register_number);
@@ -2683,14 +2678,14 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
if (swfdec_action_get_movie_by_path (cx, s, &object, &rest)) {
if (object && rest) {
swfdec_as_object_set_variable (object,
- swfdec_as_context_get_string (cx, rest), &cx->throw_value);
+ swfdec_as_context_get_string (cx, rest), &val);
} else {
if (object) {
rest = s;
} else {
rest = swfdec_as_context_get_string (cx, rest);
}
- swfdec_as_frame_set_variable (frame, rest, &cx->throw_value);
+ swfdec_as_frame_set_variable (frame, rest, &val);
}
}
else
@@ -2704,9 +2699,6 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
swfdec_as_frame_push_block (frame, try_data->catch_start,
try_data->catch_start + try_data->catch_size,
swfdec_action_try_end_catch, try_data, swfdec_action_try_data_unref);
-
- cx->throwing = FALSE;
- SWFDEC_AS_VALUE_SET_UNDEFINED (&cx->throw_value);
}
swfdec_action_try_data_unref (try_data);
commit 3c105cb641d7c45ff98fd33bfc94f7162010d769
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 02:07:48 2007 +0300
Fix reversed assert in swfdec_as_context_throw
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index ed491b1..403e03d 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -685,7 +685,7 @@ swfdec_as_context_throw (SwfdecAsContext *context, const SwfdecAsValue *value)
{
g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
- g_return_if_fail (context->throwing);
+ g_return_if_fail (!context->throwing);
context->throwing = TRUE;
context->throw_value = *value;
commit eae34b29ae9c059478f7f85c9fb519fb67380b2f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 01:57:52 2007 +0300
Add swfdec_as_context_throw and swfdec_as_context_catch functions
diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index 2442538..2b3a774 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -307,6 +307,8 @@ swfdec_as_context_use_mem
swfdec_as_context_gc
swfdec_as_context_maybe_gc
swfdec_as_context_run
+swfdec_as_context_throw
+swfdec_as_context_catch
swfdec_as_context_unuse_mem
swfdec_as_context_eval
swfdec_as_context_eval_set
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 531ff00..ed491b1 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -673,6 +673,52 @@ swfdec_as_context_get_frame (SwfdecAsContext *context)
}
/**
+ * swfdec_as_context_throw:
+ * @context: a #SwfdecAsContext
+ * @value: a #SwfdecAsValue to be thrown
+ *
+ * Throws a new exception in the @context using the given @value. This function
+ * can only be called if the @context is not already throwing an exception.
+ **/
+void
+swfdec_as_context_throw (SwfdecAsContext *context, const SwfdecAsValue *value)
+{
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
+ g_return_if_fail (context->throwing);
+
+ context->throwing = TRUE;
+ context->throw_value = *value;
+}
+
+/**
+ * swfdec_as_context_catch:
+ * @context: a #SwfdecAsContext
+ * @value: a #SwfdecAsValue to be thrown
+ *
+ * Removes the currently thrown exception from @context and sets @value to the
+ * thrown value
+ *
+ * Returns: %TRUE if an exception was catched, %FALSE otherwise
+ **/
+gboolean
+swfdec_as_context_catch (SwfdecAsContext *context, SwfdecAsValue *value)
+{
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
+
+ if (!context->throwing)
+ return FALSE;
+
+ if (value != NULL)
+ *value = context->throw_value;
+
+ context->throwing = FALSE;
+ SWFDEC_AS_VALUE_SET_UNDEFINED (&context->throw_value);
+
+ return TRUE;
+}
+
+/**
* swfdec_as_context_get_time:
* @context: a #SwfdecAsContext
* @tv: a #GTimeVal to be set to the context's time
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 0f062c8..145f647 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -113,6 +113,11 @@ const char * swfdec_as_context_give_string (SwfdecAsContext * context,
void swfdec_as_context_abort (SwfdecAsContext * context,
const char * reason);
+void swfdec_as_context_throw (SwfdecAsContext * context,
+ const SwfdecAsValue * value);
+gboolean swfdec_as_context_catch (SwfdecAsContext * context,
+ SwfdecAsValue * value);
+
gboolean swfdec_as_context_use_mem (SwfdecAsContext * context,
gsize bytes);
void swfdec_as_context_unuse_mem (SwfdecAsContext * context,
commit c9d43105c71931ba583ff12dd0adf5624e50aaa8
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 01:19:50 2007 +0300
Don't abort when we get an unhandled exception
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 31a9bdf..531ff00 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -818,7 +818,8 @@ start:
pc = frame->pc;
}
if (context->throwing) {
- swfdec_as_context_abort (context, "Unhandled exception");
+ SWFDEC_ERROR ("Unhandled exception: %s",
+ swfdec_as_value_to_string (context, &context->throw_value));
goto error;
}
if (check_block && (pc < frame->block_start || pc >= frame->block_end)) {
commit c4f51df1f6b9ac1b2eea5b22ec43de5a1caa70a8
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 01:09:08 2007 +0300
Mark context->throw_value
Add FIXME comment about not marking throw_value while running finally loop
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 6e35622..31a9bdf 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -361,6 +361,7 @@ static void
swfdec_as_context_do_mark (SwfdecAsContext *context)
{
swfdec_as_object_mark (context->global);
+ swfdec_as_value_mark (&context->throw_value);
swfdec_as_object_mark (context->Function);
swfdec_as_object_mark (context->Function_prototype);
swfdec_as_object_mark (context->Object);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f578829..f4ecef7 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2625,6 +2625,7 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
error = g_malloc (sizeof (SwfdecAsValue));
*error = cx->throw_value;
+ // FIXME: the error value is not marked while finally block runs
swfdec_as_frame_push_block (frame, try_data->finally_start,
try_data->finally_start + try_data->finally_size,
swfdec_action_try_end_finally, error, g_free);
commit d5cff3948b57d9b3bc44eb88d652eda10c0d41eb
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Sat Oct 27 00:58:45 2007 +0300
Clean up Try code. Fix couple of bugs
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index cf41ff0..f578829 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2544,9 +2544,8 @@ swfdec_action_throw (SwfdecAsContext *cx, guint action, const guint8 *data,
typedef struct {
int ref_count;
- const guint8 * start;
- gboolean catch;
- gboolean finally;
+ const guint8 * catch_start;
+ const guint8 * finally_start;
guint catch_size;
guint finally_size;
@@ -2626,8 +2625,8 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
error = g_malloc (sizeof (SwfdecAsValue));
*error = cx->throw_value;
- swfdec_as_frame_push_block (frame, try_data->start + try_data->catch_size,
- try_data->start + try_data->catch_size + try_data->finally_size,
+ swfdec_as_frame_push_block (frame, try_data->finally_start,
+ try_data->finally_start + try_data->finally_size,
swfdec_action_try_end_finally, error, g_free);
cx->throwing = FALSE;
@@ -2648,7 +2647,7 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
// if we don't have a catch block, we handle try block exactly like it was
// catch block
- if (!try_data->catch) {
+ if (!try_data->catch_start) {
swfdec_action_try_end_catch (frame, try_data);
return;
}
@@ -2701,9 +2700,9 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
}
swfdec_action_try_data_ref (try_data);
- swfdec_as_frame_push_block (frame, try_data->start,
- try_data->start + try_data->catch_size, swfdec_action_try_end_catch,
- try_data, swfdec_action_try_data_unref);
+ swfdec_as_frame_push_block (frame, try_data->catch_start,
+ try_data->catch_start + try_data->catch_size,
+ swfdec_action_try_end_catch, try_data, swfdec_action_try_data_unref);
cx->throwing = FALSE;
SWFDEC_AS_VALUE_SET_UNDEFINED (&cx->throw_value);
@@ -2718,6 +2717,7 @@ swfdec_action_try (SwfdecAsContext *cx, guint action, const guint8 *data, guint
SwfdecBits bits;
TryData *try_data;
guint try_size;
+ gboolean use_finally, use_catch;
if (len <= 8) {
SWFDEC_ERROR ("With action requires a length of at least 8, but got %u",
@@ -2727,18 +2727,22 @@ swfdec_action_try (SwfdecAsContext *cx, guint action, const guint8 *data, guint
}
try_data = g_malloc0 (sizeof (TryData));
+ swfdec_action_try_data_ref (try_data);
swfdec_bits_init_data (&bits, data, len);
swfdec_bits_getbits (&bits, 5); // reserved
try_data->use_register = swfdec_bits_getbit (&bits);
- try_data->finally = swfdec_bits_getbit (&bits);
- try_data->catch = swfdec_bits_getbit (&bits);
+ use_finally = swfdec_bits_getbit (&bits);
+ use_catch = swfdec_bits_getbit (&bits);
try_size = swfdec_bits_get_u16 (&bits);
try_data->catch_size = swfdec_bits_get_u16 (&bits);
try_data->finally_size = swfdec_bits_get_u16 (&bits);
- try_data->start = data + len + try_size;
+ if (use_catch)
+ try_data->catch_start = data + len + try_size;
+ if (use_finally)
+ try_data->finally_start = try_data->catch_start + try_data->catch_size;
if (try_data->use_register) {
try_data->register_number = swfdec_bits_get_u8 (&bits);
@@ -2751,9 +2755,13 @@ swfdec_action_try (SwfdecAsContext *cx, guint action, const guint8 *data, guint
SWFDEC_WARNING ("leftover bytes in Try action");
}
- swfdec_action_try_data_ref (try_data);
- swfdec_as_frame_push_block (cx->frame, data + len, data + len + try_size,
- swfdec_action_try_end_try, try_data, swfdec_action_try_data_unref);
+ if (try_data->catch_start || try_data->finally_start) {
+ swfdec_as_frame_push_block (cx->frame, data + len, data + len + try_size,
+ swfdec_action_try_end_try, try_data, swfdec_action_try_data_unref);
+ } else {
+ SWFDEC_ERROR ("Try without neither catch or finally block");
+ swfdec_action_try_data_unref (try_data);
+ }
}
static void
More information about the Swfdec
mailing list