Pekka Lampila
2007-Oct-25 15:03 UTC
[Swfdec] 12 commits - libswfdec/swfdec_as_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_field_movie.c test/trace
libswfdec/swfdec_as_internal.h | 4 libswfdec/swfdec_as_interpret.c | 44 +++++++ libswfdec/swfdec_as_object.c | 73 +++++++++---- libswfdec/swfdec_text_field_movie.c | 20 +-- libswfdec/swfdec_text_field_movie_as.c | 6 - test/trace/Makefile.am | 45 ++++++-- test/trace/instance-of-5.swf |binary test/trace/instance-of-5.swf.trace | 56 ++++++++++ test/trace/instance-of-6.swf |binary test/trace/instance-of-6.swf.trace | 58 ++++++++++ test/trace/instance-of-7.swf |binary test/trace/instance-of-7.swf.trace | 58 ++++++++++ test/trace/instance-of-8.swf |binary test/trace/instance-of-8.swf.trace | 58 ++++++++++ test/trace/instance-of.as | 82 ++++++++++++++ test/trace/prototype-handling-5.swf |binary test/trace/prototype-handling-5.swf.trace | 127 ++++++++++++++++++++++ test/trace/prototype-handling-6.swf |binary test/trace/prototype-handling-6.swf.trace | 139 ++++++++++++++++++++++++ test/trace/prototype-handling-7.swf |binary test/trace/prototype-handling-7.swf.trace | 139 ++++++++++++++++++++++++ test/trace/prototype-handling-8.swf |binary test/trace/prototype-handling-8.swf.trace | 140 +++++++++++++++++++++++++ test/trace/prototype-handling.as | 118 +++++++++++++++++++++ test/trace/text-field-replace-text-5.swf |binary test/trace/text-field-replace-text-5.swf.trace | 9 + test/trace/text-field-replace-text-6.swf |binary test/trace/text-field-replace-text-6.swf.trace | 9 + test/trace/text-field-replace-text-7.swf |binary test/trace/text-field-replace-text-7.swf.trace | 9 + test/trace/text-field-replace-text-8.swf |binary test/trace/text-field-replace-text-8.swf.trace | 9 + test/trace/text-field-replace-text.as | 53 +++++++++ test/trace/textformat-init-5.swf |binary test/trace/textformat-init-5.swf.trace | 2 test/trace/textformat-init-6.swf |binary test/trace/textformat-init-6.swf.trace | 2 test/trace/textformat-init-7.swf |binary test/trace/textformat-init-7.swf.trace | 2 test/trace/textformat-init-8.swf |binary test/trace/textformat-init-8.swf.trace | 2 test/trace/textformat-init.as | 5 42 files changed, 1224 insertions(+), 45 deletions(-) New commits: commit e872e8da0fc9e844df32212e268bc4c44fdc065e Merge: 1b395e8... 429b509... Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 18:02:11 2007 +0300 Merge commit 'origin' commit 1b395e83331d516388a4370df93936b7f544b1ae Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 18:00:58 2007 +0300 Add a test to see how __proto__ is handled in different places diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index bcada90..5bde4df 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -1261,6 +1261,15 @@ EXTRA_DIST = \ prototype-addProperty-7.swf.trace \ prototype-addProperty-8.swf \ prototype-addProperty-8.swf.trace \ + prototype-handling.as \ + prototype-handling-5.swf \ + prototype-handling-5.swf.trace \ + prototype-handling-6.swf \ + prototype-handling-6.swf.trace \ + prototype-handling-7.swf \ + prototype-handling-7.swf.trace \ + prototype-handling-8.swf \ + prototype-handling-8.swf.trace \ prototype-movie.as \ prototype-movie-5.swf \ prototype-movie-5.swf.trace \ diff --git a/test/trace/prototype-handling-5.swf b/test/trace/prototype-handling-5.swf new file mode 100644 index 0000000..54fd55a Binary files /dev/null and b/test/trace/prototype-handling-5.swf differ diff --git a/test/trace/prototype-handling-5.swf.trace b/test/trace/prototype-handling-5.swf.trace new file mode 100644 index 0000000..e7dab0c --- /dev/null +++ b/test/trace/prototype-handling-5.swf.trace @@ -0,0 +1,127 @@ +Test how different functions handle __proto__ and it's propflags +instanceOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +false +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +false +o.__proto__: 2048 +true +o.__proto__: 4096 +false +o.__proto__: deleted +false +get: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +undefined +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +undefined +o.__proto__: 2048 +true +o.__proto__: 4096 +undefined +o.__proto__: deleted +undefined +set: +o.__proto__: 2 +o.__proto__: 4 +o.__proto__: 8 +o.__proto__: 16 +o.__proto__: 32 +o.__proto__: 64 +o.__proto__: 128 +o.__proto__: 256 +o.__proto__: 512 +o.__proto__: 1024 +o.__proto__: 2048 +o.__proto__: 4096 +o.__proto__: deleted +for ... in: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +false +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +false +o.__proto__: 2048 +true +o.__proto__: 4096 +false +o.__proto__: deleted +false +isPrototypeOf: +undefined +o.__proto__: 2 +undefined +o.__proto__: 4 +undefined +o.__proto__: 8 +undefined +o.__proto__: 16 +undefined +o.__proto__: 32 +undefined +o.__proto__: 64 +undefined +o.__proto__: 128 +undefined +o.__proto__: 256 +undefined +o.__proto__: 512 +undefined +o.__proto__: 1024 +undefined +o.__proto__: 2048 +undefined +o.__proto__: 4096 +undefined +o.__proto__: deleted +undefined diff --git a/test/trace/prototype-handling-6.swf b/test/trace/prototype-handling-6.swf new file mode 100644 index 0000000..3d16c9d Binary files /dev/null and b/test/trace/prototype-handling-6.swf differ diff --git a/test/trace/prototype-handling-6.swf.trace b/test/trace/prototype-handling-6.swf.trace new file mode 100644 index 0000000..20768bc --- /dev/null +++ b/test/trace/prototype-handling-6.swf.trace @@ -0,0 +1,139 @@ +Test how different functions handle __proto__ and it's propflags +instanceOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +false +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false +get: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +undefined +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +undefined +set: +test_set: true +o.__proto__: 2 +test_set: true +o.__proto__: 4 +test_set: true +o.__proto__: 8 +test_set: true +o.__proto__: 16 +test_set: true +o.__proto__: 32 +test_set: true +o.__proto__: 64 +test_set: true +o.__proto__: 128 +test_set: true +o.__proto__: 256 +test_set: true +o.__proto__: 512 +test_set: true +o.__proto__: 1024 +o.__proto__: 2048 +test_set: true +o.__proto__: 4096 +test_set: true +o.__proto__: deleted +for ... in: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +false +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false +isPrototypeOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +false +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false diff --git a/test/trace/prototype-handling-7.swf b/test/trace/prototype-handling-7.swf new file mode 100644 index 0000000..e8f8bc1 Binary files /dev/null and b/test/trace/prototype-handling-7.swf differ diff --git a/test/trace/prototype-handling-7.swf.trace b/test/trace/prototype-handling-7.swf.trace new file mode 100644 index 0000000..26914d0 --- /dev/null +++ b/test/trace/prototype-handling-7.swf.trace @@ -0,0 +1,139 @@ +Test how different functions handle __proto__ and it's propflags +instanceOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +false +o.__proto__: deleted +false +get: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +true +set: +test_set: true +o.__proto__: 2 +test_set: true +o.__proto__: 4 +test_set: true +o.__proto__: 8 +test_set: true +o.__proto__: 16 +test_set: true +o.__proto__: 32 +test_set: true +o.__proto__: 64 +test_set: true +o.__proto__: 128 +test_set: true +o.__proto__: 256 +test_set: true +o.__proto__: 512 +test_set: true +o.__proto__: 1024 +test_set: true +o.__proto__: 2048 +test_set: true +o.__proto__: 4096 +o.__proto__: deleted +for ... in: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +false +o.__proto__: deleted +false +isPrototypeOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +false +o.__proto__: deleted +false diff --git a/test/trace/prototype-handling-8.swf b/test/trace/prototype-handling-8.swf new file mode 100644 index 0000000..c939537 Binary files /dev/null and b/test/trace/prototype-handling-8.swf differ diff --git a/test/trace/prototype-handling-8.swf.trace b/test/trace/prototype-handling-8.swf.trace new file mode 100644 index 0000000..90c95fa --- /dev/null +++ b/test/trace/prototype-handling-8.swf.trace @@ -0,0 +1,140 @@ +Test how different functions handle __proto__ and it's propflags +instanceOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false +get: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +true +set: +test_set: true +o.__proto__: 2 +test_set: true +o.__proto__: 4 +test_set: true +o.__proto__: 8 +test_set: true +o.__proto__: 16 +test_set: true +o.__proto__: 32 +test_set: true +o.__proto__: 64 +test_set: true +o.__proto__: 128 +test_set: true +o.__proto__: 256 +test_set: true +o.__proto__: 512 +test_set: true +o.__proto__: 1024 +test_set: true +o.__proto__: 2048 +test_set: true +o.__proto__: 4096 +test_set: true +o.__proto__: deleted +for ... in: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false +isPrototypeOf: +true +o.__proto__: 2 +true +o.__proto__: 4 +true +o.__proto__: 8 +true +o.__proto__: 16 +true +o.__proto__: 32 +true +o.__proto__: 64 +true +o.__proto__: 128 +true +o.__proto__: 256 +true +o.__proto__: 512 +true +o.__proto__: 1024 +true +o.__proto__: 2048 +true +o.__proto__: 4096 +true +o.__proto__: deleted +false diff --git a/test/trace/prototype-handling.as b/test/trace/prototype-handling.as new file mode 100644 index 0000000..6dcfb9d --- /dev/null +++ b/test/trace/prototype-handling.as @@ -0,0 +1,118 @@ +// makeswf -v 7 -r 1 -o test-7.swf test.as + +trace ("Test how different functions handle __proto__ and it's propflags"); + +trace ("instanceOf:"); + +var p = { prototype: {} }; +var o = { __proto__: p.prototype }; + +trace (o instanceOf p); +for (var i = 1; i <= 12; i++) { + trace ("o.__proto__: " + Math.pow (2, i)); + ASSetPropFlags (o, "__proto__", Math.pow (2, i), 0); + trace (o instanceOf p); + ASSetPropFlags (o, "__proto__", 0, Math.pow (2, i)); +} +trace ("o.__proto__: deleted"); +delete o.__proto__; +trace (o instanceOf p); + + +trace ("get:"); + +p = { test: true }; +o = { __proto__: p }; + +trace (o.test); +for (var i = 1; i <= 12; i++) { + trace ("o.__proto__: " + Math.pow (2, i)); + ASSetPropFlags (o, "__proto__", Math.pow (2, i), 0); + trace (o.test); + ASSetPropFlags (o, "__proto__", 0, Math.pow (2, i)); +} +trace ("o.__proto__: deleted"); +delete o.__proto__; +trace (o.test); + + +trace ("set:"); + +function test_get () { + trace ("test_get"); + return true; +} + +function test_set () { + trace ("test_set: " + arguments); +} + +p = {}; +p.addProperty ("test", test_get, test_set); +o = { __proto__: p }; +o.hasOwnProperty = ASnative (101, 5); + +o.test = true; +delete o.test; +for (var i = 1; i <= 12; i++) { + trace ("o.__proto__: " + Math.pow (2, i)); + ASSetPropFlags (o, "__proto__", Math.pow (2, i), 0); + o.test = true; + delete o.test; + ASSetPropFlags (o, "__proto__", 0, Math.pow (2, i)); +} +trace ("o.__proto__: deleted"); +delete o.__proto__; +o.test = true; + + +trace ("for ... in:"); + +p = { test: true }; +o = { __proto__: p }; + +var found = false; +for (var prop in o) { + if (prop == "test") + found = true; +} +trace (found); +for (var i = 1; i <= 12; i++) { + trace ("o.__proto__: " + Math.pow (2, i)); + ASSetPropFlags (o, "__proto__", Math.pow (2, i), 0); + found = false; + for (var prop in o) { + if (prop == "test") + found = true; + } + trace (found); + ASSetPropFlags (o, "__proto__", 0, Math.pow (2, i)); +} +trace ("o.__proto__: deleted"); +delete o.__proto__; +found = false; +for (var prop in o) { + if (prop == "test") + found = true; +} +trace (found); + + +trace ("isPrototypeOf:"); + +p = { test: true }; +o = { __proto__: p }; + +trace (p.isPrototypeOf (o)); +for (var i = 1; i <= 12; i++) { + trace ("o.__proto__: " + Math.pow (2, i)); + ASSetPropFlags (o, "__proto__", Math.pow (2, i), 0); + trace (p.isPrototypeOf (o)); + ASSetPropFlags (o, "__proto__", 0, Math.pow (2, i)); +} +trace ("o.__proto__: deleted"); +delete o.__proto__; +trace (p.isPrototypeOf (o)); + + +loadMovie ("FSCommand:quit", ""); commit 28bf895b93b1f95aa372a78adbda188718be6bee Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 17:55:44 2007 +0300 Fix test/trace/Makefile.am to say text-format-init not -properties (oops) diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index d32492e..bcada90 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -1963,15 +1963,15 @@ EXTRA_DIST = \ textformat-7.swf.trace \ textformat-8.swf \ textformat-8.swf.trace \ - textformat-properties.as \ - textformat-properties-5.swf \ - textformat-properties-5.swf.trace \ - textformat-properties-6.swf \ - textformat-properties-6.swf.trace \ - textformat-properties-7.swf \ - textformat-properties-7.swf.trace \ - textformat-properties-8.swf \ - textformat-properties-8.swf.trace \ + textformat-init.as \ + textformat-init-5.swf \ + textformat-init-5.swf.trace \ + textformat-init-6.swf \ + textformat-init-6.swf.trace \ + textformat-init-7.swf \ + textformat-init-7.swf.trace \ + textformat-init-8.swf \ + textformat-init-8.swf.trace \ textformat-valueof.as \ textformat-valueof-5.swf \ textformat-valueof-5.swf.trace \ commit 0e27bb910e8fce7932affabef8c9c4b354435b50 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 17:46:19 2007 +0300 Replace swfdec_as_object_prototype_for_version, use for instanceOf too swfdec_as_object_prototype_for_version was replaced with swfdec_as_object_get_prototype and swfdec_as_object_get_prototype_internal diff --git a/libswfdec/swfdec_as_internal.h b/libswfdec/swfdec_as_internal.h index 374232d..6dc088d 100644 --- a/libswfdec/swfdec_as_internal.h +++ b/libswfdec/swfdec_as_internal.h @@ -71,9 +71,7 @@ void swfdec_as_object_init_context (SwfdecAsContext * context, guint version); void swfdec_as_object_decode (SwfdecAsObject * obj, const char * str); -SwfdecAsObject * swfdec_as_object_prototype_for_version (SwfdecAsObject *object, - guint version, - gboolean check7); +SwfdecAsObject * swfdec_as_object_get_prototype (SwfdecAsObject * object); void swfdec_as_object_run_with_security (SwfdecAsObject * object, SwfdecScript * script, diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 8f5012c..b30bde8 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -2206,15 +2206,11 @@ swfdec_action_instance_of (SwfdecAsContext *cx, guint action, prototype = SWFDEC_AS_VALUE_GET_OBJECT (&val); class = object; - swfdec_as_object_get_variable (class, SWFDEC_AS_STR___proto__, &val); - while (SWFDEC_AS_VALUE_IS_OBJECT (&val)) - { - class = SWFDEC_AS_VALUE_GET_OBJECT (&val); + while ((class = swfdec_as_object_get_prototype (class)) != NULL) { if (class == prototype) { SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), TRUE); break; } - swfdec_as_object_get_variable (class, SWFDEC_AS_STR___proto__, &val); } } @@ -2275,7 +2271,7 @@ swfdec_action_do_enumerate (SwfdecAsContext *cx, SwfdecAsObject *object) for (i = 0; i < 256 && object; i++) { swfdec_as_object_foreach (object, swfdec_action_enumerate_foreach, &list); - object = swfdec_as_object_prototype_for_version (object, cx->version, TRUE); + object = swfdec_as_object_get_prototype (object); } if (i == 256) { swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded"); diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index a7d45d7..6c4feb9 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -290,10 +290,20 @@ swfdec_as_watch_unref (SwfdecAsWatch *watch) } } -SwfdecAsObject * -swfdec_as_object_prototype_for_version (SwfdecAsObject *object, guint version, - gboolean check7) +/* + * Like swfdec_as_object_get_prototype, but doesn't check 8_UP flag when + * version is 7 and doesn't check if the property has been deleted if version + * is 6 or earlier + */ +static SwfdecAsObject * +swfdec_as_object_get_prototype_internal (SwfdecAsObject *object) { + int version; + + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); + + version = object->context->version; + if (object->prototype == NULL) return NULL; @@ -302,14 +312,44 @@ swfdec_as_object_prototype_for_version (SwfdecAsObject *object, guint version, // don't check for NOT_6 flag if (object->prototype_flags & SWFDEC_AS_VARIABLE_VERSION_7_UP && version < 7) return NULL; - // only check 8_UP for version < 6 + // don't check 8_UP for version 6 or 7 if (object->prototype_flags & SWFDEC_AS_VARIABLE_VERSION_8_UP && version < 6) return NULL; - if (check7) { - if (object->prototype_flags & SWFDEC_AS_VARIABLE_VERSION_8_UP && version == 7) - return NULL; - } + // check that it exists, if version < 7 + if (version < 7 && + !swfdec_as_object_hash_lookup (object, SWFDEC_AS_STR___proto__)) + return NULL; + + return object->prototype; +} + +/* + * Get's the object->prototype, if propflags allow it for current version and + * if it hasn't been deleted from the object already + */ +SwfdecAsObject * +swfdec_as_object_get_prototype (SwfdecAsObject *object) +{ + int version; + SwfdecAsObject *prototype; + + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL); + + version = object->context->version; + + prototype = swfdec_as_object_get_prototype_internal (object); + + if (prototype == NULL) + return NULL; + // check 8_UP for version 7, still not for version 6 + if (object->prototype_flags & SWFDEC_AS_VARIABLE_VERSION_8_UP && + version == 7) + return NULL; + // require it to exist even on version >= 7 + if (version >= 7 && + !swfdec_as_object_hash_lookup (object, SWFDEC_AS_STR___proto__)) + return NULL; return object->prototype; } @@ -329,15 +369,13 @@ swfdec_as_object_do_set (SwfdecAsObject *object, const char *variable, guint i; SwfdecAsObject *proto; - proto = swfdec_as_object_prototype_for_version (object, - object->context->version, FALSE); + proto = swfdec_as_object_get_prototype (object); for (i = 0; i < SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT && proto; i++) { var = swfdec_as_object_hash_lookup (proto, variable); if (var && var->get) break; - proto = swfdec_as_object_prototype_for_version (proto, - proto->context->version, FALSE); + proto = swfdec_as_object_get_prototype (proto); var = NULL; } if (i == SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT) { @@ -443,11 +481,8 @@ swfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable) if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT) return SWFDEC_AS_DELETE_NOT_DELETED; - // special case: in version > 6 deleting doesn't stop __proto__ from working - if (variable == SWFDEC_AS_STR___proto__ && object->context->version <= 6) { - object->prototype = NULL; - object->prototype_flags = 0; - } + // Note: We won't remove object->prototype, even if __proto__ is deleted + swfdec_as_object_free_property (NULL, var, object); if (!g_hash_table_remove (object->properties, variable)) { g_assert_not_reached (); @@ -826,8 +861,7 @@ swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object, *pobject = cur; return TRUE; } - cur = swfdec_as_object_prototype_for_version (cur, cur->context->version, - FALSE); + cur = swfdec_as_object_get_prototype_internal (cur); } if (i > SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT) { swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded"); @@ -1409,7 +1443,7 @@ swfdec_as_object_isPrototypeOf (SwfdecAsContext *cx, if (class == NULL) return; - while ((class = swfdec_as_object_prototype_for_version (class, cx->version, TRUE)) != NULL) { + while ((class = swfdec_as_object_get_prototype (class)) != NULL) { if (object == class) { SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE); return; commit 7a422e1eed7cf157fa0eecb3bb4f1060423174c9 Merge: 379173f... 45ecc75... Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 17:22:21 2007 +0300 Merge commit 'origin' commit 379173f63232e5009e5ebbce3fb64dfda8076217 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 15:08:20 2007 +0300 Add a test case for instanceOf diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index a39326f..ff8b3ce 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -762,6 +762,15 @@ EXTRA_DIST = \ instance-name-loaded-6.swf.trace \ instance-name-loaded-7.swf \ instance-name-loaded-7.swf.trace \ + instance-of.as \ + instance-of-5.swf \ + instance-of-5.swf.trace \ + instance-of-6.swf \ + instance-of-6.swf.trace \ + instance-of-7.swf \ + instance-of-7.swf.trace \ + instance-of-8.swf \ + instance-of-8.swf.trace \ invalid-variable-name.as \ invalid-variable-name-5.swf \ invalid-variable-name-5.swf.trace \ diff --git a/test/trace/instance-of-5.swf b/test/trace/instance-of-5.swf new file mode 100644 index 0000000..8efa11e Binary files /dev/null and b/test/trace/instance-of-5.swf differ diff --git a/test/trace/instance-of-5.swf.trace b/test/trace/instance-of-5.swf.trace new file mode 100644 index 0000000..c10f962 --- /dev/null +++ b/test/trace/instance-of-5.swf.trace @@ -0,0 +1,56 @@ +0: Object +1: Object.prototype +2: new Object () +3: Object () +4: {} +5: new Object (), properties removed +6: {}, properties added +7: String +8: String.prototype +9: new String () +10: String () +11: "test" +12: Number +13: Number.prototype +14: new Number () +15: Number () +16: 1 +17: Array +18: Array.prototype +19: new Array () +20: Array () +21: [] +22: new Array (), __proto__ changed and restored +23: XML +24: MovieClip +25: this +26: TextField + + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 0 + 1 + 2 0 + 3 + 4 0 + 5 + 6 0 + 7 + 8 0 + 9 0 7 +10 +11 +12 +13 0 +14 0 12 +15 +16 +17 +18 0 +19 0 17 +20 0 17 +21 0 17 +22 0 17 +23 +24 +25 0 24 +26 diff --git a/test/trace/instance-of-6.swf b/test/trace/instance-of-6.swf new file mode 100644 index 0000000..c28ea4c Binary files /dev/null and b/test/trace/instance-of-6.swf differ diff --git a/test/trace/instance-of-6.swf.trace b/test/trace/instance-of-6.swf.trace new file mode 100644 index 0000000..c1e8354 --- /dev/null +++ b/test/trace/instance-of-6.swf.trace @@ -0,0 +1,58 @@ +0: Object +1: Object.prototype +2: new Object () +3: Object () +4: {} +5: new Object (), properties removed +6: {}, properties added +7: String +8: String.prototype +9: new String () +10: String () +11: "test" +12: Number +13: Number.prototype +14: new Number () +15: Number () +16: 1 +17: Array +18: Array.prototype +19: new Array () +20: Array () +21: [] +22: new Array (), __proto__ changed and restored +23: XML +24: MovieClip +25: this +26: TextField +27: createTextField (...) + + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 + 0 0 + 1 + 2 0 + 3 + 4 0 + 5 + 6 0 + 7 0 + 8 0 + 9 0 7 +10 +11 +12 0 +13 0 +14 0 12 +15 +16 +17 0 +18 0 +19 0 17 +20 0 17 +21 0 17 +22 0 17 +23 0 +24 0 +25 0 24 +26 0 +27 0 26 diff --git a/test/trace/instance-of-7.swf b/test/trace/instance-of-7.swf new file mode 100644 index 0000000..51cd6c3 Binary files /dev/null and b/test/trace/instance-of-7.swf differ diff --git a/test/trace/instance-of-7.swf.trace b/test/trace/instance-of-7.swf.trace new file mode 100644 index 0000000..c1e8354 --- /dev/null +++ b/test/trace/instance-of-7.swf.trace @@ -0,0 +1,58 @@ +0: Object +1: Object.prototype +2: new Object () +3: Object () +4: {} +5: new Object (), properties removed +6: {}, properties added +7: String +8: String.prototype +9: new String () +10: String () +11: "test" +12: Number +13: Number.prototype +14: new Number () +15: Number () +16: 1 +17: Array +18: Array.prototype +19: new Array () +20: Array () +21: [] +22: new Array (), __proto__ changed and restored +23: XML +24: MovieClip +25: this +26: TextField +27: createTextField (...) + + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 + 0 0 + 1 + 2 0 + 3 + 4 0 + 5 + 6 0 + 7 0 + 8 0 + 9 0 7 +10 +11 +12 0 +13 0 +14 0 12 +15 +16 +17 0 +18 0 +19 0 17 +20 0 17 +21 0 17 +22 0 17 +23 0 +24 0 +25 0 24 +26 0 +27 0 26 diff --git a/test/trace/instance-of-8.swf b/test/trace/instance-of-8.swf new file mode 100644 index 0000000..e91f063 Binary files /dev/null and b/test/trace/instance-of-8.swf differ diff --git a/test/trace/instance-of-8.swf.trace b/test/trace/instance-of-8.swf.trace new file mode 100644 index 0000000..c1e8354 --- /dev/null +++ b/test/trace/instance-of-8.swf.trace @@ -0,0 +1,58 @@ +0: Object +1: Object.prototype +2: new Object () +3: Object () +4: {} +5: new Object (), properties removed +6: {}, properties added +7: String +8: String.prototype +9: new String () +10: String () +11: "test" +12: Number +13: Number.prototype +14: new Number () +15: Number () +16: 1 +17: Array +18: Array.prototype +19: new Array () +20: Array () +21: [] +22: new Array (), __proto__ changed and restored +23: XML +24: MovieClip +25: this +26: TextField +27: createTextField (...) + + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 + 0 0 + 1 + 2 0 + 3 + 4 0 + 5 + 6 0 + 7 0 + 8 0 + 9 0 7 +10 +11 +12 0 +13 0 +14 0 12 +15 +16 +17 0 +18 0 +19 0 17 +20 0 17 +21 0 17 +22 0 17 +23 0 +24 0 +25 0 24 +26 0 +27 0 26 diff --git a/test/trace/instance-of.as b/test/trace/instance-of.as new file mode 100644 index 0000000..436da43 --- /dev/null +++ b/test/trace/instance-of.as @@ -0,0 +1,82 @@ +// makeswf -v 7 -r 1 -o instance-of-7.swf instance-of.as + +var empty_object_properties_added = {}; +var new_object_properties_removed = new Object (); +ASSetPropFlags (new_object_properties_removed, null, 0, 7); +for (var prop in new_object_properties_removed) { + empty_object_properties_added[prop] = new_object_properties_removed[prop]; + delete new_object_properties_removed[prop]; +} + +var new_array_proto_changed_and_restored = new Array (); +new_array_proto_changed_and_restored.__proto__ = XML.prototype; +new_array_proto_changed_and_restored.__proto__ = Array.prototype; + +this.createTextField ("t", 0, 0, 0, 100, 100); + +var objects = []; +objects.push ({ o: Object, n: "Object" }); +objects.push ({ o: Object.prototype, n: "Object.prototype" }); +objects.push ({ o: new Object (), n: "new Object ()" }); +objects.push ({ o: Object (), n: "Object ()" }); +objects.push ({ o: {}, n: "{}" }); +objects.push ({ o: new_object_properties_removed, n: "new Object (), properties removed" }); +objects.push ({ o: empty_object_properties_added, n: "{}, properties added" }); +objects.push ({ o: String, n: "String" }); +objects.push ({ o: String.prototype, n: "String.prototype" }); +objects.push ({ o: new String (), n: "new String ()" }); +objects.push ({ o: String (), n: "String ()" }); +objects.push ({ o: "test", n: "\"test\"" }); +objects.push ({ o: Number, n: "Number" }); +objects.push ({ o: Number.prototype, n: "Number.prototype" }); +objects.push ({ o: new Number (), n: "new Number ()" }); +objects.push ({ o: Number (), n: "Number ()" }); +objects.push ({ o: 1, n: "1" }); +objects.push ({ o: Array, n: "Array" }); +objects.push ({ o: Array.prototype, n: "Array.prototype" }); +objects.push ({ o: new Array (), n: "new Array ()" }); +objects.push ({ o: Array (), n: "Array ()" }); +objects.push ({ o: [], n: "[]" }); +objects.push ({ o: new_array_proto_changed_and_restored, n: "new Array (), __proto__ changed and restored" }); +objects.push ({ o: XML, n: "XML" }); +objects.push ({ o: MovieClip, n: "MovieClip" }); +objects.push ({ o: this, n: "this" }); +objects.push ({ o: TextField, n: "TextField" }); +// FIXME +#if __SWF_VERSION__ > 5 +objects.push ({ o: t, n: "createTextField (...)" }); +#endif + +for (var i = 0; i < objects.length; i++) { + trace (i + ": " + objects[i].n); +} +trace (""); + +var str = " "; +for (var i = 0; i < objects.length; i++) { + if (i < 10) + str += " "; + str += " " + i; +} +trace (str); + +for (var i = 0; i < objects.length; i++) { + if (i < 10) { + str = " "; + } else { + str = ""; + } + str += i; + for (var j = 0; j < objects.length; j++) { + if (objects[i].o instanceOf objects[j].o) { + if (j < 10) + str += " "; + str += " "+j; + } else { + str += " "; + } + } + trace (str); +} + +loadMovie ("FSCommand:quit", ""); commit 8a03a1c260c8bb822f7585da4ba006c014109590 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 14:49:16 2007 +0300 Implement the InstanceOf ActionScript action diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 99a1215..8f5012c 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -2175,6 +2175,50 @@ swfdec_action_get_time (SwfdecAsContext *cx, guint action, const guint8 *data, g } static void +swfdec_action_instance_of (SwfdecAsContext *cx, guint action, + const guint8 *data, guint len) +{ + SwfdecAsValue val, *val_p; + SwfdecAsObject *object, *class, *constructor, *prototype; + + val_p = swfdec_as_stack_pop (cx); + if (SWFDEC_AS_VALUE_IS_OBJECT (val_p)) { + constructor = SWFDEC_AS_VALUE_GET_OBJECT (val_p); + } else { + constructor = NULL; + } + + val_p = swfdec_as_stack_pop (cx); + if (SWFDEC_AS_VALUE_IS_OBJECT (val_p)) { + object = SWFDEC_AS_VALUE_GET_OBJECT (val_p); + } else { + object = NULL; + } + + SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_push (cx), FALSE); + + if (object == NULL || constructor == NULL) + return; + + swfdec_as_object_get_variable (constructor, SWFDEC_AS_STR_prototype, &val); + if (!SWFDEC_AS_VALUE_IS_OBJECT (&val)) + return; + prototype = SWFDEC_AS_VALUE_GET_OBJECT (&val); + + class = object; + swfdec_as_object_get_variable (class, SWFDEC_AS_STR___proto__, &val); + while (SWFDEC_AS_VALUE_IS_OBJECT (&val)) + { + class = SWFDEC_AS_VALUE_GET_OBJECT (&val); + if (class == prototype) { + SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), TRUE); + break; + } + swfdec_as_object_get_variable (class, SWFDEC_AS_STR___proto__, &val); + } +} + +static void swfdec_action_extends (SwfdecAsContext *cx, guint action, const guint8 *data, guint len) { SwfdecAsValue *superclass, *subclass, proto; @@ -2856,7 +2900,7 @@ const SwfdecActionSpec swfdec_as_actions[256] = { [SWFDEC_AS_ACTION_CALL_METHOD] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } }, [SWFDEC_AS_ACTION_NEW_METHOD] = { "NewMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_new_method, swfdec_action_new_method, swfdec_action_new_method } }, /* version 6 */ - [SWFDEC_AS_ACTION_INSTANCE_OF] = { "InstanceOf", NULL }, + [SWFDEC_AS_ACTION_INSTANCE_OF] = { "InstanceOf", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_instance_of, swfdec_action_instance_of } }, [SWFDEC_AS_ACTION_ENUMERATE2] = { "Enumerate2", NULL, 1, -1, { NULL, NULL, NULL, swfdec_action_enumerate2, swfdec_action_enumerate2 } }, [SWFDEC_AS_ACTION_BREAKPOINT] = { "Breakpoint", NULL, }, /* version 5 */ commit 76af34f924f385678683a5af30428d75dc005347 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 14:43:38 2007 +0300 Add a comment about __proto__ deleting diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index 6cd0661..a7d45d7 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -443,6 +443,7 @@ swfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable) if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT) return SWFDEC_AS_DELETE_NOT_DELETED; + // special case: in version > 6 deleting doesn't stop __proto__ from working if (variable == SWFDEC_AS_STR___proto__ && object->context->version <= 6) { object->prototype = NULL; object->prototype_flags = 0; commit 9db3b17ad978716efb19666e19cbdba562a3cb9b Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 13:21:52 2007 +0300 Make getTextFormat init TextFormat's properties, add a test diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c index 88207a2..979652e 100644 --- a/libswfdec/swfdec_text_field_movie.c +++ b/libswfdec/swfdec_text_field_movie.c @@ -1126,6 +1126,7 @@ swfdec_text_field_movie_get_text_format (SwfdecTextFieldMovie *text, continue; if (format == NULL) { + swfdec_text_format_init_properties (SWFDEC_AS_OBJECT (text)->context); format swfdec_text_format_copy (((SwfdecFormatIndex *)iter->data)->format); } else { diff --git a/test/trace/textformat-init-5.swf b/test/trace/textformat-init-5.swf index 3a223ce..0d0f898 100644 Binary files a/test/trace/textformat-init-5.swf and b/test/trace/textformat-init-5.swf differ diff --git a/test/trace/textformat-init-5.swf.trace b/test/trace/textformat-init-5.swf.trace index 0eee3fb..5250da6 100644 --- a/test/trace/textformat-init-5.swf.trace +++ b/test/trace/textformat-init-5.swf.trace @@ -9,3 +9,5 @@ undefined undefined undefined undefined +undefined +undefined diff --git a/test/trace/textformat-init-6.swf b/test/trace/textformat-init-6.swf index 5ebe00a..90fa33d 100644 Binary files a/test/trace/textformat-init-6.swf and b/test/trace/textformat-init-6.swf differ diff --git a/test/trace/textformat-init-6.swf.trace b/test/trace/textformat-init-6.swf.trace index feaee9f..fe7abe9 100644 --- a/test/trace/textformat-init-6.swf.trace +++ b/test/trace/textformat-init-6.swf.trace @@ -6,6 +6,8 @@ false true false true +true +true false false false diff --git a/test/trace/textformat-init-7.swf b/test/trace/textformat-init-7.swf index 552ff89..241b9c6 100644 Binary files a/test/trace/textformat-init-7.swf and b/test/trace/textformat-init-7.swf differ diff --git a/test/trace/textformat-init-7.swf.trace b/test/trace/textformat-init-7.swf.trace index 5368f4e..ad56dfa 100644 --- a/test/trace/textformat-init-7.swf.trace +++ b/test/trace/textformat-init-7.swf.trace @@ -6,6 +6,8 @@ false true false true +true +true false false false diff --git a/test/trace/textformat-init-8.swf b/test/trace/textformat-init-8.swf index 9d93be3..3171d89 100644 Binary files a/test/trace/textformat-init-8.swf and b/test/trace/textformat-init-8.swf differ diff --git a/test/trace/textformat-init-8.swf.trace b/test/trace/textformat-init-8.swf.trace index 5368f4e..ad56dfa 100644 --- a/test/trace/textformat-init-8.swf.trace +++ b/test/trace/textformat-init-8.swf.trace @@ -6,6 +6,8 @@ false true false true +true +true false false false diff --git a/test/trace/textformat-init.as b/test/trace/textformat-init.as index adfd606..3459b91 100644 --- a/test/trace/textformat-init.as +++ b/test/trace/textformat-init.as @@ -21,6 +21,7 @@ tmp.parse (".a { text-size: 4; }"); check_and_reset (); this.createTextField ("t", 0, 0, 0, 100, 100); +t.text = "hello"; check_and_reset (); t.getNewTextFormat (); check_and_reset (); @@ -28,6 +29,10 @@ t.setNewTextFormat (new Object ()); check_and_reset (); t.getTextFormat (); check_and_reset (); +t.getTextFormat (20, 21); +check_and_reset (); +t.getTextFormat (1, 2); +check_and_reset (); t.setTextFormat (new Object ()); check_and_reset (); tmp = t.textColor; commit 1c3323f7df70f50fb6ad4184c66c8977d6ea6612 Merge: c0affd1... b0b423c... Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 13:15:05 2007 +0300 Merge branch 'master' of ssh://medar at git.freedesktop.org/git/swfdec/swfdec Conflicts: libswfdec/swfdec_text_field_movie.c diff --cc libswfdec/swfdec_text_field_movie.c index 8cdd015,bd42350..88207a2 --- a/libswfdec/swfdec_text_field_movie.c +++ b/libswfdec/swfdec_text_field_movie.c @@@ -1592,8 -1601,7 +1592,8 @@@ swfdec_text_field_movie_replace_text (S } prev = iter; } + - if (end_index == g_utf8_strlen (text->input->str, -1)) { + if (end_index == (guint) g_utf8_strlen (text->input->str, -1)) { if (SWFDEC_AS_OBJECT (text)->context->version < 8) { SWFDEC_FIXME ("replaceText to the end of the TextField might use wrong text format on version 7"); } commit c0affd1ac98b7ac9e2eebd02ad47018ecdce0415 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 12:04:55 2007 +0300 Add a test for TextField's replaceText method diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index aa7b8e8..a39326f 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -1891,6 +1891,15 @@ EXTRA_DIST = \ text-field-length-7.swf.trace \ text-field-length-8.swf \ text-field-length-8.swf.trace \ + text-field-replace-text.as \ + text-field-replace-text-5.swf \ + text-field-replace-text-5.swf.trace \ + text-field-replace-text-6.swf \ + text-field-replace-text-6.swf.trace \ + text-field-replace-text-7.swf \ + text-field-replace-text-7.swf.trace \ + text-field-replace-text-8.swf \ + text-field-replace-text-8.swf.trace \ text-field-set-text-format.as \ text-field-set-text-format-5.swf \ text-field-set-text-format-5.swf.trace \ diff --git a/test/trace/text-field-replace-text-5.swf b/test/trace/text-field-replace-text-5.swf new file mode 100644 index 0000000..7d427b3 Binary files /dev/null and b/test/trace/text-field-replace-text-5.swf differ diff --git a/test/trace/text-field-replace-text-5.swf.trace b/test/trace/text-field-replace-text-5.swf.trace new file mode 100644 index 0000000..e3c0074 --- /dev/null +++ b/test/trace/text-field-replace-text-5.swf.trace @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/test/trace/text-field-replace-text-6.swf b/test/trace/text-field-replace-text-6.swf new file mode 100644 index 0000000..db176b1 Binary files /dev/null and b/test/trace/text-field-replace-text-6.swf differ diff --git a/test/trace/text-field-replace-text-6.swf.trace b/test/trace/text-field-replace-text-6.swf.trace new file mode 100644 index 0000000..6ef5cf6 --- /dev/null +++ b/test/trace/text-field-replace-text-6.swf.trace @@ -0,0 +1,9 @@ +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! diff --git a/test/trace/text-field-replace-text-7.swf b/test/trace/text-field-replace-text-7.swf new file mode 100644 index 0000000..8569a94 Binary files /dev/null and b/test/trace/text-field-replace-text-7.swf differ diff --git a/test/trace/text-field-replace-text-7.swf.trace b/test/trace/text-field-replace-text-7.swf.trace new file mode 100644 index 0000000..f9b8139 --- /dev/null +++ b/test/trace/text-field-replace-text-7.swf.trace @@ -0,0 +1,9 @@ +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l12Hiw13o14r15l16d17! +6H7e8l12Hiw13o15Hil16d17! +6H7e8l12Hiw13o15Hil16d17!6Hi +6H7e8l12Hiw13o15Hil6Hi diff --git a/test/trace/text-field-replace-text-8.swf b/test/trace/text-field-replace-text-8.swf new file mode 100644 index 0000000..65de215 Binary files /dev/null and b/test/trace/text-field-replace-text-8.swf differ diff --git a/test/trace/text-field-replace-text-8.swf.trace b/test/trace/text-field-replace-text-8.swf.trace new file mode 100644 index 0000000..f9b8139 --- /dev/null +++ b/test/trace/text-field-replace-text-8.swf.trace @@ -0,0 +1,9 @@ +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l9l10o11 12w13o14r15l16d17! +6H7e8l12Hiw13o14r15l16d17! +6H7e8l12Hiw13o15Hil16d17! +6H7e8l12Hiw13o15Hil16d17!6Hi +6H7e8l12Hiw13o15Hil6Hi diff --git a/test/trace/text-field-replace-text.as b/test/trace/text-field-replace-text.as new file mode 100644 index 0000000..f4c53e0 --- /dev/null +++ b/test/trace/text-field-replace-text.as @@ -0,0 +1,53 @@ +// makeswf -v 7 -r 1 -o text-field-replace-text-7.swf text-field-replace-text.as + +function check() { + str = ""; + size = -1; + for (var i = 0; i < t.length; i++) { + var fmt = t.getTextFormat (i); + if (fmt.size != size) { + size = fmt.size; + str = str + size; + } + str = str + t.text.charAt (i); + } + trace (str); +} + +this.createTextField ("t", 1, 0, 0, 100, 100); + +t.html = true; +t.text = "Hello world!"; + +var fmt = new TextFormat (); +for (var i = 0; i < t.length; i++) { + fmt.size = 6 + i; + t.setTextFormat (i, i + 1, fmt); +} +fmt.size = 5; +fmt.color = 0xFF0000; +t.setNewTextFormat (fmt); + +check (); + +// won't work: +t.replaceText (1, "Hi"); +check (); +t.replaceText (1, 0, "Hi"); +check (); +t.replaceText (-1, 5, "Hi"); +check (); +t.replaceText (50, 45, "Hi"); +check (); + +// will work: +t.replaceText (3, 6, "Hi"); +check (); +t.replaceText (7, 8, "Hi"); +check (); +t.replaceText (50, 55, "Hi"); +check (); +t.replaceText (10, 20, "Hi"); +check (); + +loadMovie ("FSCommand:quit", ""); commit 602a2fd29e587c2ca9b62c5483fafdf7a92f6a28 Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Thu Oct 25 12:03:54 2007 +0300 Fix errors in TextField's replaceText method diff --git a/libswfdec/swfdec_text_field_movie.c b/libswfdec/swfdec_text_field_movie.c index 516e270..8cdd015 100644 --- a/libswfdec/swfdec_text_field_movie.c +++ b/libswfdec/swfdec_text_field_movie.c @@ -1566,15 +1566,6 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text, if (text->style_sheet_input) return; - text->input = g_string_erase (text->input, - g_utf8_offset_to_pointer (text->input->str, start_index) - - text->input->str, - g_utf8_offset_to_pointer (text->input->str, end_index) - - g_utf8_offset_to_pointer (text->input->str, start_index)); - text->input = g_string_insert (text->input, - g_utf8_offset_to_pointer (text->input->str, start_index) - - text->input->str, str); - first = TRUE; prev = NULL; for (iter = text->formats; iter != NULL; iter = iter->next) @@ -1601,6 +1592,7 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text, } prev = iter; } + if (end_index == g_utf8_strlen (text->input->str, -1)) { if (SWFDEC_AS_OBJECT (text)->context->version < 8) { SWFDEC_FIXME ("replaceText to the end of the TextField might use wrong text format on version 7"); @@ -1612,6 +1604,15 @@ swfdec_text_field_movie_replace_text (SwfdecTextFieldMovie *text, text->formats = g_slist_append (text->formats, findex); } + text->input = g_string_erase (text->input, + g_utf8_offset_to_pointer (text->input->str, start_index) - + text->input->str, + g_utf8_offset_to_pointer (text->input->str, end_index) - + g_utf8_offset_to_pointer (text->input->str, start_index)); + text->input = g_string_insert (text->input, + g_utf8_offset_to_pointer (text->input->str, start_index) - + text->input->str, str); + swfdec_movie_invalidate (SWFDEC_MOVIE (text)); swfdec_text_field_movie_auto_size (text); swfdec_text_field_movie_update_scroll (text, TRUE); diff --git a/libswfdec/swfdec_text_field_movie_as.c b/libswfdec/swfdec_text_field_movie_as.c index bc810ea..9f7cf46 100644 --- a/libswfdec/swfdec_text_field_movie_as.c +++ b/libswfdec/swfdec_text_field_movie_as.c @@ -1089,14 +1089,14 @@ swfdec_text_field_movie_replaceText (SwfdecAsContext *cx, SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "iis", &start_index, &end_index, &str); - start_index = MIN (start_index, g_utf8_strlen (text->input->str, -1)); if (start_index < 0) return; - - end_index = MIN (end_index, g_utf8_strlen (text->input->str, -1)); if (end_index < start_index) return; + start_index = MIN (start_index, g_utf8_strlen (text->input->str, -1)); + end_index = MIN (end_index, g_utf8_strlen (text->input->str, -1)); + swfdec_text_field_movie_replace_text (text, start_index, end_index, str); }
Possibly Parallel Threads
- 18 commits - libswfdec/swfdec_player_internal.h libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_format.c libswfdec/swfdec_text_format.h libswfdec/swfdec_xml.c libswfdec/swfdec_xml_node.c libswfdec/swfdec_xml_node.h test/trace
- 20 commits - libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_html_parser.c libswfdec/swfdec_initialize.as libswfdec/swfdec_initialize.h libswfdec/swfdec_text_field.c libswfdec/swfdec_text_field.h
- 5 commits - libswfdec/swfdec_html_parser.c libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_field_movie.c test/trace
- 4 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_interpret.h libswfdec/swfdec_movie.c libswfdec/swfdec_system_as.c libswfdec/swfdec_text_field_movie.c test/trace
- 11 commits - libswfdec/swfdec_as_strings.c libswfdec/swfdec_text_field.c libswfdec/swfdec_text_field.h libswfdec/swfdec_text_field_movie_as.c libswfdec/swfdec_text_field_movie.c libswfdec/swfdec_text_field_movie.h test/trace