Benjamin Otte
2007-Feb-16 13:03 UTC
[Swfdec] 11 commits - libswfdec/swfdec_font.c libswfdec/swfdec_font.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/.gitignore test/trace
libswfdec/swfdec_font.c | 4 libswfdec/swfdec_font.h | 2 libswfdec/swfdec_js_movie.c | 8 - libswfdec/swfdec_script.c | 225 +++++++++++++++++++++++++++++++++++++++---- libswfdec/swfdec_script.h | 14 ++ test/.gitignore | 1 test/trace/Makefile.am | 6 + test/trace/height4.swf |binary test/trace/height4.swf.trace | 5 test/trace/scope.swf |binary test/trace/scope.swf.trace | 2 test/trace/scope2.swf |binary test/trace/scope2.swf.trace | 2 13 files changed, 244 insertions(+), 25 deletions(-) New commits: diff-tree d33393b8767f81772dee644af8bc7143e766e4bb (from 4f71cc6f5f14bcc3c69cff4c0c9dca27b7f476fe) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 21:12:39 2007 +0100 add 2 tests for function scopes diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index d5706dc..f1755ee 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -90,6 +90,10 @@ EXTRA_DIST = \ order.swf.trace \ rotation-5.swf \ rotation-5.swf.trace \ + scope.swf \ + scope.swf.trace \ + scope2.swf \ + scope2.swf.trace \ setvariable.swf \ setvariable.swf.trace \ transform.swf \ diff --git a/test/trace/scope.swf b/test/trace/scope.swf new file mode 100755 index 0000000..b7a9a90 Binary files /dev/null and b/test/trace/scope.swf differ diff --git a/test/trace/scope.swf.trace b/test/trace/scope.swf.trace new file mode 100755 index 0000000..fd3c81a --- /dev/null +++ b/test/trace/scope.swf.trace @@ -0,0 +1,2 @@ +5 +5 diff --git a/test/trace/scope2.swf b/test/trace/scope2.swf new file mode 100755 index 0000000..78d454c Binary files /dev/null and b/test/trace/scope2.swf differ diff --git a/test/trace/scope2.swf.trace b/test/trace/scope2.swf.trace new file mode 100755 index 0000000..fd3c81a --- /dev/null +++ b/test/trace/scope2.swf.trace @@ -0,0 +1,2 @@ +5 +5 diff-tree 4f71cc6f5f14bcc3c69cff4c0c9dca27b7f476fe (from aabc4fdacdad8392d185467be20a858d2bff1cad) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 21:11:56 2007 +0100 use this as parent in DefineFunction diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 95a5561..9a9dd75 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1439,10 +1439,10 @@ swfdec_action_do_define_function (JSCont n_args = swfdec_bits_get_u16 (&bits); if (*function_name == '\0') { /* anonymous function */ - fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA, NULL, NULL); + fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA, cx->fp->thisp, NULL); } else { /* named function */ - fun = JS_NewFunction (cx, NULL, n_args, 0, NULL, function_name); + fun = JS_NewFunction (cx, NULL, n_args, 0, cx->fp->thisp, function_name); } if (fun == NULL) return JS_FALSE; diff-tree aabc4fdacdad8392d185467be20a858d2bff1cad (from debdc90a5da93480aa82e2d78331720c4f53c103) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 19:23:42 2007 +0100 make DefineFunction2 work various changes, including: - make DefineFunction2 really work (it used to not work before) - allocate 4 local variables in swfdec_script_interpret diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index dc8b2a5..95a5561 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1418,7 +1418,8 @@ swfdec_action_init_object (JSContext *cx } static JSBool -swfdec_action_define_function (JSContext *cx, guint action, const guint8 *data, guint len) +swfdec_action_do_define_function (JSContext *cx, guint action, + const guint8 *data, guint len, gboolean v2) { const char *function_name; guint i, n_args, size; @@ -1426,7 +1427,8 @@ swfdec_action_define_function (JSContext JSFunction *fun; SwfdecScript *script; gboolean has_preloads = FALSE; - gboolean v2 = (action == 0x8e); + guint flags = 0; + guint8 *preloads = NULL; swfdec_bits_init_data (&bits, data, len); function_name = swfdec_bits_get_string (&bits); @@ -1446,8 +1448,8 @@ swfdec_action_define_function (JSContext return JS_FALSE; if (v2) { fun->nvars = swfdec_bits_get_u8 (&bits); - script->flags = swfdec_bits_get_u16 (&bits); - script->preloads = g_new0 (guint8, n_args); + flags = swfdec_bits_get_u16 (&bits); + preloads = g_new0 (guint8, n_args); } else { fun->nvars = 4; } @@ -1462,9 +1464,10 @@ swfdec_action_define_function (JSContext return JS_FALSE; } if (preload != 0) { - script->preloads[i] = preload; + preloads[i] = preload; swfdec_bits_skip_string (&bits); has_preloads = TRUE; + continue; } } arg_name = swfdec_bits_skip_string (&bits); @@ -1483,9 +1486,9 @@ swfdec_action_define_function (JSContext return JS_FALSE; } } - if (script->preloads && !has_preloads) { - g_free (script->preloads); - script->preloads = NULL; + if (preloads && !has_preloads) { + g_free (preloads); + preloads = NULL; } size = swfdec_bits_get_u16 (&bits); /* check the script can be created */ @@ -1509,8 +1512,11 @@ swfdec_action_define_function (JSContext } if (script == NULL) { SWFDEC_ERROR ("failed to create script"); + g_free (preloads); return JS_FALSE; } + script->flags = flags; + script->preloads = preloads; fun->swf = script; /* attach the function */ if (*function_name == '\0') { @@ -1531,6 +1537,18 @@ swfdec_action_define_function (JSContext } static JSBool +swfdec_action_define_function (JSContext *cx, guint action, const guint8 *data, guint len) +{ + return swfdec_action_do_define_function (cx, action, data, len, FALSE); +} + +static JSBool +swfdec_action_define_function2 (JSContext *cx, guint action, const guint8 *data, guint len) +{ + return swfdec_action_do_define_function (cx, action, data, len, TRUE); +} + +static JSBool swfdec_action_bitwise (JSContext *cx, guint action, const guint8 *data, guint len) { guint32 a, b; @@ -2109,7 +2127,7 @@ static const SwfdecActionSpec actions[25 /* version 4 */ [0x8d] = { "WaitForFrame2", swfdec_action_print_wait_for_frame2, 1, 0, { NULL, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2 } }, /* version 7 */ - [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function } }, + [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function2 } }, [0x8f] = { "Try", NULL }, /* version 5 */ [0x94] = { "With", NULL }, @@ -2517,6 +2535,7 @@ swfdec_script_execute (SwfdecScript *scr JSStackFrame *oldfp, frame; JSObject *obj; JSBool ok; + void *mark; g_return_val_if_fail (script != NULL, JSVAL_VOID); g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (scriptable), JSVAL_VOID); @@ -2534,8 +2553,8 @@ swfdec_script_execute (SwfdecScript *scr frame.swf = script; frame.constant_pool = NULL; frame.thisp = obj; - frame.argc = frame.nvars = 0; - frame.argv = frame.vars = NULL; + frame.argc = 0; + frame.argv = NULL; frame.annotation = NULL; frame.sharpArray = NULL; frame.rval = JSVAL_VOID; @@ -2549,6 +2568,14 @@ swfdec_script_execute (SwfdecScript *scr frame.dormantNext = NULL; frame.objAtomMap = NULL; + /* allocate stack for variables */ + frame.nvars = 4; + frame.vars = js_AllocStack (cx, frame.nvars, &mark); + if (frame.vars == NULL) { + return JS_FALSE; + } + frame.vars[0] = frame.vars[1] = frame.vars[2] = frame.vars[3] = JSVAL_VOID; + if (oldfp) { g_assert (!oldfp->dormantNext); oldfp->dormantNext = cx->dormantFrameChain; @@ -2563,7 +2590,7 @@ swfdec_script_execute (SwfdecScript *scr */ ok = swfdec_script_interpret (script, cx, &frame.rval); - /* FIXME: where to clean this up? */ + js_FreeStack (cx, mark); if (frame.constant_pool) swfdec_constant_pool_free (frame.constant_pool); diff-tree debdc90a5da93480aa82e2d78331720c4f53c103 (from 1abcc041eb03537f5f95ff42e3feada49b90d5a4) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 15:54:28 2007 +0100 implement ActionModulo diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 8859440..dc8b2a5 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -28,8 +28,9 @@ #include "js/jscntxt.h" #include "js/jsinterp.h" -#include <string.h> +#include <errno.h> #include <math.h> +#include <string.h> #include "swfdec_decoder.h" #include "swfdec_js.h" #include "swfdec_movie.h" @@ -1691,6 +1692,43 @@ swfdec_action_store_register (JSContext return JS_TRUE; } +static JSBool +swfdec_action_modulo_5 (JSContext *cx, guint action, const guint8 *data, guint len) +{ + double x, y; + + x = swfdec_action_to_number (cx, cx->fp->sp[-1]); + y = swfdec_action_to_number (cx, cx->fp->sp[-2]); + cx->fp->sp--; + errno = 0; + x = fmod (x, y); + if (errno != 0) { + cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN); + return JS_TRUE; + } else { + return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]); + } +} + +static JSBool +swfdec_action_modulo_7 (JSContext *cx, guint action, const guint8 *data, guint len) +{ + double x, y; + + if (!swfdec_value_to_number_7 (cx, cx->fp->sp[-1], &x) || + !swfdec_value_to_number_7 (cx, cx->fp->sp[-2], &y)) + return JS_FALSE; + cx->fp->sp--; + errno = 0; + x = fmod (x, y); + if (errno != 0) { + cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN); + return JS_TRUE; + } else { + return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]); + } +} + /*** PRINT FUNCTIONS ***/ static char * @@ -2020,7 +2058,7 @@ static const SwfdecActionSpec actions[25 [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } }, [0x3d] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } }, [0x3e] = { "Return", NULL, 1, 0, { NULL, NULL, swfdec_action_return, swfdec_action_return, swfdec_action_return } }, - [0x3f] = { "Modulo", NULL }, + [0x3f] = { "Modulo", NULL, 2, 1, { NULL, NULL, swfdec_action_modulo_5, swfdec_action_modulo_5, swfdec_action_modulo_7 } }, [0x40] = { "NewObject", NULL, -1, 1, { NULL, NULL, swfdec_action_new_object, swfdec_action_new_object, swfdec_action_new_object } }, [0x41] = { "DefineLocal2", NULL, 1, 0, { NULL, NULL, swfdec_action_define_local2, swfdec_action_define_local2, swfdec_action_define_local2 } }, [0x42] = { "InitArray", NULL }, diff-tree 1abcc041eb03537f5f95ff42e3feada49b90d5a4 (from cddfdb3c4ca0782b1d9e9c97fabf64a024120762) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 10:04:37 2007 +0100 implement StoreRegister and pushing registers in ActionPush diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 54913b2..8859440 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -124,6 +124,15 @@ swfdec_constant_pool_get_area (SwfdecScr /*** SUPPORT FUNCTIONS ***/ +static gboolean +swfdec_action_has_register (JSContext *cx, guint i) +{ + if (cx->fp->fun == NULL) + return i < 4; + else + return i < cx->fp->fun->nvars; +} + static SwfdecMovie * swfdec_action_get_target (JSContext *cx) { @@ -461,6 +470,16 @@ swfdec_action_push (JSContext *cx, guint case 3: /* undefined */ *cx->fp->sp++ = JSVAL_VOID; break; + case 4: /* register */ + { + guint regnum = swfdec_bits_get_u8 (&bits); + if (!swfdec_action_has_register (cx, regnum)) { + SWFDEC_ERROR ("cannot Push register %u: not enough registers", regnum); + return JS_FALSE; + } + *cx->fp->sp++ = cx->fp->vars[regnum]; + break; + } case 5: /* boolean */ *cx->fp->sp++ = swfdec_bits_get_u8 (&bits) ? JSVAL_TRUE : JSVAL_FALSE; break; @@ -512,7 +531,6 @@ swfdec_action_push (JSContext *cx, guint return JS_FALSE; break; } - case 4: /* register */ default: SWFDEC_ERROR ("Push: type %u not implemented", type); return JS_FALSE; @@ -1658,9 +1676,34 @@ swfdec_action_delete (JSContext *cx, gui return JS_DeleteProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[0]), name); } +static JSBool +swfdec_action_store_register (JSContext *cx, guint action, const guint8 *data, guint len) +{ + if (len != 1) { + SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); + return JS_FALSE; + } + if (!swfdec_action_has_register (cx, *data)) { + SWFDEC_ERROR ("Cannot store into register %u, not enough registers", (guint) *data); + return JS_FALSE; + } + cx->fp->vars[*data] = cx->fp->sp[-1]; + return JS_TRUE; +} + /*** PRINT FUNCTIONS ***/ static char * +swfdec_action_print_store_register (guint action, const guint8 *data, guint len) +{ + if (len != 1) { + SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); + return NULL; + } + return g_strdup_printf ("StoreRegister %u", (guint) *data); +} + +static char * swfdec_action_print_set_target (guint action, const guint8 *data, guint len) { if (!memchr (data, 0, len)) { @@ -1795,6 +1838,9 @@ swfdec_action_print_push (guint action, case 3: /* undefined */ g_string_append (string, "void"); break; + case 4: /* register */ + g_string_append_printf (string, "Register %u", swfdec_bits_get_u8 (&bits)); + break; case 5: /* boolean */ g_string_append (string, swfdec_bits_get_u8 (&bits) ? "True" : "False"); break; @@ -1810,7 +1856,6 @@ swfdec_action_print_push (guint action, case 9: /* 16bit ConstantPool address */ g_string_append_printf (string, "Pool %u", swfdec_bits_get_u16 (&bits)); break; - case 4: /* register */ default: SWFDEC_ERROR ("Push: type %u not implemented", type); return JS_FALSE; @@ -2017,7 +2062,7 @@ static const SwfdecActionSpec actions[25 [0x81] = { "GotoFrame", swfdec_action_print_goto_frame, 0, 0, { swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame } }, [0x83] = { "GetURL", swfdec_action_print_get_url, 0, 0, { swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url } }, /* version 5 */ - [0x87] = { "StoreRegister", NULL }, + [0x87] = { "StoreRegister", swfdec_action_print_store_register, 1, 1, { NULL, NULL, swfdec_action_store_register, swfdec_action_store_register, swfdec_action_store_register } }, [0x88] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } }, /* version 3 */ [0x8a] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } }, diff-tree cddfdb3c4ca0782b1d9e9c97fabf64a024120762 (from 31af4f795a29ab40cf4584cc45a291286b059928) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 09:52:31 2007 +0100 implement ActionDelete diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 0f279e5..54913b2 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1644,6 +1644,20 @@ swfdec_action_return (JSContext *cx, gui return JS_TRUE; } +static JSBool +swfdec_action_delete (JSContext *cx, guint action, const guint8 *data, guint len) +{ + const char *name; + + cx->fp->sp -= 2; + name = swfdec_js_to_string (cx, cx->fp->sp[1]); + if (name == NULL) + return JS_FALSE; + if (!JSVAL_IS_OBJECT (cx->fp->sp[0])) + return JS_TRUE; + return JS_DeleteProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[0]), name); +} + /*** PRINT FUNCTIONS ***/ static char * @@ -1956,7 +1970,7 @@ static const SwfdecActionSpec actions[25 [0x36] = { "MBCharToAscii", NULL }, [0x37] = { "MVAsciiToChar", NULL }, /* version 5 */ - [0x3a] = { "Delete", NULL }, + [0x3a] = { "Delete", NULL, 2, 0, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } }, [0x3b] = { "Delete2", NULL }, [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } }, [0x3d] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } }, diff-tree 31af4f795a29ab40cf4584cc45a291286b059928 (from 8a164b9aeff20d0b77f2225135b688cc4d820905) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 09:46:40 2007 +0100 implement DefineFunction2 partially diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 14feaa1..0f279e5 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1406,6 +1406,8 @@ swfdec_action_define_function (JSContext SwfdecBits bits; JSFunction *fun; SwfdecScript *script; + gboolean has_preloads = FALSE; + gboolean v2 = (action == 0x8e); swfdec_bits_init_data (&bits, data, len); function_name = swfdec_bits_get_string (&bits); @@ -1423,9 +1425,30 @@ swfdec_action_define_function (JSContext } if (fun == NULL) return JS_FALSE; + if (v2) { + fun->nvars = swfdec_bits_get_u8 (&bits); + script->flags = swfdec_bits_get_u16 (&bits); + script->preloads = g_new0 (guint8, n_args); + } else { + fun->nvars = 4; + } for (i = 0; i < n_args; i++) { JSAtom *atom; - const char *arg_name = swfdec_bits_get_string (&bits); + const char *arg_name; + if (v2) { + guint preload = swfdec_bits_get_u8 (&bits); + if (preload && preload >= fun->nvars) { + SWFDEC_ERROR ("argument %u is preloaded into register %u out of %u", + i, preload, fun->nvars); + return JS_FALSE; + } + if (preload != 0) { + script->preloads[i] = preload; + swfdec_bits_skip_string (&bits); + has_preloads = TRUE; + } + } + arg_name = swfdec_bits_skip_string (&bits); if (arg_name == NULL || *arg_name == '\0') { SWFDEC_ERROR ("empty argument name not allowed"); return JS_FALSE; @@ -1441,6 +1464,10 @@ swfdec_action_define_function (JSContext return JS_FALSE; } } + if (script->preloads && !has_preloads) { + g_free (script->preloads); + script->preloads = NULL; + } size = swfdec_bits_get_u16 (&bits); /* check the script can be created */ script = cx->fp->swf; @@ -1635,8 +1662,9 @@ swfdec_action_print_define_function (gui GString *string; const char *function_name; guint i, n_args, size; + gboolean v2 = (action == 0x8e); - string = g_string_new ("DefineFunction "); + string = g_string_new (v2 ? "DefineFunction2 " : "DefineFunction "); swfdec_bits_init_data (&bits, data, len); function_name = swfdec_bits_get_string (&bits); if (function_name == NULL) { @@ -1650,17 +1678,30 @@ swfdec_action_print_define_function (gui } n_args = swfdec_bits_get_u16 (&bits); g_string_append_c (string, '('); + if (v2) { + /* n_regs = */ swfdec_bits_get_u8 (&bits); + /* flags = */ swfdec_bits_get_u16 (&bits); + } for (i = 0; i < n_args; i++) { - const char *arg_name = swfdec_bits_get_string (&bits); - if (arg_name == NULL || *arg_name == '\0') { + guint preload; + const char *arg_name; + if (v2) + preload = swfdec_bits_get_u8 (&bits); + else + preload = 0; + arg_name = swfdec_bits_get_string (&bits); + if (preload == 0 && (arg_name == NULL || *arg_name == '\0')) { SWFDEC_ERROR ("empty argument name not allowed"); g_string_free (string, TRUE); return NULL; } if (i) g_string_append (string, ", "); - g_string_append (string, arg_name); + if (preload) + g_string_append_printf (string, "PRELOAD %u", preload); + else + g_string_append (string, arg_name); } g_string_append_c (string, ')'); size = swfdec_bits_get_u16 (&bits); @@ -1971,7 +2012,7 @@ static const SwfdecActionSpec actions[25 /* version 4 */ [0x8d] = { "WaitForFrame2", swfdec_action_print_wait_for_frame2, 1, 0, { NULL, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2 } }, /* version 7 */ - [0x8e] = { "DefineFunction2", NULL }, + [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function } }, [0x8f] = { "Try", NULL }, /* version 5 */ [0x94] = { "With", NULL }, @@ -2150,6 +2191,7 @@ swfdec_script_unref (SwfdecScript *scrip if (script->constant_pool) swfdec_buffer_unref (script->constant_pool); g_free (script->name); + g_free (script->preloads); g_free (script); } @@ -2187,6 +2229,29 @@ swfdec_script_interpret (SwfdecScript *s version = EXTRACT_VERSION (script->version); *rval = JSVAL_VOID; fp = cx->fp; + /* do the preloading */ + if (script->preloads) { + guint i; + for (i = 0; i < fp->fun->nargs; i++) { + if (script->preloads[i]) + fp->vars[script->preloads[i]] = fp->argv[i]; + } + } + if (script->flags) { + guint preload_reg = 0; + SwfdecPlayer *player = JS_GetContextPrivate (cx); + if (script->flags & SWFDEC_SCRIPT_PRELOAD_THIS) + fp->vars[preload_reg++] = OBJECT_TO_JSVAL (fp->thisp); + if (script->flags & SWFDEC_SCRIPT_PRELOAD_ARGS) + + if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER || + script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT || + script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT) { + g_assert_not_reached (); + } + if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL) + fp->vars[preload_reg++] = OBJECT_TO_JSVAL (player->jsobj); + } /* set up the script */ startpc = pc = script->buffer->data; endpc = startpc + script->buffer->length; diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h index 93f59b9..82d2169 100644 --- a/libswfdec/swfdec_script.h +++ b/libswfdec/swfdec_script.h @@ -29,6 +29,18 @@ G_BEGIN_DECLS //typedef struct _SwfdecScript SwfdecScript; +typedef enum { + SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0), + SWFDEC_SCRIPT_SUPPRESS_THIS = (1 << 1), + SWFDEC_SCRIPT_PRELOAD_ARGS = (1 << 2), + SWFDEC_SCRIPT_SUPPRESS_ARGS = (1 << 3), + SWFDEC_SCRIPT_PRELOAD_SUPER = (1 << 4), + SWFDEC_SCRIPT_SUPPRESS_SUPER = (1 << 5), + SWFDEC_SCRIPT_PRELOAD_ROOT = (1 << 6), + SWFDEC_SCRIPT_PRELOAD_PARENT = (1 << 7), + SWFDEC_SCRIPT_PRELOAD_GLOBAL = (1 << 8) +} SwfdecScriptFlag; + typedef gboolean (* SwfdecScriptForeachFunc) (gconstpointer bytecode, guint action, const guint8 *data, guint len, gpointer user_data); @@ -41,6 +53,8 @@ struct _SwfdecScript { gpointer debugger; /* debugger owning us or NULL */ /* needed by functions */ SwfdecBuffer * constant_pool; /* constant pool action */ + guint flags; /* SwfdecScriptFlags */ + guint8 * preloads; /* NULL or where to preload variables to */ }; const char * swfdec_action_get_name (guint action); diff-tree 8a164b9aeff20d0b77f2225135b688cc4d820905 (from 1ef3f0b656af57ba7b8cf08fdefa874d644b97bf) Author: Benjamin Otte <otte@gnome.org> Date: Fri Feb 16 09:46:19 2007 +0100 fix invalid code that caused crashes when parsing kerning tables Only Youtube seems to have those... Also updated Copyright headers diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index ac64c22..03157b1 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -237,7 +237,7 @@ tag_func_define_font (SwfdecSwfDecoder * static void swfdec_font_parse_kerning_table (SwfdecSwfDecoder *s, SwfdecFont *font, gboolean wide_codes) { - SwfdecBits *bits; + SwfdecBits *bits = &s->b; guint n_kernings, i; n_kernings = swfdec_bits_get_u16 (bits); diff --git a/libswfdec/swfdec_font.h b/libswfdec/swfdec_font.h index 23ecce4..babfa5a 100644 --- a/libswfdec/swfdec_font.h +++ b/libswfdec/swfdec_font.h @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff-tree 1ef3f0b656af57ba7b8cf08fdefa874d644b97bf (from 5e07f4f518cf43351da51a95c43c2fda2016c388) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 21:15:23 2007 +0100 add another test for the width/height changes diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index d931702..d5706dc 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -64,6 +64,8 @@ EXTRA_DIST = \ height2.swf.trace \ height3.swf \ height3.swf.trace \ + height4.swf \ + height4.swf.trace \ lifetime1.swf \ lifetime1.swf.trace \ load-4.swf \ diff --git a/test/trace/height4.swf b/test/trace/height4.swf new file mode 100755 index 0000000..1df1e43 Binary files /dev/null and b/test/trace/height4.swf differ diff --git a/test/trace/height4.swf.trace b/test/trace/height4.swf.trace new file mode 100755 index 0000000..8fc6ef9 --- /dev/null +++ b/test/trace/height4.swf.trace @@ -0,0 +1,5 @@ +Test rounding of non-integer width and height +0 +0 +133.3 +133.3 diff-tree 5e07f4f518cf43351da51a95c43c2fda2016c388 (from ab0a07ebac71f88d925f7f50dc5d2ae618cb7fe2) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 21:14:44 2007 +0100 round the width and height instead of just casting This gets around some irregularities when playing copter.swf diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c index d33ba94..10fde07 100644 --- a/libswfdec/swfdec_js_movie.c +++ b/libswfdec/swfdec_js_movie.c @@ -818,7 +818,7 @@ mc_width_get (JSContext *cx, JSObject *o g_assert (movie); swfdec_movie_update (movie); - d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.x1 - movie->extents.x0)); + d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.x1 - movie->extents.x0))); return JS_NewNumberValue (cx, d, vp); } @@ -842,7 +842,7 @@ mc_width_set (JSContext *cx, JSObject *o } swfdec_movie_update (movie); movie->modified = TRUE; - cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.x1 - movie->extents.x0)); + cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.x1 - movie->extents.x0))); if (cur != 0) { movie->xscale *= d / cur; } else { @@ -864,7 +864,7 @@ mc_height_get (JSContext *cx, JSObject * g_assert (movie); swfdec_movie_update (movie); - d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.y1 - movie->extents.y0)); + d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.y1 - movie->extents.y0))); return JS_NewNumberValue (cx, d, vp); } @@ -888,7 +888,7 @@ mc_height_set (JSContext *cx, JSObject * } swfdec_movie_update (movie); movie->modified = TRUE; - cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.y1 - movie->extents.y0)); + cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.y1 - movie->extents.y0))); if (cur != 0) { movie->yscale *= d / cur; } else { diff-tree ab0a07ebac71f88d925f7f50dc5d2ae618cb7fe2 (from 5a3b6dc3f4091163b071a50172bfb21de3aa31fd) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 21:13:50 2007 +0100 add swfscript diff --git a/test/.gitignore b/test/.gitignore index 9280a20..eb7f89f 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -12,3 +12,4 @@ dump parse swfdec-extract swfedit +swfscript
Reasonably Related Threads
- Branch 'as' - 4 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_interpret.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h
- Branch 'interpreter' - 20 commits - autogen.sh configure.ac libswfdec/js libswfdec/swfdec_debug.h libswfdec/swfdec_js.c libswfdec/swfdec_js_color.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_script.c
- 17 commits - libswfdec/js libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_root_movie.c
- 4 commits - libswfdec/swfdec_script.c test/image test/trace
- 22 commits - libswfdec/js libswfdec/swfdec_debugger.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_script.c