Benjamin Otte
2007-Jun-06 14:37 UTC
[Swfdec] Branch 'as' - 13 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_string.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_with.c libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_debugger.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/trace
libswfdec/swfdec_as_context.c | 24 +++ libswfdec/swfdec_as_context.h | 2 libswfdec/swfdec_as_frame.c | 56 +++++-- libswfdec/swfdec_as_frame.h | 4 libswfdec/swfdec_as_interpret.c | 18 +- libswfdec/swfdec_as_object.c | 85 +++------- libswfdec/swfdec_as_object.h | 16 +- libswfdec/swfdec_as_string.c | 58 +++++++ libswfdec/swfdec_as_strings.c | 2 libswfdec/swfdec_as_super.c | 3 libswfdec/swfdec_as_with.c | 8 - libswfdec/swfdec_bits.c | 59 +++++-- libswfdec/swfdec_bits.h | 2 libswfdec/swfdec_debugger.c | 9 - libswfdec/swfdec_script.c | 62 ++++--- libswfdec/swfdec_script.h | 7 test/trace/Makefile.am | 56 ++++++- test/trace/charat-5.swf |binary test/trace/charat-5.swf.trace | 221 ++++++++++++++++++++++++++++ test/trace/charat-6.swf |binary test/trace/charat-6.swf.trace | 221 ++++++++++++++++++++++++++++ test/trace/charat-7.swf |binary test/trace/charat-7.swf.trace | 221 ++++++++++++++++++++++++++++ test/trace/charat.as | 10 + test/trace/delete-object-5.swf |binary test/trace/delete-object-5.swf.trace | 4 test/trace/delete-object-6.swf |binary test/trace/delete-object-6.swf.trace | 4 test/trace/delete-object-7.swf |binary test/trace/delete-object-7.swf.trace | 4 test/trace/delete-object.as | 13 + test/trace/delete-prototypes-5.swf |binary test/trace/delete-prototypes-5.swf.trace | 4 test/trace/delete-prototypes-6.swf |binary test/trace/delete-prototypes-6.swf.trace | 4 test/trace/delete-prototypes-7.swf |binary test/trace/delete-prototypes-7.swf.trace | 4 test/trace/delete-prototypes.as | 14 + test/trace/with-delete-5.swf |binary test/trace/with-delete-5.swf.trace | 13 + test/trace/with-delete-6.swf |binary test/trace/with-delete-6.swf.trace | 13 + test/trace/with-delete-7.swf |binary test/trace/with-delete-7.swf.trace | 13 + test/trace/with-delete.as | 24 +++ test/trace/with-function-delete-5.swf |binary test/trace/with-function-delete-5.swf.trace | 10 + test/trace/with-function-delete-6.swf |binary test/trace/with-function-delete-6.swf.trace | 10 + test/trace/with-function-delete-7.swf |binary test/trace/with-function-delete-7.swf.trace | 10 + test/trace/with-function-delete.as | 26 +++ test/trace/with-prototypes-5.swf |binary test/trace/with-prototypes-5.swf.trace | 3 test/trace/with-prototypes-6.swf |binary test/trace/with-prototypes-6.swf.trace | 3 test/trace/with-prototypes-7.swf |binary test/trace/with-prototypes-7.swf.trace | 3 test/trace/with-prototypes.as | 14 + 59 files changed, 1188 insertions(+), 149 deletions(-) New commits: diff-tree bf3f17bb8f8aa3d5a9cf4d4121e77efc2c1f048c (from 10e5b6967cb6df937b34a9d9cad410bc7c9e4d59) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 16:32:37 2007 +0200 add test for String.charAt() and String.charCodeAt() diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index 0c58f4d..79ab157 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -45,6 +45,13 @@ EXTRA_DIST = \ case1-6.swf.trace \ case1-7.swf \ case1-7.swf.trace \ + charat.as \ + charat-5.swf \ + charat-5.swf.trace \ + charat-6.swf \ + charat-6.swf.trace \ + charat-7.swf \ + charat-7.swf.trace \ children.swf \ children.swf.trace \ chr.as \ diff --git a/test/trace/charat-5.swf b/test/trace/charat-5.swf new file mode 100644 index 0000000..5146b64 Binary files /dev/null and b/test/trace/charat-5.swf differ diff --git a/test/trace/charat-5.swf.trace b/test/trace/charat-5.swf.trace new file mode 100644 index 0000000..288b443 --- /dev/null +++ b/test/trace/charat-5.swf.trace @@ -0,0 +1,221 @@ +Check charAt and CharCodeAt + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN +G +71 +r +114 +?? +195 +?? +188 +?? +195 +?? +159 + +32 +G +71 +o +111 +t +116 +t +116 + +32 +?? +206 +?? +147 +?? +206 +?? +181 +?? +206 +?? +185 +?? +206 +?? +172 + +32 +?? +207 +?? +131 +?? +206 +?? +177 +?? +207 +?? +130 + +32 +?? +215 +?? +169 +?? +215 +?? +156 +?? +215 +?? +149 +?? +215 +?? +157 + +32 +?? +230 +?? +151 +?? +165 +?? +230 +?? +156 +?? +172 +?? +232 +?? +170 +?? +158 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 + +0 diff --git a/test/trace/charat-6.swf b/test/trace/charat-6.swf new file mode 100644 index 0000000..caa5268 Binary files /dev/null and b/test/trace/charat-6.swf differ diff --git a/test/trace/charat-6.swf.trace b/test/trace/charat-6.swf.trace new file mode 100644 index 0000000..d59d99f --- /dev/null +++ b/test/trace/charat-6.swf.trace @@ -0,0 +1,221 @@ +Check charAt and CharCodeAt + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN +G +71 +r +114 +?? +252 +?? +223 + +32 +G +71 +o +111 +t +116 +t +116 + +32 +?? +915 +?? +949 +?? +953 +?? +940 + +32 +?? +963 +?? +945 +?? +962 + +32 +?? +1513 +?? +1500 +?? +1493 +?? +1501 + +32 +??? +26085 +??? +26412 +??? +35486 + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN diff --git a/test/trace/charat-7.swf b/test/trace/charat-7.swf new file mode 100644 index 0000000..cc89ff5 Binary files /dev/null and b/test/trace/charat-7.swf differ diff --git a/test/trace/charat-7.swf.trace b/test/trace/charat-7.swf.trace new file mode 100644 index 0000000..d59d99f --- /dev/null +++ b/test/trace/charat-7.swf.trace @@ -0,0 +1,221 @@ +Check charAt and CharCodeAt + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN +G +71 +r +114 +?? +252 +?? +223 + +32 +G +71 +o +111 +t +116 +t +116 + +32 +?? +915 +?? +949 +?? +953 +?? +940 + +32 +?? +963 +?? +945 +?? +962 + +32 +?? +1513 +?? +1500 +?? +1493 +?? +1501 + +32 +??? +26085 +??? +26412 +??? +35486 + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN + +NaN diff --git a/test/trace/charat.as b/test/trace/charat.as new file mode 100644 index 0000000..400372b --- /dev/null +++ b/test/trace/charat.as @@ -0,0 +1,10 @@ +// makeswf -v 7 -s 200x150 -r 1 -o charat.swf charat.as + +trace ("Check charAt and CharCodeAt"); +s = "Gr???? Gott ???????? ?????? ???????? ?????????"; +for (i = -10; i < 100; i++) { + trace (s.charAt (i)); + trace (s.charCodeAt (i)); +}; + +loadMovie ("FSCommand:quit", ""); diff-tree 10e5b6967cb6df937b34a9d9cad410bc7c9e4d59 (from d26079526cc944606e9f3fb72cdb72faa09d0494) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 16:31:36 2007 +0200 add test for deletes from withn a function defined in a with block diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index 1154931..0c58f4d 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -400,6 +400,13 @@ EXTRA_DIST = \ with-delete-6.swf.trace \ with-delete-7.swf \ with-delete-7.swf.trace \ + with-function-delete.as \ + with-function-delete-5.swf \ + with-function-delete-5.swf.trace \ + with-function-delete-6.swf \ + with-function-delete-6.swf.trace \ + with-function-delete-7.swf \ + with-function-delete-7.swf.trace \ with-prototypes.as \ with-prototypes-5.swf \ with-prototypes-5.swf.trace \ diff --git a/test/trace/with-function-delete-5.swf b/test/trace/with-function-delete-5.swf new file mode 100644 index 0000000..2a24df6 Binary files /dev/null and b/test/trace/with-function-delete-5.swf differ diff --git a/test/trace/with-function-delete-5.swf.trace b/test/trace/with-function-delete-5.swf.trace new file mode 100644 index 0000000..ab252a1 --- /dev/null +++ b/test/trace/with-function-delete-5.swf.trace @@ -0,0 +1,10 @@ +3 +0 +4 +undefined +5 +undefined +6 +undefined +7 +undefined diff --git a/test/trace/with-function-delete-6.swf b/test/trace/with-function-delete-6.swf new file mode 100644 index 0000000..5a1072f Binary files /dev/null and b/test/trace/with-function-delete-6.swf differ diff --git a/test/trace/with-function-delete-6.swf.trace b/test/trace/with-function-delete-6.swf.trace new file mode 100644 index 0000000..873d7d8 --- /dev/null +++ b/test/trace/with-function-delete-6.swf.trace @@ -0,0 +1,10 @@ +3 +2 +4 +1 +5 +0 +6 +-1 +7 +undefined diff --git a/test/trace/with-function-delete-7.swf b/test/trace/with-function-delete-7.swf new file mode 100644 index 0000000..a1255aa Binary files /dev/null and b/test/trace/with-function-delete-7.swf differ diff --git a/test/trace/with-function-delete-7.swf.trace b/test/trace/with-function-delete-7.swf.trace new file mode 100644 index 0000000..873d7d8 --- /dev/null +++ b/test/trace/with-function-delete-7.swf.trace @@ -0,0 +1,10 @@ +3 +2 +4 +1 +5 +0 +6 +-1 +7 +undefined diff --git a/test/trace/with-function-delete.as b/test/trace/with-function-delete.as new file mode 100644 index 0000000..3bc559a --- /dev/null +++ b/test/trace/with-function-delete.as @@ -0,0 +1,26 @@ +// makeswf -v 7 -s 200x150 -r 1 -o with-function-delete.swf with-function-delete.as + +trace ("Check how delete works inside functions defined in a With statement"); + +x = 0; +_global.x = -1; +o = { x: 1 }; +p = { x: 2 }; +with (o) { + with (p) { + foo = function (x) { + trace (x); + delete x; + trace (x); + delete x; + }; + }; +}; + +foo (3); +foo (4); +foo (5); +foo (6); +foo (7); + +loadMovie ("FSCommand:quit", ""); diff-tree d26079526cc944606e9f3fb72cdb72faa09d0494 (from ad83487f995f4c10dbed77adfbb8e94a42a08c98) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 16:30:02 2007 +0200 handle reading strings better Strings are LATIN1 in Flash <= 5 and only became UTF8 in Flash 6. swfdec_bits_skip_string () has been removed because of this and swfdec_bits_get_string_with_version() that automatically does the right conversion. swfdec_bits_get_string() should be considered deprecated. Someone should add some tests to ensure all strings behave like this and switch the rest of the functions. diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c index e0f6fe2..0c312bf 100644 --- a/libswfdec/swfdec_as_frame.c +++ b/libswfdec/swfdec_as_frame.c @@ -130,7 +130,7 @@ swfdec_as_frame_new (SwfdecAsContext *co if (script->constant_pool) { frame->constant_pool_buffer = swfdec_buffer_ref (script->constant_pool); frame->constant_pool = swfdec_constant_pool_new_from_action ( - script->constant_pool->data, script->constant_pool->length); + script->constant_pool->data, script->constant_pool->length, script->version); if (frame->constant_pool) { swfdec_constant_pool_attach_to_context (frame->constant_pool, context); } else { diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 7c3fcbc..d1e4b57 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -319,7 +319,7 @@ swfdec_action_constant_pool (SwfdecAsCon SwfdecAsFrame *frame; frame = cx->frame; - pool = swfdec_constant_pool_new_from_action (data, len); + pool = swfdec_constant_pool_new_from_action (data, len, cx->version); if (pool == NULL) return; swfdec_constant_pool_attach_to_context (pool, cx); @@ -346,7 +346,7 @@ swfdec_action_push (SwfdecAsContext *cx, switch (type) { case 0: /* string */ { - const char *s = swfdec_bits_skip_string (&bits); + char *s = swfdec_bits_get_string_with_version (&bits, cx->version); if (s == NULL) return; SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (stack), @@ -1433,7 +1433,7 @@ swfdec_action_define_function (SwfdecAsC frame = cx->frame; swfdec_bits_init_data (&bits, data, len); - function_name = swfdec_bits_skip_string (&bits); + function_name = swfdec_bits_get_string_with_version (&bits, cx->version); if (function_name == NULL) { SWFDEC_ERROR ("could not parse function name"); return; @@ -2120,7 +2120,8 @@ swfdec_action_print_push (guint action, switch (type) { case 0: /* string */ { - const char *s = swfdec_bits_skip_string (&bits); + /* FIXME: need version! */ + char *s = swfdec_bits_get_string (&bits); if (!s) { g_string_free (string, TRUE); return NULL; @@ -2128,6 +2129,7 @@ swfdec_action_print_push (guint action, g_string_append_c (string, '"'); g_string_append (string, s); g_string_append_c (string, '"'); + g_free (s); break; } case 1: /* float */ @@ -2173,7 +2175,8 @@ swfdec_action_print_constant_pool (guint GString *string; SwfdecConstantPool *pool; - pool = swfdec_constant_pool_new_from_action (data, len); + /* FIXME: version */ + pool = swfdec_constant_pool_new_from_action (data, len, 6); if (pool == NULL) return g_strdup ("ConstantPool (invalid)"); string = g_string_new ("ConstantPool"); diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c index 7f085cc..8b24f37 100644 --- a/libswfdec/swfdec_as_strings.c +++ b/libswfdec/swfdec_as_strings.c @@ -204,6 +204,8 @@ const char swfdec_as_strings[] = SWFDEC_AS_CONSTANT_STRING ("clearInterval") SWFDEC_AS_CONSTANT_STRING ("escape") SWFDEC_AS_CONSTANT_STRING ("unescape") + SWFDEC_AS_CONSTANT_STRING ("charAt") + SWFDEC_AS_CONSTANT_STRING ("charCodeAt") /* add more here */ ; diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c index c8a5062..9fb0041 100644 --- a/libswfdec/swfdec_bits.c +++ b/libswfdec/swfdec_bits.c @@ -470,22 +470,14 @@ swfdec_bits_get_matrix (SwfdecBits * bit swfdec_bits_syncbits (bits); } -char * -swfdec_bits_get_string (SwfdecBits * bits) -{ - const char *s = swfdec_bits_skip_string (bits); - - return g_strdup (s); -} - -const char * +static const char * swfdec_bits_skip_string (SwfdecBits *bits) { char *s; const char *end; guint len; - swfdec_bits_syncbits (bits); + SWFDEC_BYTES_CHECK (bits, 1); end = memchr (bits->ptr, 0, bits->end - bits->ptr); if (end == NULL) { SWFDEC_ERROR ("could not parse string"); @@ -495,15 +487,54 @@ swfdec_bits_skip_string (SwfdecBits *bit len = end - (const char *) bits->ptr; s = (char *) bits->ptr; bits->ptr += len + 1; - if (!g_utf8_validate (s, -1, NULL)) { - SWFDEC_ERROR ("parsed string is not valid utf-8"); - s = NULL; - } return s; } /** + * swfdec_bits_get_string_with_version: + * @bits: a #SwfdecBits + * @version: Flash player version + * + * Prior to Flash 6, strings used to be encoded as LATIN1. Since Flash 6, + * strings are encoded as UTF8. This version does the check automatically + * and converts strings to UTF-8. + * + * Returns: a UTF-8 encoded string or %NULL on error + **/ +char * +swfdec_bits_get_string_with_version (SwfdecBits *bits, guint version) +{ + const char *s; + + g_return_val_if_fail (bits != NULL, NULL); + + s = swfdec_bits_skip_string (bits); + if (s == NULL) + return NULL; + + if (version < 6) { + char *ret = g_convert (s, -1, "UTF8", "LATIN1", NULL , NULL, NULL); + if (ret == NULL) + g_warning ("Could not convert string from LATIN1 to UTF8"); + return ret; + } else { + if (!g_utf8_validate (s, -1, NULL)) { + SWFDEC_ERROR ("parsed string is not valid utf-8"); + return NULL; + } + return g_strdup (s); + } +} + +/* FIXME: deprecated - someone remove this */ +char * +swfdec_bits_get_string (SwfdecBits * bits) +{ + return swfdec_bits_get_string_with_version (bits, 6); +} + +/** * swfdec_bits_skip_bytes: * @bits: a #SwfdecBits * @n_bytes: number of bytes to skip diff --git a/libswfdec/swfdec_bits.h b/libswfdec/swfdec_bits.h index a86e705..8d6492e 100644 --- a/libswfdec/swfdec_bits.h +++ b/libswfdec/swfdec_bits.h @@ -61,10 +61,10 @@ void swfdec_bits_get_color_transform (Sw SwfdecColorTransform * ct); void swfdec_bits_get_matrix (SwfdecBits * bits, cairo_matrix_t *matrix, cairo_matrix_t *inverse); -const char *swfdec_bits_skip_string (SwfdecBits * bits); guint swfdec_bits_skip_bytes (SwfdecBits *bits, guint bytes); char *swfdec_bits_get_string (SwfdecBits * bits); char *swfdec_bits_get_string_length (SwfdecBits * bits, guint len); +char *swfdec_bits_get_string_with_version (SwfdecBits *bits, guint version); SwfdecColor swfdec_bits_get_color (SwfdecBits * bits); SwfdecColor swfdec_bits_get_rgba (SwfdecBits * bits); SwfdecGradient *swfdec_bits_get_gradient (SwfdecBits * bits); diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c index 8d0a96e..52ae539 100644 --- a/libswfdec/swfdec_debugger.c +++ b/libswfdec/swfdec_debugger.c @@ -47,6 +47,7 @@ static guint signals[LAST_SIGNAL] = { 0, /*** SwfdecDebuggerScript ***/ typedef struct { + guint version; /* version of parsed file */ SwfdecConstantPool * constant_pool; /* current constant pool */ GArray * commands; /* SwfdecDebuggerCommands parsed so far */ } ScriptParser; @@ -69,12 +70,13 @@ swfdec_debugger_print_push (ScriptParser switch (type) { case 0: /* string */ { - const char *s = swfdec_bits_skip_string (&bits); + char *s = swfdec_bits_get_string_with_version (&bits, parser->version); if (!s) goto error; g_string_append_c (string, '"'); g_string_append (string, s); g_string_append_c (string, '"'); + g_free (s); break; } case 1: /* float */ @@ -150,7 +152,7 @@ swfdec_debugger_add_command (gconstpoint if (action == SWFDEC_AS_ACTION_CONSTANT_POOL) { if (parser->constant_pool) swfdec_constant_pool_free (parser->constant_pool); - parser->constant_pool = swfdec_constant_pool_new_from_action (data, len); + parser->constant_pool = swfdec_constant_pool_new_from_action (data, len, parser->version); } return TRUE; } @@ -165,9 +167,10 @@ swfdec_debugger_script_new (SwfdecScript ret->script = script; swfdec_script_ref (script); parser.commands = g_array_new (TRUE, FALSE, sizeof (SwfdecDebuggerCommand)); + parser.version = script->version; if (script->constant_pool) { parser.constant_pool = swfdec_constant_pool_new_from_action ( - script->constant_pool->data, script->constant_pool->length); + script->constant_pool->data, script->constant_pool->length, parser.version); } else { parser.constant_pool = NULL; } diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index bc1b964..bf38d51 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -44,36 +44,37 @@ /*** CONSTANT POOLS ***/ +struct _SwfdecConstantPool { + SwfdecAsContext * context; /* context we are attached to or NULL */ + guint n_strings; /* number of strings */ + char * strings[1]; /* n_strings strings */ +}; + SwfdecConstantPool * -swfdec_constant_pool_new_from_action (const guint8 *data, guint len) +swfdec_constant_pool_new_from_action (const guint8 *data, guint len, guint version) { - guint8 *next; guint i, n; - GPtrArray *pool; + SwfdecBits bits; + SwfdecConstantPool *pool; - if (len < 2) { - SWFDEC_ERROR ("constant pool too small"); + swfdec_bits_init_data (&bits, data, len); + + n = swfdec_bits_get_u16 (&bits); + if (n == 0) return NULL; - } - n = GUINT16_FROM_LE (*((guint16*) data)); - data += 2; - len -= 2; - pool = g_ptr_array_sized_new (n); - g_ptr_array_set_size (pool, n); + + pool = g_malloc0 (sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *)); + pool->n_strings = n; for (i = 0; i < n; i++) { - next = memchr (data, 0, len); - if (next == NULL) { + pool->strings[i] = swfdec_bits_get_string_with_version (&bits, version); + if (pool->strings[i] == NULL) { SWFDEC_ERROR ("not enough strings available"); - g_ptr_array_free (pool, TRUE); + swfdec_constant_pool_free (pool); return NULL; } - next++; - g_ptr_array_index (pool, i) = (gpointer) data; - len -= next - data; - data = next; } - if (len != 0) { - SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", len); + if (swfdec_bits_left (&bits)) { + SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8); } return pool; } @@ -84,31 +85,38 @@ swfdec_constant_pool_attach_to_context ( guint i; g_return_if_fail (pool != NULL); + g_return_if_fail (pool->context == NULL); g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); - for (i = 0; i < pool->len; i++) { - g_ptr_array_index (pool, i) = (gpointer) swfdec_as_context_get_string (context, - g_ptr_array_index (pool, i)); + pool->context = context; + for (i = 0; i < pool->n_strings; i++) { + pool->strings[i] = (char *) swfdec_as_context_give_string (context, pool->strings[i]); } } guint swfdec_constant_pool_size (SwfdecConstantPool *pool) { - return pool->len; + return pool->n_strings; } const char * swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i) { - g_assert (i < pool->len); - return g_ptr_array_index (pool, i); + g_assert (i < pool->n_strings); + return pool->strings[i]; } void swfdec_constant_pool_free (SwfdecConstantPool *pool) { - g_ptr_array_free (pool, TRUE); + if (pool->context == NULL) { + guint i; + for (i = 0; i < pool->n_strings; i++) { + g_free (pool->strings[i]); + } + } + g_free (pool); } /*** SUPPORT FUNCTIONS ***/ diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h index 643001f..267aecb 100644 --- a/libswfdec/swfdec_script.h +++ b/libswfdec/swfdec_script.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS //typedef struct _SwfdecScript SwfdecScript; typedef struct _SwfdecScriptArgument SwfdecScriptArgument; -typedef GPtrArray SwfdecConstantPool; +typedef struct _SwfdecConstantPool SwfdecConstantPool; typedef enum { SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0), @@ -71,8 +71,9 @@ const char * swfdec_action_get_name (gu guint swfdec_action_get_from_name (const char * name); SwfdecConstantPool * - swfdec_constant_pool_new_from_action (const guint8 * data, - guint len); + swfdec_constant_pool_new_from_action (const guint8 * data, + guint len, + guint version); void swfdec_constant_pool_free (SwfdecConstantPool * pool); guint swfdec_constant_pool_size (SwfdecConstantPool * pool); const char * swfdec_constant_pool_get (SwfdecConstantPool * pool, diff-tree ad83487f995f4c10dbed77adfbb8e94a42a08c98 (from c679eed66607c228a12788da17236dd6b4d0e168) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 16:27:13 2007 +0200 implement String.charAt() and String.charCodeAt() diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c index cdf6fbd..d18b068 100644 --- a/libswfdec/swfdec_as_string.c +++ b/libswfdec/swfdec_as_string.c @@ -57,6 +57,62 @@ swfdec_as_string_init (SwfdecAsString *s /*** AS CODE ***/ +static inline const char * +swfdec_as_str_nth_char (const char *s, guint n) +{ + while (*s && n--) + s = g_utf8_next_char (s); + return s; +} + +static void +swfdec_as_string_charAt (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) +{ + SwfdecAsString *string = SWFDEC_AS_STRING (object); + int i; + const char *s, *t; + + i = swfdec_as_value_to_integer (object->context, &argv[0]); + if (i < 0) { + SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY); + return; + } + s = swfdec_as_str_nth_char (string->string, i); + if (*s == 0) { + SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY); + return; + } + t = g_utf8_next_char (s); + s = swfdec_as_context_give_string (object->context, g_strndup (s, t - s)); + SWFDEC_AS_VALUE_SET_STRING (ret, s); +} + +static void +swfdec_as_string_charCodeAt (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) +{ + SwfdecAsString *string = SWFDEC_AS_STRING (object); + int i; + const char *s; + gunichar c; + + i = swfdec_as_value_to_integer (object->context, &argv[0]); + if (i < 0) { + SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN); + return; + } + s = swfdec_as_str_nth_char (string->string, i); + if (*s == 0) { + if (object->context->version > 5) { + SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN); + } else { + SWFDEC_AS_VALUE_SET_INT (ret, 0); + } + return; + } + c = g_utf8_get_char (s); + SWFDEC_AS_VALUE_SET_NUMBER (ret, c); +} + static void swfdec_as_string_fromCharCode_5 (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { @@ -492,6 +548,8 @@ swfdec_as_string_init_context (SwfdecAsC swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val); SWFDEC_AS_VALUE_SET_OBJECT (&val, string); swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_charAt, SWFDEC_TYPE_AS_STRING, swfdec_as_string_charAt, 1); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_charCodeAt, SWFDEC_TYPE_AS_STRING, swfdec_as_string_charCodeAt, 1); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_substr, SWFDEC_TYPE_AS_STRING, swfdec_as_string_substr, 1); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_substring, SWFDEC_TYPE_AS_STRING, swfdec_as_string_substring, 1); swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toLowerCase, SWFDEC_TYPE_AS_STRING, swfdec_as_string_toLowerCase, 0); diff-tree c679eed66607c228a12788da17236dd6b4d0e168 (from f66b838c176e6a90a0d70df451aaa0db1dfc081f) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 16:26:41 2007 +0200 add swfdec_as_context_give_string that g_free's the given string diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index c10a5ea..50cff5b 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -356,6 +356,30 @@ swfdec_as_context_get_string (SwfdecAsCo return swfdec_as_context_create_string (context, string, len); } +/** + * swfdec_as_context_give_string: + * @context: a #SwfdecAsContext + * @string: string to make refcounted + * + * Takes ownership of @string and returns a refcounted version of the same + * string. This function is the same as swfdec_as_context_get_string(), but + * takes ownership of @string. + * + * Returns: A refcounted string + **/ +const char * +swfdec_as_context_give_string (SwfdecAsContext *context, char *string) +{ + const char *ret; + + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + g_return_val_if_fail (string != NULL, NULL); + + ret = swfdec_as_context_get_string (context, string); + g_free (string); + return ret; +} + SwfdecAsContext * swfdec_as_context_new (void) { diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h index 88c6c6f..5d2d7ba 100644 --- a/libswfdec/swfdec_as_context.h +++ b/libswfdec/swfdec_as_context.h @@ -93,6 +93,8 @@ void swfdec_as_context_get_time (Swfdec GTimeVal * tv); const char * swfdec_as_context_get_string (SwfdecAsContext * context, const char * string); +const char * swfdec_as_context_give_string (SwfdecAsContext * context, + char * string); #define swfdec_as_context_abort_oom(context) swfdec_as_context_abort (context, "Out of memory") void swfdec_as_context_abort (SwfdecAsContext * context, diff-tree f66b838c176e6a90a0d70df451aaa0db1dfc081f (from dcfd952c19e73011ef91dd111ba944409121a82a) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 12:06:57 2007 +0200 add tests for Delete behaviour diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index a9def0e..1154931 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -86,6 +86,20 @@ EXTRA_DIST = \ countdown.swf.trace \ currentframe.swf \ currentframe.swf.trace \ + delete-object.as \ + delete-object-5.swf \ + delete-object-5.swf.trace \ + delete-object-6.swf \ + delete-object-6.swf.trace \ + delete-object-7.swf \ + delete-object-7.swf.trace \ + delete-prototypes.as \ + delete-prototypes-5.swf \ + delete-prototypes-5.swf.trace \ + delete-prototypes-6.swf \ + delete-prototypes-6.swf.trace \ + delete-prototypes-7.swf \ + delete-prototypes-7.swf.trace \ divide.as \ divide-7.swf \ divide-7.swf.trace \ @@ -379,6 +393,13 @@ EXTRA_DIST = \ unescape2-7.swf \ unescape2-7.swf.trace \ video.flv \ + with-delete.as \ + with-delete-5.swf \ + with-delete-5.swf.trace \ + with-delete-6.swf \ + with-delete-6.swf.trace \ + with-delete-7.swf \ + with-delete-7.swf.trace \ with-prototypes.as \ with-prototypes-5.swf \ with-prototypes-5.swf.trace \ diff --git a/test/trace/delete-object-5.swf b/test/trace/delete-object-5.swf new file mode 100644 index 0000000..781abc6 Binary files /dev/null and b/test/trace/delete-object-5.swf differ diff --git a/test/trace/delete-object-5.swf.trace b/test/trace/delete-object-5.swf.trace new file mode 100644 index 0000000..5d7d7f3 --- /dev/null +++ b/test/trace/delete-object-5.swf.trace @@ -0,0 +1,4 @@ +Check that deleting from an object does not delete from the prototype +1 +2 +2 diff --git a/test/trace/delete-object-6.swf b/test/trace/delete-object-6.swf new file mode 100644 index 0000000..e5e2762 Binary files /dev/null and b/test/trace/delete-object-6.swf differ diff --git a/test/trace/delete-object-6.swf.trace b/test/trace/delete-object-6.swf.trace new file mode 100644 index 0000000..5d7d7f3 --- /dev/null +++ b/test/trace/delete-object-6.swf.trace @@ -0,0 +1,4 @@ +Check that deleting from an object does not delete from the prototype +1 +2 +2 diff --git a/test/trace/delete-object-7.swf b/test/trace/delete-object-7.swf new file mode 100644 index 0000000..371f619 Binary files /dev/null and b/test/trace/delete-object-7.swf differ diff --git a/test/trace/delete-object-7.swf.trace b/test/trace/delete-object-7.swf.trace new file mode 100644 index 0000000..5d7d7f3 --- /dev/null +++ b/test/trace/delete-object-7.swf.trace @@ -0,0 +1,4 @@ +Check that deleting from an object does not delete from the prototype +1 +2 +2 diff --git a/test/trace/delete-object.as b/test/trace/delete-object.as new file mode 100644 index 0000000..267a95e --- /dev/null +++ b/test/trace/delete-object.as @@ -0,0 +1,13 @@ +// makeswf -v 7 -s 200x150 -r 1 -o delete-object.swf delete-object.as + +trace ("Check that deleting from an object does not delete from the prototype"); + +o = { x: 1 }; +o.__proto__ = { x: 2 }; +trace (o.x); +delete o.x; +trace (o.x); +delete o.x; +trace (o.x); + +loadMovie ("FSCommand:quit", ""); diff --git a/test/trace/delete-prototypes-5.swf b/test/trace/delete-prototypes-5.swf new file mode 100644 index 0000000..f51c30b Binary files /dev/null and b/test/trace/delete-prototypes-5.swf differ diff --git a/test/trace/delete-prototypes-5.swf.trace b/test/trace/delete-prototypes-5.swf.trace new file mode 100644 index 0000000..f0be7d2 --- /dev/null +++ b/test/trace/delete-prototypes-5.swf.trace @@ -0,0 +1,4 @@ +Check that delete doesn't delete from prototypes. +this +prototype +prototype diff --git a/test/trace/delete-prototypes-6.swf b/test/trace/delete-prototypes-6.swf new file mode 100644 index 0000000..2cbfcf5 Binary files /dev/null and b/test/trace/delete-prototypes-6.swf differ diff --git a/test/trace/delete-prototypes-6.swf.trace b/test/trace/delete-prototypes-6.swf.trace new file mode 100644 index 0000000..f0be7d2 --- /dev/null +++ b/test/trace/delete-prototypes-6.swf.trace @@ -0,0 +1,4 @@ +Check that delete doesn't delete from prototypes. +this +prototype +prototype diff --git a/test/trace/delete-prototypes-7.swf b/test/trace/delete-prototypes-7.swf new file mode 100644 index 0000000..bc9af16 Binary files /dev/null and b/test/trace/delete-prototypes-7.swf differ diff --git a/test/trace/delete-prototypes-7.swf.trace b/test/trace/delete-prototypes-7.swf.trace new file mode 100644 index 0000000..f0be7d2 --- /dev/null +++ b/test/trace/delete-prototypes-7.swf.trace @@ -0,0 +1,4 @@ +Check that delete doesn't delete from prototypes. +this +prototype +prototype diff --git a/test/trace/delete-prototypes.as b/test/trace/delete-prototypes.as new file mode 100644 index 0000000..7463ea0 --- /dev/null +++ b/test/trace/delete-prototypes.as @@ -0,0 +1,14 @@ +// makeswf -v 7 -s 200x150 -r 1 -o delete-prototypes.swf delete-prototypes.as + +trace ("Check that delete doesn't delete from prototypes."); + +x = "this"; +this.__proto__.x = "prototype"; + +trace (x); +delete x; +trace (x); +delete x; +trace (x); + +loadMovie ("FSCommand:quit", ""); diff --git a/test/trace/with-delete-5.swf b/test/trace/with-delete-5.swf new file mode 100644 index 0000000..8acc082 Binary files /dev/null and b/test/trace/with-delete-5.swf differ diff --git a/test/trace/with-delete-5.swf.trace b/test/trace/with-delete-5.swf.trace new file mode 100644 index 0000000..80bceb6 --- /dev/null +++ b/test/trace/with-delete-5.swf.trace @@ -0,0 +1,13 @@ +Check that delete inside a With doesn't delete from prototypes. +1 +0 +1 +2 +2 +0 +2 +2 +2 +undefined +2 +2 diff --git a/test/trace/with-delete-6.swf b/test/trace/with-delete-6.swf new file mode 100644 index 0000000..2a7bfb8 Binary files /dev/null and b/test/trace/with-delete-6.swf differ diff --git a/test/trace/with-delete-6.swf.trace b/test/trace/with-delete-6.swf.trace new file mode 100644 index 0000000..80bceb6 --- /dev/null +++ b/test/trace/with-delete-6.swf.trace @@ -0,0 +1,13 @@ +Check that delete inside a With doesn't delete from prototypes. +1 +0 +1 +2 +2 +0 +2 +2 +2 +undefined +2 +2 diff --git a/test/trace/with-delete-7.swf b/test/trace/with-delete-7.swf new file mode 100644 index 0000000..2c217b2 Binary files /dev/null and b/test/trace/with-delete-7.swf differ diff --git a/test/trace/with-delete-7.swf.trace b/test/trace/with-delete-7.swf.trace new file mode 100644 index 0000000..80bceb6 --- /dev/null +++ b/test/trace/with-delete-7.swf.trace @@ -0,0 +1,13 @@ +Check that delete inside a With doesn't delete from prototypes. +1 +0 +1 +2 +2 +0 +2 +2 +2 +undefined +2 +2 diff --git a/test/trace/with-delete.as b/test/trace/with-delete.as new file mode 100644 index 0000000..4ddd663 --- /dev/null +++ b/test/trace/with-delete.as @@ -0,0 +1,24 @@ +// makeswf -v 7 -s 200x150 -r 1 -o with-delete.swf with-delete.as + +trace ("Check that delete inside a With doesn't delete from prototypes."); +x = 0; +o = { x: 1 }; +o.__proto__ = { x: 2 }; +with (o) { + trace (x); + trace (this.x); + trace (o.x); + trace (o.__proto__.x); + delete x; + trace (x); + trace (this.x); + trace (o.x); + trace (o.__proto__.x); + delete x; + trace (x); + trace (this.x); + trace (o.x); + trace (o.__proto__.x); +}; + +loadMovie ("FSCommand:quit", ""); diff-tree dcfd952c19e73011ef91dd111ba944409121a82a (from 56c6cb1ab174836cf75253e228f9b1ccff0a7c21) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 11:57:43 2007 +0200 restore alphabetic ordering diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index d85db0f..a9def0e 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -180,6 +180,13 @@ EXTRA_DIST = \ height3.swf.trace \ height4.swf \ height4.swf.trace \ + if.as \ + if-5.swf \ + if-5.swf.trace \ + if-6.swf \ + if-6.swf.trace \ + if-7.swf \ + if-7.swf.trace \ initobject-stack.as \ initobject-stack-5.swf \ initobject-stack-5.swf.trace \ @@ -194,13 +201,6 @@ EXTRA_DIST = \ isnan-6.swf.trace \ isnan-7.swf \ isnan-7.swf.trace \ - if.as \ - if-5.swf \ - if-5.swf.trace \ - if-6.swf \ - if-6.swf.trace \ - if-7.swf \ - if-7.swf.trace \ jump-into-with.as \ jump-into-with.swf \ jump-into-with.swf.trace \ diff-tree 56c6cb1ab174836cf75253e228f9b1ccff0a7c21 (from 092b1c745bb08393fb2ea512cfba6fb0df6ae81d) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 11:53:29 2007 +0200 recode delete handling Delete does not delete from prototypes. diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c index de0dbd7..e0f6fe2 100644 --- a/libswfdec/swfdec_as_frame.c +++ b/libswfdec/swfdec_as_frame.c @@ -232,6 +232,43 @@ swfdec_as_frame_find_variable (SwfdecAsF return NULL; } +/* FIXME: merge with find_variable somehow */ +gboolean +swfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable) +{ + SwfdecAsScope *cur; + guint i; + + g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), FALSE); + g_return_val_if_fail (variable != NULL, FALSE); + + cur = frame->scope; + for (i = 0; i < 256; i++) { + if (swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable)) + return TRUE; + if (cur->next == NULL) + break; + cur = cur->next; + } + if (i == 256) { + swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded"); + return FALSE; + } + g_assert (SWFDEC_IS_AS_FRAME (cur)); + /* we've walked the scope chain down. Now look in the special objects. */ + /* 1) the target set via SetTarget */ + if (frame->target) { + if (swfdec_as_object_delete_variable (frame->target, variable)) + return TRUE; + } else { + /* The default target is the original object that called into us */ + if (swfdec_as_object_delete_variable (SWFDEC_AS_FRAME (cur)->thisp, variable)) + return TRUE; + } + /* 2) the global object */ + return swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable); +} + /** * swfdec_as_frame_set_target: * @frame: a #SwfdecAsFrame diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h index 7bb41b4..a790e47 100644 --- a/libswfdec/swfdec_as_frame.h +++ b/libswfdec/swfdec_as_frame.h @@ -76,6 +76,8 @@ void swfdec_as_frame_preload (SwfdecAs SwfdecAsObject *swfdec_as_frame_find_variable (SwfdecAsFrame * frame, const char * variable); +gboolean swfdec_as_frame_delete_variable (SwfdecAsFrame * frame, + const char * variable); void swfdec_as_frame_set_target (SwfdecAsFrame * frame, SwfdecAsObject * target); diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index f1898a1..7c3fcbc 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -1660,12 +1660,9 @@ static void swfdec_action_delete2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len) { const char *name; - SwfdecAsObject *object; name = swfdec_as_value_to_string (cx, swfdec_as_stack_pop (cx->frame->stack)); - object = swfdec_as_frame_find_variable (cx->frame, name); - if (object) - swfdec_as_object_delete_variable (object, name); + swfdec_as_frame_delete_variable (cx->frame, name); } static void diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index 567ff16..ce48065 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -142,17 +142,22 @@ swfdec_as_object_free_property (gpointer g_slice_free (SwfdecAsVariable, value); } -static void +static gboolean swfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable) { SwfdecAsVariable *var; var = g_hash_table_lookup (object->properties, variable); - g_assert (var); + if (var == NULL) + return FALSE; + if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT) + return TRUE; + swfdec_as_object_free_property (NULL, var, object); if (!g_hash_table_remove (object->properties, variable)) { g_assert_not_reached (); } + return TRUE; } typedef struct { @@ -314,35 +319,27 @@ swfdec_as_object_set_variable (SwfdecAsO klass->set (object, variable, value); } -static inline gboolean -swfdec_as_object_lookup (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint *flags) -{ - SwfdecAsObjectClass *klass; - SwfdecAsValue tmp_val; - guint tmp_flags; - - if (value == NULL) - value = &tmp_val; - if (flags == NULL) - flags = &tmp_flags; - - klass = SWFDEC_AS_OBJECT_GET_CLASS (object); - return klass->get (object, variable, value, flags); -} - gboolean swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint *flags) { + SwfdecAsObjectClass *klass; guint i; + SwfdecAsValue tmp_val; + guint tmp_flags; g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE); g_return_val_if_fail (variable != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); + if (value == NULL) + value = &tmp_val; + if (flags == NULL) + flags = &tmp_flags; + for (i = 0; i < 256 && object != NULL; i++) { - if (swfdec_as_object_lookup (object, variable, value, flags)) + klass = SWFDEC_AS_OBJECT_GET_CLASS (object); + if (klass->get (object, variable, value, flags)) return TRUE; object = object->prototype; } @@ -351,37 +348,21 @@ swfdec_as_object_get_variable_and_flags return FALSE; } //SWFDEC_WARNING ("no such variable %s", variable); - if (value) - SWFDEC_AS_VALUE_SET_UNDEFINED (value); - if (flags) - *flags = 0; + SWFDEC_AS_VALUE_SET_UNDEFINED (value); + *flags = 0; return FALSE; } -void +gboolean swfdec_as_object_delete_variable (SwfdecAsObject *object, const char *variable) { SwfdecAsObjectClass *klass; - guint i, flags; - g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); - g_return_if_fail (variable != NULL); + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE); + g_return_val_if_fail (variable != NULL, FALSE); - for (i = 0; i < 256 && object != NULL; i++) { - if (!swfdec_as_object_lookup (object, variable, NULL, &flags)) { - object = object->prototype; - continue; - } - if (!(flags & SWFDEC_AS_VARIABLE_PERMANENT)) { - klass = SWFDEC_AS_OBJECT_GET_CLASS (object); - klass->delete (object, variable); - } - return; - } - if (i == 256) { - swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded"); - return; - } + klass = SWFDEC_AS_OBJECT_GET_CLASS (object); + return klass->delete (object, variable); } /** @@ -674,7 +655,7 @@ swfdec_as_object_hasOwnProperty (SwfdecA name = swfdec_as_value_to_string (object->context, &argv[0]); - if (swfdec_as_object_lookup (object, name, NULL, &flags) && + if (swfdec_as_object_get_variable_and_flags (object, name, NULL, &flags) && (flags & SWFDEC_AS_VARIABLE_NATIVE) == 0) SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE); else diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h index 2fc8704..3ce58c5 100644 --- a/libswfdec/swfdec_as_object.h +++ b/libswfdec/swfdec_as_object.h @@ -80,8 +80,8 @@ struct _SwfdecAsObjectClass { const char * variable, guint flags, guint mask); - /* delete the variable - it does exists */ - void (* delete) (SwfdecAsObject * object, + /* delete the variable - return TRUE if it exists */ + gboolean (* delete) (SwfdecAsObject * object, const char * variable); /* call with every variable until func returns FALSE */ gboolean (* foreach) (SwfdecAsObject * object, @@ -119,7 +119,7 @@ gboolean swfdec_as_object_get_variable_a const char * variable, SwfdecAsValue * value, guint * flags); -void swfdec_as_object_delete_variable(SwfdecAsObject * object, +gboolean swfdec_as_object_delete_variable(SwfdecAsObject * object, const char * variable); void swfdec_as_object_set_variable_flags (SwfdecAsObject * object, diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c index 6f5902f..72dc8d2 100644 --- a/libswfdec/swfdec_as_super.c +++ b/libswfdec/swfdec_as_super.c @@ -94,10 +94,11 @@ swfdec_as_super_set_flags (SwfdecAsObjec /* if we have no variables, we also can't set its flags... */ } -static void +static gboolean swfdec_as_super_delete (SwfdecAsObject *object, const char *variable) { /* if we have no variables... */ + return FALSE; } static void diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c index e292af4..fa02b0d 100644 --- a/libswfdec/swfdec_as_with.c +++ b/libswfdec/swfdec_as_with.c @@ -67,13 +67,12 @@ swfdec_as_with_set_flags (SwfdecAsObject klass->set_flags (with->object, variable, flags, mask); } -static void +static gboolean swfdec_as_with_delete (SwfdecAsObject *object, const char *variable) { SwfdecAsWith *with = SWFDEC_AS_WITH (object); - SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object); - klass->delete (with->object, variable); + return swfdec_as_object_delete_variable (with->object, variable); } static gboolean diff-tree 092b1c745bb08393fb2ea512cfba6fb0df6ae81d (from fd685fdf3f91154644283ef97d382fe7da480e19) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 10:16:53 2007 +0200 check that prototypes are used in With statements diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index dd0ea9b..d85db0f 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -379,6 +379,13 @@ EXTRA_DIST = \ unescape2-7.swf \ unescape2-7.swf.trace \ video.flv \ + with-prototypes.as \ + with-prototypes-5.swf \ + with-prototypes-5.swf.trace \ + with-prototypes-6.swf \ + with-prototypes-6.swf.trace \ + with-prototypes-7.swf \ + with-prototypes-7.swf.trace \ xscale.swf \ xscale.swf.trace diff --git a/test/trace/with-prototypes-5.swf b/test/trace/with-prototypes-5.swf new file mode 100644 index 0000000..113132a Binary files /dev/null and b/test/trace/with-prototypes-5.swf differ diff --git a/test/trace/with-prototypes-5.swf.trace b/test/trace/with-prototypes-5.swf.trace new file mode 100644 index 0000000..1ab70b5 --- /dev/null +++ b/test/trace/with-prototypes-5.swf.trace @@ -0,0 +1,3 @@ +Check prototypes get used in With +1 +2 diff --git a/test/trace/with-prototypes-6.swf b/test/trace/with-prototypes-6.swf new file mode 100644 index 0000000..a0adce8 Binary files /dev/null and b/test/trace/with-prototypes-6.swf differ diff --git a/test/trace/with-prototypes-6.swf.trace b/test/trace/with-prototypes-6.swf.trace new file mode 100644 index 0000000..1ab70b5 --- /dev/null +++ b/test/trace/with-prototypes-6.swf.trace @@ -0,0 +1,3 @@ +Check prototypes get used in With +1 +2 diff --git a/test/trace/with-prototypes-7.swf b/test/trace/with-prototypes-7.swf new file mode 100644 index 0000000..2a9c0a6 Binary files /dev/null and b/test/trace/with-prototypes-7.swf differ diff --git a/test/trace/with-prototypes-7.swf.trace b/test/trace/with-prototypes-7.swf.trace new file mode 100644 index 0000000..1ab70b5 --- /dev/null +++ b/test/trace/with-prototypes-7.swf.trace @@ -0,0 +1,3 @@ +Check prototypes get used in With +1 +2 diff --git a/test/trace/with-prototypes.as b/test/trace/with-prototypes.as new file mode 100644 index 0000000..5ff702a --- /dev/null +++ b/test/trace/with-prototypes.as @@ -0,0 +1,14 @@ +// makeswf -v 7 -s 200x150 -r 1 -o with-prototypes.swf with-prototypes.as + +trace ("Check prototypes get used in With"); +x = 0; +_global.x = -1; +o = new Object (); +o.__proto__ = { x: 1 }; +with (o) { + trace (x); + o.x = 2; + trace (x); +}; + +loadMovie ("FSCommand:quit", ""); diff-tree fd685fdf3f91154644283ef97d382fe7da480e19 (from 466b3016671ffa1985339c0fe3075cc19e32f3c7) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 10:14:24 2007 +0200 try to get variables also from prototypes diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c index b5c6ce1..e292af4 100644 --- a/libswfdec/swfdec_as_with.c +++ b/libswfdec/swfdec_as_with.c @@ -43,9 +43,8 @@ swfdec_as_with_get (SwfdecAsObject *obje SwfdecAsValue *val, guint *flags) { SwfdecAsWith *with = SWFDEC_AS_WITH (object); - SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object); - return klass->get (with->object, variable, val, flags); + return swfdec_as_object_get_variable_and_flags (with->object, variable, val, flags); } static void diff-tree 466b3016671ffa1985339c0fe3075cc19e32f3c7 (from f1f78721fb699bbb94bb90edb82b2bbbe203b284) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 10:11:03 2007 +0200 add swfdec_as_object_get_variable_and_flags() The variable get/set API needs some overhaul I think diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index a495ed4..567ff16 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -332,8 +332,8 @@ swfdec_as_object_lookup (SwfdecAsObject } gboolean -swfdec_as_object_get_variable (SwfdecAsObject *object, - const char *variable, SwfdecAsValue *value) +swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint *flags) { guint i; @@ -342,7 +342,7 @@ swfdec_as_object_get_variable (SwfdecAsO g_return_val_if_fail (value != NULL, FALSE); for (i = 0; i < 256 && object != NULL; i++) { - if (swfdec_as_object_lookup (object, variable, value, NULL)) + if (swfdec_as_object_lookup (object, variable, value, flags)) return TRUE; object = object->prototype; } @@ -351,7 +351,10 @@ swfdec_as_object_get_variable (SwfdecAsO return FALSE; } //SWFDEC_WARNING ("no such variable %s", variable); - SWFDEC_AS_VALUE_SET_UNDEFINED (value); + if (value) + SWFDEC_AS_VALUE_SET_UNDEFINED (value); + if (flags) + *flags = 0; return FALSE; } diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h index a9b637d..2fc8704 100644 --- a/libswfdec/swfdec_as_object.h +++ b/libswfdec/swfdec_as_object.h @@ -112,9 +112,13 @@ void swfdec_as_object_unroot (Swfdec void swfdec_as_object_set_variable (SwfdecAsObject * object, const char * variable, const SwfdecAsValue * value); -gboolean swfdec_as_object_get_variable (SwfdecAsObject * object, +#define swfdec_as_object_get_variable(object, variable, value) \ + swfdec_as_object_get_variable_and_flags (object, variable, value, NULL) +gboolean swfdec_as_object_get_variable_and_flags + (SwfdecAsObject * object, const char * variable, - SwfdecAsValue * value); + SwfdecAsValue * value, + guint * flags); void swfdec_as_object_delete_variable(SwfdecAsObject * object, const char * variable); void swfdec_as_object_set_variable_flags diff-tree f1f78721fb699bbb94bb90edb82b2bbbe203b284 (from 7311076213bb5ceb0c56b64632ea4e0b07c21d72) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 10:00:16 2007 +0200 remove swfdec_as_object_find_variable and use swfdec_as_object_get_variable instead diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c index de18973..de0dbd7 100644 --- a/libswfdec/swfdec_as_frame.c +++ b/libswfdec/swfdec_as_frame.c @@ -195,17 +195,16 @@ swfdec_as_frame_set_this (SwfdecAsFrame SwfdecAsObject * swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const char *variable) { - SwfdecAsObject *ret = NULL; SwfdecAsScope *cur; guint i; + SwfdecAsValue val; g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL); g_return_val_if_fail (variable != NULL, NULL); cur = frame->scope; for (i = 0; i < 256; i++) { - ret = swfdec_as_object_find_variable (SWFDEC_AS_OBJECT (cur), variable); - if (ret) + if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), variable, &val)) return SWFDEC_AS_OBJECT (cur); if (cur->next == NULL) break; @@ -219,18 +218,18 @@ swfdec_as_frame_find_variable (SwfdecAsF /* we've walked the scope chain down. Now look in the special objects. */ /* 1) the target set via SetTarget */ if (frame->target) { - ret = swfdec_as_object_find_variable (frame->target, variable); - if (ret) + if (swfdec_as_object_get_variable (frame->target, variable, &val)) return frame->target; } else { /* The default target is the original object that called into us */ - ret = swfdec_as_object_find_variable (SWFDEC_AS_FRAME (cur)->thisp, variable); - if (ret) + if (swfdec_as_object_get_variable (SWFDEC_AS_FRAME (cur)->thisp, variable, &val)) return SWFDEC_AS_FRAME (cur)->thisp; } /* 2) the global object */ - ret = swfdec_as_object_find_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable); - return ret ? SWFDEC_AS_OBJECT (frame)->context->global : NULL; + if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable, &val)) + return SWFDEC_AS_OBJECT (frame)->context->global; + + return NULL; } /** diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index bdfe5d3..a495ed4 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -381,27 +381,6 @@ swfdec_as_object_delete_variable (Swfdec } } -SwfdecAsObject * -swfdec_as_object_find_variable (SwfdecAsObject *object, - const char *variable) -{ - guint i; - - g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); - g_return_val_if_fail (variable != NULL, NULL); - - for (i = 0; i < 256 && object != NULL; i++) { - if (swfdec_as_object_lookup (object, variable, NULL, NULL)) - return object; - object = object->prototype; - } - if (i == 256) { - swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded"); - return NULL; - } - return NULL; -} - /** * swfdec_as_object_set_variable_flags: * @object: a #SwfdecAsObject diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h index c703fb0..a9b637d 100644 --- a/libswfdec/swfdec_as_object.h +++ b/libswfdec/swfdec_as_object.h @@ -117,8 +117,6 @@ gboolean swfdec_as_object_get_variable ( SwfdecAsValue * value); void swfdec_as_object_delete_variable(SwfdecAsObject * object, const char * variable); -SwfdecAsObject *swfdec_as_object_find_variable (SwfdecAsObject * object, - const char * variable); void swfdec_as_object_set_variable_flags (SwfdecAsObject * object, const char * variable, diff-tree 7311076213bb5ceb0c56b64632ea4e0b07c21d72 (from 777b3d0c598129177ec806335ba681b41fd1d239) Author: Benjamin Otte <otte at gnome.org> Date: Wed Jun 6 09:59:34 2007 +0200 Fix comment diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h index c2423e3..7bb41b4 100644 --- a/libswfdec/swfdec_as_frame.h +++ b/libswfdec/swfdec_as_frame.h @@ -49,7 +49,7 @@ struct _SwfdecAsFrame { char * function_name; /* name of function */ /* normal execution */ SwfdecScript * script; /* script being executed */ - SwfdecAsScope * scope; /* first object in scope chain (can be NULL) */ + SwfdecAsScope * scope; /* first object in scope chain (either this frame or a with object) */ SwfdecAsObject * target; /* target to use instead of last object in scope chain */ SwfdecAsObject * var_object; /* new variables go here */ SwfdecAsValue * registers; /* the registers */
Reasonably Related Threads
- Branch 'as' - 3 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_types.c
- Branch 'as' - 9 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_stack.c libswfdec/swfdec_as_stack.h
- 2 commits - libswfdec/swfdec_debugger.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h
- 3 commits - doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_boolean.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c
- Branch 'vivi' - 12 commits - libswfdec-gtk/swfdec_gtk_player.c libswfdec-gtk/swfdec_gtk_player.h libswfdec/Makefile.am libswfdec/swfdec_as_array.h libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_debugger.c