Pekka Lampila
2007-Aug-17 11:26 UTC
[Swfdec] 2 commits - libswfdec/swfdec_as_array.c test/trace
libswfdec/swfdec_as_array.c | 407 +++++++++++++++++++++++++----------------- test/trace/array2-5.swf |binary test/trace/array2-5.swf.trace | 38 +++ test/trace/array2-6.swf |binary test/trace/array2-6.swf.trace | 38 +++ test/trace/array2-7.swf |binary test/trace/array2-7.swf.trace | 38 +++ test/trace/array2.as | 77 +++++++ 8 files changed, 437 insertions(+), 161 deletions(-) New commits: diff-tree c44ef5cc232c3bad04a9c5e86d0f501b93e2390f (from a41661fd62a2ed7ae083f3a9a583377991e20930) Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Fri Aug 17 12:21:16 2007 +0300 Add test on whether the arrays length is increased if it's negative and a value is inserted in bigger, but still negative index. diff --git a/test/trace/array2-5.swf b/test/trace/array2-5.swf index 4057223..803ccac 100644 Binary files a/test/trace/array2-5.swf and b/test/trace/array2-5.swf differ diff --git a/test/trace/array2-5.swf.trace b/test/trace/array2-5.swf.trace index d3221d7..d3081e8 100644 --- a/test/trace/array2-5.swf.trace +++ b/test/trace/array2-5.swf.trace @@ -42,6 +42,8 @@ undefined [, , , , , , , , , ] [] [] +[] +[] [[], [], [], , ] [] [[], [], [], , ] diff --git a/test/trace/array2-6.swf b/test/trace/array2-6.swf index 42059f3..1d5c236 100644 Binary files a/test/trace/array2-6.swf and b/test/trace/array2-6.swf differ diff --git a/test/trace/array2-6.swf.trace b/test/trace/array2-6.swf.trace index 51dc019..bd63dd6 100644 --- a/test/trace/array2-6.swf.trace +++ b/test/trace/array2-6.swf.trace @@ -42,6 +42,8 @@ undefined [, , , , , , , , , ] [] -4 +[] +-1 [1, b, c, , ] 3.4 [1, b, c, , ] diff --git a/test/trace/array2-7.swf b/test/trace/array2-7.swf index 1ceb5d9..e93a801 100644 Binary files a/test/trace/array2-7.swf and b/test/trace/array2-7.swf differ diff --git a/test/trace/array2-7.swf.trace b/test/trace/array2-7.swf.trace index 04a5849..e51c513 100644 --- a/test/trace/array2-7.swf.trace +++ b/test/trace/array2-7.swf.trace @@ -42,6 +42,8 @@ undefined [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined] [] -4 +[] +-1 [1, b, c, undefined, ] 3.4 [1, b, c, undefined, ] diff --git a/test/trace/array2.as b/test/trace/array2.as index bea9179..237a156 100644 --- a/test/trace/array2.as +++ b/test/trace/array2.as @@ -100,6 +100,11 @@ a = new Array (1, "b", "c", 4); // nega a.length = -4; mytrace (a); mytrace (a.length); +a = new Array (); // setting negative variable while negative length +a.length = -4; +a[-2] = "x"; +mytrace (a); +mytrace (a.length); a = new Array (1, "b", "c", 4); // floating point values a.length = 3.4; mytrace (a); @@ -116,7 +121,7 @@ a = new Array (1, "b", "c", 4); // non- a.length = new Object (); mytrace (a); mytrace (a.length); -a = new Array (1, "b", "c", 4); // disabled until crash bug fixed +a = new Array (1, "b", "c", 4); a.length = "har"; mytrace (a); mytrace (a.length); diff-tree a41661fd62a2ed7ae083f3a9a583377991e20930 (from bf81efebf34c71944530945a70c24532de6ea111) Author: Pekka Lampila <pekka.lampila at iki.fi> Date: Fri Aug 17 12:13:06 2007 +0300 Make Array's method work with plain Objects. Fix push and pop methods to handle negative length values. Add test cases for both things. diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c index f6314a7..9d245c3 100644 --- a/libswfdec/swfdec_as_array.c +++ b/libswfdec/swfdec_as_array.c @@ -33,6 +33,7 @@ #include "swfdec_as_native_function.h" #include "swfdec_as_strings.h" #include "swfdec_debug.h" +#include "swfdec_player_internal.h" G_DEFINE_TYPE (SwfdecAsArray, swfdec_as_array, SWFDEC_TYPE_AS_OBJECT) @@ -73,7 +74,7 @@ swfdec_as_array_to_index (const char *st } static gint32 -swfdec_as_array_get_length (SwfdecAsObject *object) +swfdec_as_array_get_length_as_integer (SwfdecAsObject *object) { SwfdecAsValue val; gint32 length; @@ -83,6 +84,16 @@ swfdec_as_array_get_length (SwfdecAsObje swfdec_as_object_get_variable (object, SWFDEC_AS_STR_length, &val); length = swfdec_as_value_to_integer (object->context, &val); + return length; +} + +static gint32 +swfdec_as_array_get_length (SwfdecAsObject *object) +{ + gint32 length; + + length = swfdec_as_array_get_length_as_integer (object); + if (length < 0) return 0; @@ -105,7 +116,8 @@ typedef struct { gint32 num; } ForeachRemoveRangeData; -static gboolean swfdec_as_array_foreach_remove_range (SwfdecAsObject *object, +static gboolean +swfdec_as_array_foreach_remove_range (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachRemoveRangeData *fdata = data; @@ -122,7 +134,8 @@ static gboolean swfdec_as_array_foreach_ } static void -swfdec_as_array_remove_range (SwfdecAsArray *array, gint32 start_index, gint32 num) +swfdec_as_array_remove_range (SwfdecAsArray *array, gint32 start_index, + gint32 num) { SwfdecAsObject *object = SWFDEC_AS_OBJECT (array); @@ -140,7 +153,8 @@ swfdec_as_array_remove_range (SwfdecAsAr swfdec_as_object_delete_variable (object, var); } else { ForeachRemoveRangeData fdata = { start_index, num }; - swfdec_as_object_foreach_remove (object, swfdec_as_array_foreach_remove_range, &fdata); + swfdec_as_object_foreach_remove (object, + swfdec_as_array_foreach_remove_range, &fdata); } } @@ -151,8 +165,8 @@ typedef struct { } ForeachMoveRangeData; static const char * -swfdec_as_array_foreach_move_range (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint flags, gpointer data) +swfdec_as_array_foreach_move_range (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachMoveRangeData *fdata = data; gint32 idx; @@ -172,12 +186,12 @@ swfdec_as_array_foreach_move_range (Swfd } static void -swfdec_as_array_move_range (SwfdecAsArray *array, gint32 from_index, gint32 num, gint32 to_index) +swfdec_as_array_move_range (SwfdecAsObject *object, gint32 from_index, + gint32 num, gint32 to_index) { - SwfdecAsObject *object = SWFDEC_AS_OBJECT (array); ForeachMoveRangeData fdata = { from_index, num, to_index }; - g_return_if_fail (SWFDEC_IS_AS_ARRAY (array)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (from_index >= 0); g_return_if_fail (num >= 0); g_return_if_fail (from_index + num <= swfdec_as_array_get_length (object)); @@ -186,7 +200,8 @@ swfdec_as_array_move_range (SwfdecAsArra if (num == 0 || from_index == to_index) return; - swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_move_range, &fdata); + swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_move_range, + &fdata); // only changes length if it becomes bigger, not if it becomes smaller if (to_index + num > swfdec_as_array_get_length (object)) @@ -194,15 +209,14 @@ swfdec_as_array_move_range (SwfdecAsArra } static void -swfdec_as_array_set_range (SwfdecAsArray *array, gint32 start_index, gint32 num, - const SwfdecAsValue *value) +swfdec_as_array_set_range (SwfdecAsObject *object, gint32 start_index, + gint32 num, const SwfdecAsValue *value) { - SwfdecAsObject *object = SWFDEC_AS_OBJECT (array); gint32 i; const char *var; - g_return_if_fail (SWFDEC_IS_AS_ARRAY (array)); - g_return_if_fail (start_index >= 0); + // allow negative indexes + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (num >= 0); g_return_if_fail (value != NULL); @@ -212,6 +226,15 @@ swfdec_as_array_set_range (SwfdecAsArray } } +static void +swfdec_as_array_append_internal (SwfdecAsObject *object, guint n, + const SwfdecAsValue *value) +{ + // allow negative length + swfdec_as_array_set_range (object, + swfdec_as_array_get_length_as_integer (object), n, value); +} + /** * swfdec_as_array_push: * @array: a #SwfdecAsArray @@ -230,10 +253,12 @@ swfdec_as_array_set_range (SwfdecAsArray * Appends the given @values to the array. **/ void -swfdec_as_array_append (SwfdecAsArray *array, guint n, const SwfdecAsValue *value) +swfdec_as_array_append (SwfdecAsArray *array, guint n, + const SwfdecAsValue *value) { - swfdec_as_array_set_range (array, swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array)), n, - value); + // don't allow negative length + swfdec_as_array_set_range (SWFDEC_AS_OBJECT (array), + swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array)), n, value); } typedef struct { @@ -244,8 +269,8 @@ typedef struct { } ForeachAppendArrayRangeData; static gboolean -swfdec_as_array_foreach_append_array_range (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint flags, gpointer data) +swfdec_as_array_foreach_append_array_range (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachAppendArrayRangeData *fdata = data; gint32 idx; @@ -262,16 +287,16 @@ swfdec_as_array_foreach_append_array_ran } static void -swfdec_as_array_append_array_range (SwfdecAsArray *array_to, SwfdecAsArray *array_from, - gint32 start_index, gint32 num) +swfdec_as_array_append_array_range (SwfdecAsArray *array_to, + SwfdecAsObject *object_from, gint32 start_index, gint32 num) { - SwfdecAsObject *object_from = SWFDEC_AS_OBJECT (array_from); ForeachAppendArrayRangeData fdata; g_return_if_fail (SWFDEC_IS_AS_ARRAY (array_to)); - g_return_if_fail (SWFDEC_IS_AS_ARRAY (array_from)); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object_from)); g_return_if_fail (start_index >= 0); - g_return_if_fail (start_index + num <= swfdec_as_array_get_length (object_from)); + g_return_if_fail ( + start_index + num <= swfdec_as_array_get_length (object_from)); if (num == 0) return; @@ -282,14 +307,15 @@ swfdec_as_array_append_array_range (Swfd fdata.num = num; swfdec_as_array_set_length (fdata.object_to, fdata.offset + fdata.num); - swfdec_as_object_foreach (object_from, swfdec_as_array_foreach_append_array_range, &fdata); + swfdec_as_object_foreach (object_from, + swfdec_as_array_foreach_append_array_range, &fdata); } static void -swfdec_as_array_append_array (SwfdecAsArray *array_to, SwfdecAsArray *array_from) +swfdec_as_array_append_array (SwfdecAsArray *array_to, SwfdecAsObject *object_from) { - swfdec_as_array_append_array_range (array_to, array_from, 0, - swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array_from))); + swfdec_as_array_append_array_range (array_to, object_from, 0, + swfdec_as_array_get_length (object_from)); } /* @@ -297,14 +323,6 @@ swfdec_as_array_append_array (SwfdecAsAr */ static void -swfdec_as_array_dispose (GObject *object) -{ - //SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); - - G_OBJECT_CLASS (swfdec_as_array_parent_class)->dispose (object); -} - -static void swfdec_as_array_add (SwfdecAsObject *object) { swfdec_as_array_set_length (object, 0); @@ -313,39 +331,42 @@ swfdec_as_array_add (SwfdecAsObject *obj } static void -swfdec_as_array_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val) +swfdec_as_array_set (SwfdecAsObject *object, const char *variable, + const SwfdecAsValue *val) { - gint32 l = swfdec_as_array_to_index (variable); + char *end; + gboolean indexvar = TRUE; + gint32 l = strtoul (variable, &end, 10); + + if (*end != 0 || l > G_MAXINT32) + indexvar = FALSE; // if we changed to smaller length, destroy all values that are outside it if (!strcmp (variable, SWFDEC_AS_STR_length)) { gint32 length_old = swfdec_as_array_get_length (object); - gint32 length_new = MAX (0, swfdec_as_value_to_integer (object->context, val)); - if (length_old > length_new) - swfdec_as_array_remove_range (SWFDEC_AS_ARRAY (object), length_new, length_old - length_new); + gint32 length_new = MAX (0, + swfdec_as_value_to_integer (object->context, val)); + if (length_old > length_new) { + swfdec_as_array_remove_range (SWFDEC_AS_ARRAY (object), length_new, + length_old - length_new); + } } - SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable, val); + SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable, + val); // if we added new value outside the current length, set a bigger length - if (l > -1) { - int cur; - l++; - cur = swfdec_as_array_get_length (object); - if (l > cur) { + if (indexvar) { + if (++l > swfdec_as_array_get_length_as_integer (object)) swfdec_as_array_set_length (object, l); - } } } static void swfdec_as_array_class_init (SwfdecAsArrayClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); - object_class->dispose = swfdec_as_array_dispose; - asobject_class->add = swfdec_as_array_add; asobject_class->set = swfdec_as_array_set; } @@ -374,7 +395,7 @@ swfdec_as_array_new (SwfdecAsContext *co g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); g_return_val_if_fail (context->Array != NULL, NULL); - + if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray))) return FALSE; ret = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); @@ -385,9 +406,10 @@ swfdec_as_array_new (SwfdecAsContext *co /*** AS CODE ***/ -static void -swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, - SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 7, swfdec_as_array_join) +void +swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, + SwfdecAsValue *argv, SwfdecAsValue *ret) { int i, length; const char *var, *str, *sep; @@ -422,66 +444,84 @@ swfdec_as_array_join (SwfdecAsContext *c SWFDEC_AS_VALUE_SET_STRING (ret, str); } -static void -swfdec_as_array_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 9, swfdec_as_array_toString) +void +swfdec_as_array_toString (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { swfdec_as_array_join (cx, object, 0, NULL, ret); } -static void -swfdec_as_array_do_push (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 1, swfdec_as_array_do_push) +void +swfdec_as_array_do_push (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { - SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); - - // we allow calling with 0 args, so that we'll return the length even in that case - if (argc > 0) - swfdec_as_array_append (array, argc, argv); + // if 0 args, just return the length + // manually set the length here to make the function work on non-Arrays + if (argc > 0) { + gint32 length = swfdec_as_array_get_length_as_integer (object); + swfdec_as_array_append_internal (object, argc, argv); + swfdec_as_array_set_length (object, length + argc); + } - SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object)); + SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length_as_integer (object)); } -static void +SWFDEC_AS_NATIVE (252, 2, swfdec_as_array_do_pop) +void swfdec_as_array_do_pop (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { gint32 length; const char *var; - length = swfdec_as_array_get_length (object); - if (length <= 0) + // we allow negative indexes here, but not 0 + length = swfdec_as_array_get_length_as_integer (object); + if (length == 0) return; var = swfdec_as_double_to_string (object->context, length - 1); swfdec_as_object_get_variable (object, var, ret); - swfdec_as_array_set_length (object, length - 1); + + // if Array, the length is reduced by one (which destroys the variable also) + // else the length is not reduced at all, but the variable is still deleted + if (SWFDEC_IS_AS_ARRAY (object)) { + swfdec_as_array_set_length (object, length - 1); + } else { + swfdec_as_object_delete_variable (object, var); + } } -static void -swfdec_as_array_do_unshift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 5, swfdec_as_array_do_unshift) +void +swfdec_as_array_do_unshift (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { - SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); gint32 length; if (argc) { + // don't allow negative length length = swfdec_as_array_get_length (object); - swfdec_as_array_move_range (array, 0, length, argc); - swfdec_as_array_set_range (array, 0, argc, argv); + swfdec_as_array_move_range (object, 0, length, argc); + swfdec_as_array_set_range (object, 0, argc, argv); + // if not Array, leave the length unchanged + if (!SWFDEC_IS_AS_ARRAY (object)) + swfdec_as_array_set_length (object, length); } SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object)); } -static void -swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 4, swfdec_as_array_do_shift) +void +swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { - SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); gint32 length; const char *var; + // don't allow negative length length = swfdec_as_array_get_length (object); if (length <= 0) return; @@ -489,8 +529,23 @@ swfdec_as_array_do_shift (SwfdecAsContex var = swfdec_as_double_to_string (object->context, 0); swfdec_as_object_get_variable (object, var, ret); - swfdec_as_array_move_range (array, 1, length - 1, 0); - swfdec_as_array_set_length (object, length - 1); + swfdec_as_array_move_range (object, 1, length - 1, 0); + + // if not Array, leave the length unchanged, and don't remove the element + if (SWFDEC_IS_AS_ARRAY (object)) { + swfdec_as_array_set_length (object, length - 1); + } else { + // we have to put the last element back, because we used move, not copy + SwfdecAsValue val; + if (length > 1) { + var = swfdec_as_double_to_string (object->context, length - 2); + swfdec_as_object_get_variable (object, var, &val); + } else { + val = *ret; + } + var = swfdec_as_double_to_string (object->context, length - 1); + swfdec_as_object_set_variable (object, var, &val); + } } static const char * @@ -507,19 +562,22 @@ swfdec_as_array_foreach_reverse (SwfdecA return swfdec_as_double_to_string (object->context, *length - 1 - idx); } -static void -swfdec_as_array_reverse (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +SWFDEC_AS_NATIVE (252, 11, swfdec_as_array_reverse) +void +swfdec_as_array_reverse (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { gint32 length; length = swfdec_as_array_get_length (object); - swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_reverse, &length); + swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_reverse, + &length); SWFDEC_AS_VALUE_SET_OBJECT (ret, object); } -static void +SWFDEC_AS_NATIVE (252, 3, swfdec_as_array_concat) +void swfdec_as_array_concat (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { @@ -531,18 +589,19 @@ swfdec_as_array_concat (SwfdecAsContext object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); - swfdec_as_array_append_array (array_new, SWFDEC_AS_ARRAY (object)); + swfdec_as_array_append_array (array_new, object); for (j = 0; j < argc; j++) { if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[j]) && SWFDEC_IS_AS_ARRAY (SWFDEC_AS_VALUE_GET_OBJECT (&argv[j]))) { swfdec_as_array_append_array (array_new, - SWFDEC_AS_ARRAY (SWFDEC_AS_VALUE_GET_OBJECT (&argv[j]))); + SWFDEC_AS_VALUE_GET_OBJECT (&argv[j])); } else { - var = swfdec_as_double_to_string (object->context, swfdec_as_array_get_length (object_new)); + var = swfdec_as_double_to_string (object->context, + swfdec_as_array_get_length (object_new)); swfdec_as_object_set_variable (object_new, var, &argv[j]); } } @@ -550,7 +609,8 @@ swfdec_as_array_concat (SwfdecAsContext SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new); } -static void +SWFDEC_AS_NATIVE (252, 6, swfdec_as_array_slice) +void swfdec_as_array_slice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { @@ -582,16 +642,16 @@ swfdec_as_array_slice (SwfdecAsContext * object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); - swfdec_as_array_append_array_range (array_new, SWFDEC_AS_ARRAY (object), start_index, num); + swfdec_as_array_append_array_range (array_new, object, start_index, num); SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new); } -static void +SWFDEC_AS_NATIVE (252, 8, swfdec_as_array_splice) +void swfdec_as_array_splice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { - SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); gint32 length, start_index, num_remove, num_add; SwfdecAsObject *object_new; SwfdecAsArray *array_new; @@ -608,7 +668,8 @@ swfdec_as_array_splice (SwfdecAsContext } if (argc > 1) { - num_remove = CLAMP (swfdec_as_value_to_integer (cx, &argv[1]), 0, length - start_index); + num_remove = CLAMP (swfdec_as_value_to_integer (cx, &argv[1]), 0, + length - start_index); } else { num_remove = length - start_index; } @@ -618,13 +679,14 @@ swfdec_as_array_splice (SwfdecAsContext object_new = swfdec_as_array_new (cx); array_new = SWFDEC_AS_ARRAY (object_new); - swfdec_as_array_append_array_range (array_new, array, start_index, num_remove); - swfdec_as_array_move_range (array, start_index + num_remove, length - (start_index + num_remove), - start_index + num_add); + swfdec_as_array_append_array_range (array_new, object, start_index, + num_remove); + swfdec_as_array_move_range (object, start_index + num_remove, + length - (start_index + num_remove), start_index + num_add); if (num_remove > num_add) swfdec_as_array_set_length (object, length - (num_remove - num_add)); if (argc > 2) - swfdec_as_array_set_range (array, start_index, argc - 2, argv + 2); + swfdec_as_array_set_range (object, start_index, argc - 2, argv + 2); SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new); } @@ -651,8 +713,8 @@ typedef struct { } ForeachSortData; static gint -swfdec_as_array_sort_compare (SwfdecAsContext *cx, SwfdecAsValue *a, SwfdecAsValue *b, - gint32 options, SwfdecAsFunction *fun) +swfdec_as_array_sort_compare (SwfdecAsContext *cx, SwfdecAsValue *a, + SwfdecAsValue *b, gint32 options, SwfdecAsFunction *fun) { gint retval; @@ -680,11 +742,13 @@ swfdec_as_array_sort_compare (SwfdecAsCo } else if (options & ARRAY_SORT_OPTION_CASEINSENSITIVE) { - retval = g_strcasecmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b)); + retval = g_strcasecmp (swfdec_as_value_to_string (cx, a), + swfdec_as_value_to_string (cx, b)); } else { - retval = strcmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b)); + retval = strcmp (swfdec_as_value_to_string (cx, a), + swfdec_as_value_to_string (cx, b)); } if (options & ARRAY_SORT_OPTION_DESCENDING) { @@ -696,8 +760,8 @@ swfdec_as_array_sort_compare (SwfdecAsCo // renames values in the array based on fdata->order values static const char * -swfdec_as_array_foreach_sort_rename (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint flags, gpointer data) +swfdec_as_array_foreach_sort_rename (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachSortData *fdata = data; gint32 idx, i; @@ -728,7 +792,8 @@ swfdec_as_array_foreach_sort_rename (Swf } // fills fdata->object_new array using indexes based on the fdata->order -static gboolean swfdec_as_array_foreach_sort_indexedarray (SwfdecAsObject *object, +static gboolean +swfdec_as_array_foreach_sort_indexedarray (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachSortData *fdata = data; @@ -767,7 +832,8 @@ static gboolean swfdec_as_array_foreach_ // sets undefined values in the fdata->object_new array to indexes of undefined // values in the object array static void -swfdec_as_array_sort_set_undefined_indexedarray (SwfdecAsObject *object, ForeachSortData *fdata) +swfdec_as_array_sort_set_undefined_indexedarray (SwfdecAsObject *object, + ForeachSortData *fdata) { SwfdecAsValue val; const char *var; @@ -795,8 +861,8 @@ swfdec_as_array_sort_set_undefined_index // (in the sense that sorting compare function returns 0) // used by uniquesort when there is exactly one undefined value in the array static gboolean -swfdec_as_array_foreach_sort_compare_undefined (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint flags, gpointer data) +swfdec_as_array_foreach_sort_compare_undefined (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachSortData *fdata = data; gint32 idx; @@ -811,15 +877,16 @@ swfdec_as_array_foreach_sort_compare_und fdata->defined_values++; // when testing for uniquesort the custom compare function is NOT used - if (swfdec_as_array_sort_compare (object->context, value, &fdata->undefined, fdata->options, NULL) == 0) + if (swfdec_as_array_sort_compare (object->context, value, &fdata->undefined, + fdata->options, NULL) == 0) return FALSE; return TRUE; } static gboolean -swfdec_as_array_foreach_sort_populate (SwfdecAsObject *object, const char *variable, - SwfdecAsValue *value, guint flags, gpointer data) +swfdec_as_array_foreach_sort_populate (SwfdecAsObject *object, + const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { ForeachSortData *fdata = data; gint32 idx, i; @@ -837,15 +904,18 @@ swfdec_as_array_foreach_sort_populate (S // find the position for this value for (i = 0; i < fdata->order_size; i++) { - if (fdata->order[i] == NULL || (cval = swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, fdata->compare_custom_func)) <= 0) + if (fdata->order[i] == NULL || + (cval = swfdec_as_array_sort_compare (object->context, value, + fdata->order[i], fdata->options, fdata->compare_custom_func)) <= 0) { SwfdecAsValue *tmp2, *tmp; - // if we are doing uniquesort, see if this value is the same as some earlier value + // if we are doing uniquesort, see if this value is the same as some + // earlier value if (fdata->options & ARRAY_SORT_OPTION_UNIQUESORT && fdata->order[i] != NULL && fdata->order[i] != &fdata->undefined) { - // when using custom function, uniquesort is still based on the equality given by - // the normal method, not the custom function + // when using custom function, uniquesort is still based on the + // equality given by the normal method, not the custom function if (fdata->compare_custom_func != NULL) { if (swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, NULL) == 0) return FALSE; @@ -872,7 +942,8 @@ swfdec_as_array_foreach_sort_populate (S return TRUE; } -static void +SWFDEC_AS_NATIVE (252, 10, swfdec_as_array_sort) +void swfdec_as_array_sort (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { @@ -880,7 +951,8 @@ swfdec_as_array_sort (SwfdecAsContext *c guint pos; fdata.length = swfdec_as_array_get_length (object); - fdata.order_size = MIN ((gint32)g_hash_table_size (object->properties) + 1, fdata.length + 1); + fdata.order_size + MIN ((gint32)g_hash_table_size (object->properties) + 1, fdata.length + 1); fdata.order = g_new0 (SwfdecAsValue *, fdata.order_size); SWFDEC_AS_VALUE_SET_UNDEFINED (&fdata.undefined); fdata.order[0] = &fdata.undefined; @@ -890,7 +962,8 @@ swfdec_as_array_sort (SwfdecAsContext *c if (argc > 0 && !SWFDEC_AS_VALUE_IS_NUMBER (&argv[0])) { SwfdecAsFunction *fun; if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]) || - !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]))) + !SWFDEC_IS_AS_FUNCTION ( + fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]))) return; fdata.compare_custom_func = fun; pos++; @@ -905,24 +978,31 @@ swfdec_as_array_sort (SwfdecAsContext *c } // generate fdata.order which points to the values - if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate, &fdata)) { + if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate, + &fdata)) + { // uniquesort failed SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); return; } - if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values + 1 < fdata.length) { + if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && + fdata.defined_values + 1 < fdata.length) + { // uniquesort fails, because we have more than one undefined value SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); return; } - if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values < fdata.length) { - // uniquesort used, and we have atleast one undefined value - // test if anything equeals to that - if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_compare_undefined, &fdata)) + if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && + fdata.defined_values < fdata.length) + { + // uniquesort used, and we have exactly one undefined value test if + // anything equeals to that + if (!swfdec_as_object_foreach (object, + swfdec_as_array_foreach_sort_compare_undefined, &fdata)) { SWFDEC_AS_VALUE_SET_INT (ret, 0); g_free (fdata.order); @@ -933,20 +1013,23 @@ swfdec_as_array_sort (SwfdecAsContext *c if (fdata.options & ARRAY_SORT_OPTION_RETURNINDEXEDARRAY) { // make a new array and fill it with numbers based on the order fdata.object_new = swfdec_as_array_new (cx); - swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_indexedarray, &fdata); - // we only have the elements that have been set so far, so fill in the blanks + swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_indexedarray, + &fdata); + // we only have the elements that have been set so far, fill in the blanks swfdec_as_array_sort_set_undefined_indexedarray (object, &fdata); SWFDEC_AS_VALUE_SET_OBJECT (ret, fdata.object_new); } else { // rename properties based on the new order - swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_sort_rename, &fdata); + swfdec_as_object_foreach_rename (object, + swfdec_as_array_foreach_sort_rename, &fdata); SWFDEC_AS_VALUE_SET_OBJECT (ret, object); } g_free (fdata.order); } -static void +SWFDEC_AS_NATIVE (252, 12, swfdec_as_array_sortOn) +void swfdec_as_array_sortOn (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { @@ -956,8 +1039,8 @@ swfdec_as_array_sortOn (SwfdecAsContext // Constructor static void -swfdec_as_array_construct (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, - SwfdecAsValue *argv, SwfdecAsValue *ret) +swfdec_as_array_construct (SwfdecAsContext *cx, SwfdecAsObject *object, + guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret) { SwfdecAsArray *array; @@ -969,7 +1052,8 @@ swfdec_as_array_construct (SwfdecAsConte swfdec_as_object_add (object, cx, sizeof (SwfdecAsArray)); swfdec_as_object_get_variable (cx->global, SWFDEC_AS_STR_Array, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { - swfdec_as_object_set_constructor (object, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE); + swfdec_as_object_set_constructor (object, + SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE); } else { SWFDEC_INFO ("\"Array\" is not an object"); } @@ -994,10 +1078,10 @@ swfdec_as_array_init_context (SwfdecAsCo g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); - array = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, + array = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_Array, 0, swfdec_as_array_construct, 0)); - swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (array), - SWFDEC_TYPE_AS_ARRAY); + swfdec_as_native_function_set_construct_type ( + SWFDEC_AS_NATIVE_FUNCTION (array), SWFDEC_TYPE_AS_ARRAY); if (!array) return; context->Array = array; @@ -1005,6 +1089,7 @@ swfdec_as_array_init_context (SwfdecAsCo return; proto = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); swfdec_as_object_add (proto, context, sizeof (SwfdecAsArray)); + /* set the right properties on the Array object */ SWFDEC_AS_VALUE_SET_OBJECT (&val, proto); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_prototype, &val); @@ -1020,32 +1105,34 @@ swfdec_as_array_init_context (SwfdecAsCo swfdec_as_object_set_variable (array, SWFDEC_AS_STR_RETURNINDEXEDARRAY, &val); SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_NUMERIC); swfdec_as_object_set_variable (array, SWFDEC_AS_STR_NUMERIC, &val); + /* set the right properties on the Array.prototype object */ SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype); swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val); SWFDEC_AS_VALUE_SET_OBJECT (&val, array); swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0, swfdec_as_array_toString, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_join, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_join, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_do_push, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pop, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_do_pop, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_unshift, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_do_unshift, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_shift, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_do_shift, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_reverse, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_reverse, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_concat, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_concat, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_slice, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_slice, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_splice, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_splice, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sort, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_sort, 0); - swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn, SWFDEC_TYPE_AS_ARRAY, - swfdec_as_array_sortOn, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0, + swfdec_as_array_toString, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_join, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_join, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_push, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pop, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_pop, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_unshift, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_unshift, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_shift, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_shift, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_reverse, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_reverse, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_concat, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_concat, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_slice, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_slice, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_splice, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_splice, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sort, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sort, 0); + swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn, + SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sortOn, 0); } diff --git a/test/trace/array2-5.swf b/test/trace/array2-5.swf index 4c11d71..4057223 100644 Binary files a/test/trace/array2-5.swf and b/test/trace/array2-5.swf differ diff --git a/test/trace/array2-5.swf.trace b/test/trace/array2-5.swf.trace index 38bc090..d3221d7 100644 --- a/test/trace/array2-5.swf.trace +++ b/test/trace/array2-5.swf.trace @@ -40,6 +40,8 @@ [, , , , ] undefined [, , , , , , , , , ] +[] +[] [[], [], [], , ] [] [[], [], [], , ] @@ -91,9 +93,18 @@ undefined [] [[], [], [], [], [], [[], [], []]] [] +undefined +[[, , , , , , ]] +[] +undefined +[] +[] [[]] [] [, , , , , []] +[] +[] +[] [, , , , , ] [, , , , , , , , , , , , , ] [] @@ -103,6 +114,8 @@ undefined [, , , , , , , , , , , , , , ] undefined [] +undefined +[] [] [[], [], []] [] @@ -548,4 +561,27 @@ undefined [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] [[], [], [], [], []] [[[], [], []], [[], [], [], []], [], [[], []], [[]]] +[, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] +[type Function] +5 +5: a:b:c:x:z +z +5: a:b:c:x: +5 +5: y:a:b:c:x +5 +5: z:y:a:b:c +6: z:y:a:b:c:x +z +6: y:a:b:c:x:x +x,x,c,b,a,y +6: x:x:c:b:a:y +x:x:c:b:a:y:a:x,x,c,b,a,y +6: x:x:c:b:a:y +x,c +6: x:x:c:b:a:y +c,b,a +5: x:x:i:j:y +i,j,x,x,y +5: i:j:x:x:y [, , , , , , ] diff --git a/test/trace/array2-6.swf b/test/trace/array2-6.swf index ff62b44..42059f3 100644 Binary files a/test/trace/array2-6.swf and b/test/trace/array2-6.swf differ diff --git a/test/trace/array2-6.swf.trace b/test/trace/array2-6.swf.trace index 84a7bd8..51dc019 100644 --- a/test/trace/array2-6.swf.trace +++ b/test/trace/array2-6.swf.trace @@ -40,6 +40,8 @@ [, , , , ] undefined [, , , , , , , , , ] +[] +-4 [1, b, c, , ] 3.4 [1, b, c, , ] @@ -91,9 +93,18 @@ a:b:c 6 [1, 2, 3, 4, 5, [a, b, c]] 1 +undefined +[weirder] +0 +undefined +[] +1 [6] 6 [, , , , , 6] +-2 +x +-2 ## Pop # Normal usage 4 @@ -103,6 +114,8 @@ c # Special cases undefined [] +undefined +[] 4 [1, b, c] c @@ -548,4 +561,27 @@ sort customfunc 30 [[1, 2, 3], [1, 2, 3, sort customfunc 31 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]] [1, 0, 3, 4, 2] [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]] +## Fake Array (Object with Array's methods) +[type Function] +5 +5: a:b:c:x:z +z +5: a:b:c:x: +5 +5: y:a:b:c:x +5 +5: z:y:a:b:c +6: z:y:a:b:c:x +z +6: y:a:b:c:x:x +x,x,c,b,a,y +6: x:x:c:b:a:y +x:x:c:b:a:y:a:x,x,c,b,a,y +6: x:x:c:b:a:y +x,c +6: x:x:c:b:a:y +c,b,a +5: x:x:i:j:y +i,j,x,x,y +5: i:j:x:x:y ## Done diff --git a/test/trace/array2-7.swf b/test/trace/array2-7.swf index db297a0..1ceb5d9 100644 Binary files a/test/trace/array2-7.swf and b/test/trace/array2-7.swf differ diff --git a/test/trace/array2-7.swf.trace b/test/trace/array2-7.swf.trace index 51ea2a3..04a5849 100644 --- a/test/trace/array2-7.swf.trace +++ b/test/trace/array2-7.swf.trace @@ -40,6 +40,8 @@ [undefined, undefined, undefined, undefined, undefined] undefined [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined] +[] +-4 [1, b, c, undefined, ] 3.4 [1, b, c, undefined, ] @@ -91,9 +93,18 @@ undefined:undefined:undefined:undefined: 6 [1, 2, 3, 4, 5, [a, b, c]] 1 +undefined +[weirder] +0 +undefined +[] +1 [6] 6 [undefined, undefined, undefined, undefined, undefined, 6] +-2 +x +-2 ## Pop # Normal usage 4 @@ -103,6 +114,8 @@ c # Special cases undefined [] +undefined +[] 4 [1, b, c] c @@ -548,4 +561,27 @@ sort customfunc 30 [[1, 2, 3], [1, 2, 3, sort customfunc 31 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]] [1, 0, 3, 4, 2] [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]] +## Fake Array (Object with Array's methods) +[type Function] +5 +5: a:b:c:x:z +z +5: a:b:c:x:undefined +5 +5: y:a:b:c:x +5 +5: z:y:a:b:c +6: z:y:a:b:c:x +z +6: y:a:b:c:x:x +x,x,c,b,a,y +6: x:x:c:b:a:y +x:x:c:b:a:y:a:x,x,c,b,a,y +6: x:x:c:b:a:y +x,c +6: x:x:c:b:a:y +c,b,a +5: x:x:i:j:y +i,j,x,x,y +5: i:j:x:x:y ## Done diff --git a/test/trace/array2.as b/test/trace/array2.as index 7e8edb4..bea9179 100644 --- a/test/trace/array2.as +++ b/test/trace/array2.as @@ -96,6 +96,10 @@ mytrace (a); mytrace (a[9]); a.length = 10; mytrace (a); +a = new Array (1, "b", "c", 4); // negative value +a.length = -4; +mytrace (a); +mytrace (a.length); a = new Array (1, "b", "c", 4); // floating point values a.length = 3.4; mytrace (a); @@ -187,12 +191,27 @@ mytrace (a.push ()); // pushing nothin mytrace (a); mytrace (a.push (["a", "b", "c"])); // pushing another array mytrace (a); +a = new Array (); // pushing when weird length +a.length = "weird"; +mytrace (a.push ("weirder")); +mytrace (a["weird"]); +mytrace (a); +a = new Array (); // pushing nothing, weird length +a.length = "weird"; +mytrace (a.push ()); +mytrace (a["weird"]); +mytrace (a); a = new Array (); // pushing on empty array mytrace (a.push (6)); mytrace (a); a = new Array (5); // pushing on array with only undefined values mytrace (a.push (6)); mytrace (a); +a = new Array (); // pushing on array with negative length +a.length = -3; +mytrace (a.push ("x")); +mytrace (a[-3]); +mytrace (a.length); mytrace ("## Pop"); @@ -210,6 +229,10 @@ mytrace ("# Special cases"); a = new Array (); // empty mytrace (a.pop ()); mytrace (a); +a = new Array (); // empty, weird length +a.length = "weird"; +mytrace (a.pop ()); +mytrace (a); a = new Array (1, "b", "c", 4); // use parameters mytrace (a.pop (5)); mytrace (a); @@ -444,5 +467,52 @@ a = new Array ([1,2,3], [1,2,3,4], [], [ sortall (a, compare_array_length, 0, 0); +mytrace ("## Fake Array (Object with Array's methods)"); + +fake = new Object(); + +fake.join = Array.prototype.join; +fake.toString = Array.prototype.toString; +fake.push = Array.prototype.push; +fake.pop = Array.prototype.pop; +fake.shift = Array.prototype.shift; +fake.unshift = Array.prototype.unshift; +fake.reverse = Array.prototype.reverse; +fake.concat = Array.prototype.concat; +fake.slice = Array.prototype.slice; +fake.splice = Array.prototype.splice; +fake.sort = Array.prototype.sort; + +trace (fake.push); +trace (fake.push ("a", "b", "c", "x", "z")); +trace (fake.length + ": " + fake.join (":")); +trace (fake.pop ()); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.unshift ("y")); +trace (fake.length + ": " + fake.join (":")); +trace (fake.unshift ("z")); +trace (fake.length + ": " + fake.join (":")); +fake.length++; +trace (fake.length + ": " + fake.join (":")); +trace (fake.shift ()); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.reverse ()); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.concat ("a", fake).join (":")); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.slice (1, 3)); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.splice (2, 3, "i", "j")); +trace (fake.length + ": " + fake.join (":")); + +trace (fake.sort ()); +trace (fake.length + ": " + fake.join (":")); + + mytrace ("## Done"); loadMovie ("FSCommand:quit", "");
Seemingly Similar Threads
- Branch 'vivi' - 9 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c
- 13 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_xml.c libswfdec/swfdec_xml_node.c test/trace
- 3 commits - libswfdec-gtk/swfdec_gtk_loader.c libswfdec/swfdec_as_array.c libswfdec/swfdec_asbroadcaster.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_types.c libswfdec/swfdec_xml.c
- 4 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_as_types.c test/trace
- 4 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_video_movie_as.c test/trace