Ejemplo n.º 1
0
static gboolean
swfdec_amf_parse_properties (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsObject *object)
{
  guint type;
  SwfdecAmfParseFunc func;

  while (swfdec_bits_left (bits)) {
    SwfdecAsValue val;
    const char *name;

    if (!swfdec_amf_parse_string (context, bits, &val))
      return FALSE;
    name = SWFDEC_AS_VALUE_GET_STRING (&val);
    type = swfdec_bits_get_u8 (bits);
    if (type == SWFDEC_AMF_END_OBJECT)
      break;
    if (type >= SWFDEC_AMF_N_TYPES ||
	(func = parse_funcs[type]) == NULL) {
      SWFDEC_ERROR ("no parse func for AMF type %u", type);
      goto error;
    }
    swfdec_as_object_set_variable (object, name, &val); /* GC... */
    if (!func (context, bits, &val)) {
      goto error;
    }
    swfdec_as_object_set_variable (object, name, &val);
  }
  /* no more bytes seems to end automatically */
  return TRUE;

error:
  return FALSE;
}
Ejemplo n.º 2
0
Archivo: gc.c Proyecto: fengye/swfdec
static guint
check_object_variables (void)
{
  SwfdecAsObject *o, *o2;
  guint errors = 0;
  SwfdecAsContext *context;
  const char *s;
  gpointer check = GUINT_TO_POINTER (-1); /* NOT NULL */
  gpointer check2 = GUINT_TO_POINTER (-1); /* NOT NULL */
  SwfdecAsValue v1, v2;
  
  context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
  swfdec_as_context_startup (context);
  g_assert (check != NULL);

  o = swfdec_as_object_new (context);
  o2 = swfdec_as_object_new (context);
  g_object_add_weak_pointer (G_OBJECT (o), &check);
  g_object_add_weak_pointer (G_OBJECT (o2), &check2);
  s = swfdec_as_context_get_string (context, "foo");
  /* step one: set a variable */
  SWFDEC_AS_VALUE_SET_OBJECT (&v1, o);
  swfdec_as_object_set_variable (context->global, s, &v1);
  SWFDEC_AS_VALUE_SET_OBJECT (&v2, o2);
  swfdec_as_object_set_variable (o, s, &v2);
  SWFDEC_AS_VALUE_SET_UNDEFINED (&v2);
  swfdec_as_object_get_variable (o, s, &v2);
  if (!SWFDEC_AS_VALUE_IS_OBJECT (&v2)) {
    ERROR ("variable changed type");
  } else if (o2 != SWFDEC_AS_VALUE_GET_OBJECT (&v2)) {
    ERROR ("variable changed value");
  }
  /* step 2: gc */
  swfdec_as_context_gc (context);
  if (check == NULL || check2 == NULL) {
    ERROR ("GC collected a used object, bailing");
    g_object_unref (context);
    return errors;
  }
  /* step 3: unset root reference and set cyclic variable */
  swfdec_as_object_delete_variable (context->global, s);
  swfdec_as_object_set_variable (o2, s, &v1);
  SWFDEC_AS_VALUE_SET_UNDEFINED (&v1);
  swfdec_as_object_get_variable (o2, s, &v1);
  if (!SWFDEC_AS_VALUE_IS_OBJECT (&v1)) {
    ERROR ("variable changed type");
  } else if (o != SWFDEC_AS_VALUE_GET_OBJECT (&v1)) {
    ERROR ("variable changed value");
  }
  /* step 4: gc, ensure that both objects disappears */
  swfdec_as_context_gc (context);
  if (check != NULL || check2 != NULL) {
    ERROR ("GC didn't collect unused object");
  }

  g_object_unref (context);
  return errors;

}
void
swfdec_system_query (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
{
  SwfdecPlayer *player = SWFDEC_PLAYER (cx);
  SwfdecAsValue val;
  guint i;
  GString *server;

  if (object == NULL) {
    SWFDEC_WARNING ("no this object in Query()");
    return;
  }

  server = g_string_new ("");
  for (i = 0; i < G_N_ELEMENTS (queries); i++) {
    queries[i].get (player, &val);
    swfdec_as_object_set_variable (object, queries[i].name, &val);
    if (queries[i].name == SWFDEC_AS_STR_screenResolutionY) {
      g_string_append_printf (server, "x%d", (int) SWFDEC_AS_VALUE_GET_NUMBER (val));
    } else if (queries[i].name == SWFDEC_AS_STR_pixelAspectRatio) {
      char buffer[10];
      g_ascii_formatd (buffer, sizeof (buffer), "%.1f",
	  SWFDEC_AS_VALUE_GET_NUMBER (val));
      g_string_append (server, "&AR=");
      g_string_append (server, buffer);
    } else if (queries[i].name == SWFDEC_AS_STR_manufacturer) {
      char *s = swfdec_as_string_escape (cx, player->priv->system->server_manufacturer);
      g_string_append_printf (server, "&M=%s", s);
      g_free (s);
    } else {
      g_assert (queries[i].server_string);
      if (i > 0)
	g_string_append_c (server, '&');
      g_string_append (server, queries[i].server_string);
      g_string_append_c (server, '=');
      if (SWFDEC_AS_VALUE_IS_BOOLEAN (val)) {
	g_string_append_c (server, SWFDEC_AS_VALUE_GET_BOOLEAN (val) ? 't' : 'f');
      } else if (SWFDEC_AS_VALUE_IS_NUMBER (val)) {
	g_string_append_printf (server, "%d", (int) SWFDEC_AS_VALUE_GET_NUMBER (val));
      } else if (SWFDEC_AS_VALUE_IS_STRING (val)) {
	char *s = swfdec_as_string_escape (cx, SWFDEC_AS_VALUE_GET_STRING (val));
	g_string_append (server, s);
	g_free (s);
      } else {
	g_assert_not_reached ();
      }
    }
  }
  SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_give_string (cx, g_string_free (server, FALSE)));
  swfdec_as_object_set_variable (object, SWFDEC_AS_STR_serverString, &val);
}
Ejemplo n.º 4
0
void
swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  gint32 length;
  const char *var;

  if (object == NULL || SWFDEC_IS_MOVIE (object))
    return;

  // don't allow negative length
  length = swfdec_as_array_length (object);
  if (length <= 0)
    return;

  swfdec_as_object_get_variable (object, SWFDEC_AS_STR_0, ret);

  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 (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_integer_to_string (swfdec_gc_object_get_context (object), length - 2);
      swfdec_as_object_get_variable (object, var, &val);
    } else {
      val = *ret;
    }
    var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object), length - 1);
    swfdec_as_object_set_variable (object, var, &val);
  }
}
Ejemplo n.º 5
0
Archivo: gc.c Proyecto: fengye/swfdec
static guint
check_objects (void)
{
  SwfdecAsObject *object;
  guint errors = 0;
  SwfdecAsContext *context;
  SwfdecAsValue val;
  gpointer check = GUINT_TO_POINTER (-1); /* NOT NULL */
  
  context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
  swfdec_as_context_startup (context);
  g_assert (check != NULL);

  object = swfdec_as_object_new (context);
  g_object_add_weak_pointer (G_OBJECT (object), &check);
  SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
  swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR__root, &val);
  swfdec_as_context_gc (context);
  if (check == NULL) {
    ERROR ("GC collected a rooted object, bailing");
    g_object_unref (context);
    return errors;
  }
  swfdec_as_object_delete_variable (context->global, SWFDEC_AS_STR__root);
  swfdec_as_context_gc (context);
  if (check != NULL) {
    ERROR ("GC did not collect an unreferenced object");
  }

  g_object_unref (context);
  return errors;
}
Ejemplo n.º 6
0
/**
 * swfdec_as_array_set_value:
 * @array: a #SwfdecAsArray
 * @idx: index of the value to set
 * @value: a pointer to #SwfdecAsValue
 *
 * Sets a @value to given index. The @array's length will be increased if
 * necessary.
 **/
void
swfdec_as_array_set_value (SwfdecAsArray *array, gint32 idx,
    SwfdecAsValue *value)
{
  const char *var;

  g_assert (SWFDEC_IS_AS_ARRAY (array));
  g_assert (idx >= 0);
  g_assert (SWFDEC_IS_AS_VALUE (value));

  var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (array), idx);
  swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (array), var, value);
}
Ejemplo n.º 7
0
static gboolean
swfdec_as_array_foreach_append_array_range (SwfdecAsObject *object,
    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
{
  ForeachAppendArrayRangeData *fdata = data;
  gint32 idx;
  const char *var;

  idx = swfdec_as_array_to_index (variable);
  if (idx >= fdata->start_index && idx < fdata->start_index + fdata->num) {
    var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (fdata->object_to),
	fdata->offset + (idx - fdata->start_index));
    swfdec_as_object_set_variable (fdata->object_to, var, value);
  }

  return TRUE;
}
Ejemplo n.º 8
0
void
swfdec_as_array_concat (SwfdecAsContext *cx, SwfdecAsObject *object,
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  guint j;
  SwfdecAsObject *object_new;
  SwfdecAsArray *array_new;
  const char *var;

  if (object == NULL || SWFDEC_IS_MOVIE (object))
    return;

  object_new = swfdec_as_array_new (cx);
  if (object_new == NULL)
    return;
  array_new = SWFDEC_AS_ARRAY (object_new);

  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_VALUE_GET_OBJECT (&argv[j]));
    }
    else
    {
      var = swfdec_as_integer_to_string (swfdec_gc_object_get_context (object),
	  swfdec_as_array_length (object_new));
      swfdec_as_object_set_variable (object_new, var, &argv[j]);
    }
  }

  SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);
}
Ejemplo n.º 9
0
static void
swfdec_as_array_do_sort (SwfdecAsContext *cx, SwfdecAsObject *object,
    const SortOption *options, SwfdecAsFunction *custom_function,
    const char **fields, SwfdecAsValue *ret)
{
  SortEntry *array;
  SortCollectData collect_data;
  SortCompareData compare_data;
  gint32 i, length;
  const char *var;
  SwfdecAsObject *target;
  SwfdecAsValue val;
  SortOption options_;
  gboolean descending;

  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx));
  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
  g_return_if_fail (options != NULL);
  g_return_if_fail (custom_function == NULL ||
      SWFDEC_IS_AS_FUNCTION (custom_function));
  g_return_if_fail (fields == NULL || fields[0] != NULL);

  length = swfdec_as_array_length (object);
  if (length == 0) {
    // special case for empty array, because g_try_new0 would return NULL
    SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
    return;
  }

  if (!swfdec_as_context_try_use_mem (cx, sizeof (SortEntry) * length)) {
    SWFDEC_WARNING ("Array not sorted, too big (%i elements)", length);
    SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
    return;
  }

  // FIXME: this should be different, but context's memory management is not
  // done properly yet
  array = g_try_new0 (SortEntry, length);
  if (!array) {
    SWFDEC_WARNING ("Array not sorted, too big (%i elements)", length);
    SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
    goto done;
  }

  for (i = 0; i < length; i++) {
    array[i].index_ = i;
  }

  // collect values and indexes to the array
  collect_data.length = length;
  collect_data.array = array;

  swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_collect,
	&collect_data);

  // sort the array
  compare_data.context = cx;
  compare_data.fields = fields;
  compare_data.options = options;
  // if no fields, then we'll do descending here after the sort
  if (fields == NULL && options[0] & SORT_OPTION_DESCENDING) {
    descending = TRUE;
    options_ = options[0] & ~SORT_OPTION_DESCENDING;
    compare_data.options = &options_;
  } else {
    descending = FALSE;
  }
  compare_data.custom_function = custom_function;
  compare_data.equal_found = FALSE;

  swfdec_as_array_sort_array (array, length, swfdec_as_array_sort_compare,
      &compare_data);

  // check unique sort
  if (options[0] & SORT_OPTION_UNIQUESORT) {
    if (fields == NULL && custom_function != NULL) {
      // if we used custom_function for comparision, we shall now go trough the
      // sorted array and compare them using the default array sort comparision
      // and use that to decide if it's unique (no it doesn't make too much
      // sense)
      for (i = 0; i < length - 1; i++) {
	SwfdecAsValue *a = &array[i].value;
	SwfdecAsValue *b = &array[i + 1].value;
	if (swfdec_as_array_sort_compare_values (cx, a, b, 0, NULL) == 0)
	  break;
      }
      if (i < length - 1) {
	SWFDEC_AS_VALUE_SET_INT (ret, 0);
	goto done;
      }
    } else if (compare_data.equal_found) {
      SWFDEC_AS_VALUE_SET_INT (ret, 0);
      goto done;
    }
  }

  if (options[0] & SORT_OPTION_RETURNINDEXEDARRAY) {
    target = swfdec_as_array_new (cx);
    if (!target)
      goto done;
  } else {
    target = object;
  }

  for (i = 0; i < length; i++) {
    SortEntry *entry = &array[i];

    // set only the values that have new indexes
    if (!(options[0] & SORT_OPTION_RETURNINDEXEDARRAY) &&
	entry->index_ == (descending ? length - i - 1 : i))
      continue;

    var = swfdec_as_integer_to_string (cx, (descending ? length - i - 1 : i));
    if (options[0] & SORT_OPTION_RETURNINDEXEDARRAY) {
      SWFDEC_AS_VALUE_SET_INT (&val, entry->index_);
      swfdec_as_object_set_variable (target, var, &val);
    } else {
      swfdec_as_object_set_variable (target, var, &entry->value);
    }
  }

  SWFDEC_AS_VALUE_SET_OBJECT (ret, target);

done:
  g_free (array);
  swfdec_as_context_unuse_mem (cx, sizeof (SortEntry) * length);
}
Ejemplo n.º 10
0
int
main (int argc, char **argv)
{
    char *script_filename = NULL;
    GError *error = NULL;
    SwfdecAsContext *context;
    SwfdecAsObject *array;
    SwfdecScript *script;
    SwfdecAsValue val;
    int i, ret;
    gboolean dump = FALSE;
    gboolean no_check = FALSE, only_check = FALSE;

    GOptionEntry options[] = {
        { "dump", 'd', 0, G_OPTION_ARG_NONE, &dump, "dump informative output on failure", FALSE },
        { "no-check", 0, 0, G_OPTION_ARG_NONE, &no_check, "don't check if the system is ok for running the testsuite", FALSE },
        { "self-check", 0, 0, G_OPTION_ARG_NONE, &only_check, "run a system check and exit", FALSE },
        { "player", 'p', 0, G_OPTION_ARG_STRING, &swfdec_test_plugin_name, "player to test", "NAME" },
        { "script", 's', 0, G_OPTION_ARG_STRING, &script_filename, "script to execute if not ./default.sts", "FILENAME" },
        { NULL }
    };
    GOptionContext *ctx;

    /* set the right warning levels */
    g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
    /* by default get rid of the loads of warnings the tests produce */
    g_setenv ("SWFDEC_DEBUG", "2", FALSE);

    g_thread_init (NULL);
    swfdec_init ();

    ctx = g_option_context_new ("");
    g_option_context_add_main_entries (ctx, options, "options");
    g_option_context_parse (ctx, &argc, &argv, &error);
    g_option_context_free (ctx);

    if (error) {
        g_printerr ("ERROR: wrong command line arguments: %s\n", error->message);
        g_error_free (error);
        return EXIT_FAILURE;
    }

    if (only_check || !no_check) {
        gboolean result = check_system (only_check);
        if (!result) {
            g_print ("ERROR: System checked failed, aborting. Use --no-check to disable.\n");
            return 1;
        } else if (only_check) {
            return 0;
        }
    }
    g_assert (!only_check);

    /* allow env vars instead of options - eases running make check with different settings */
    if (swfdec_test_plugin_name == NULL)
        swfdec_test_plugin_name = g_strdup (g_getenv ("SWFDEC_TEST_PLAYER"));

    script = load_script (script_filename);
    g_free (script_filename);
    if (script == NULL)
        return EXIT_FAILURE;

    context = g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
    swfdec_as_context_startup (context);

    SWFDEC_AS_VALUE_SET_BOOLEAN (&val, dump);
    swfdec_as_object_set_variable (context->global,
                                   swfdec_as_context_get_string (context, "dump"), &val);

    swfdec_test_function_init_context (context);
    swfdec_as_context_run_init_script (context, swfdec_test_initialize,
                                       sizeof (swfdec_test_initialize), SWFDEC_TEST_VERSION);

    array = swfdec_as_array_new (context);
    if (array == NULL) {
        g_print ("ERROR: Not enough memory");
        return EXIT_FAILURE;
    }
    if (argc < 2) {
        GDir *dir;
        const char *file;
        dir = g_dir_open (".", 0, NULL);
        while ((file = g_dir_read_name (dir))) {
            if (!g_str_has_suffix (file, ".swf"))
                continue;
            SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, file));
            swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val);
        }
        g_dir_close (dir);
    } else {
        for (i = 1; i < argc; i++) {
            SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (context, argv[i]));
            swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val);
        }
    }
    SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
    swfdec_as_object_set_variable (context->global,
                                   swfdec_as_context_get_string (context, "filenames"), &val);
    swfdec_as_object_run (context->global, script);
    if (swfdec_as_context_catch (context, &val)) {
        g_print ("ERROR: %s\n", swfdec_as_value_to_string (context, &val));
        ret = EXIT_FAILURE;
    } else {
        g_print ("SUCCESS\n");
        ret = EXIT_SUCCESS;
    }

    swfdec_script_unref (script);
    g_object_unref (context);

    return ret;
}