[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
Benjamin Otte
company at kemper.freedesktop.org
Wed Jun 6 07:37:23 PDT 2007
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 */
More information about the Swfdec
mailing list