[Swfdec] [PATCH] swfdec: better variable parsing.

Andreas Henriksson andreas at fatal.se
Sat Nov 10 14:20:36 PST 2007


Use swfdec_as_object_decode for parsing variables passed in webpages to flash.

swfdec_movie_set_variables (and friends) can't stuff like an url being passed
in the value of a variable and other things.
Pages which where broken included the flash at the upper right
corner of http://www.kanal5.se and the presentation of houses for
sale at http://www.svenskfast.se.

Solution: use swfdec_as_object_decode and kill off swfdec_movie_set_variables,
swfdec_urldecode_one_string, swfdec_urldecode_one and the flawed testcase in
test/various/urlencode.c.

---

Since the segfault where just fixed in git, I've now tested this patch which
works perfectly as far as I can see.

diffstat:

 b/libswfdec/swfdec_loader.c          |  106 ---------------------------------
 b/libswfdec/swfdec_loader_internal.h |    4 -
 b/libswfdec/swfdec_movie.c           |   46 --------------
 b/libswfdec/swfdec_movie.h           |    2 
 b/libswfdec/swfdec_resource.c        |    4 -
 test/various/urlencode.c             |  112 -----------------------------------
 6 files changed, 2 insertions(+), 272 deletions(-)


diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 618b9d7..0d0a56e 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -602,54 +602,6 @@ swfdec_urlencode_append_string (GString *str, const char *s)
   }
 }
 
-static char *
-swfdec_urldecode_one_string (const char *s, const char **out)
-{
-  GString *ret = g_string_new ("");
-
-  while (*s) {
-    if (strchr (urlencode_unescaped, *s)) {
-      g_string_append_c (ret, *s);
-    } else if (*s == '+') {
-      g_string_append_c (ret, ' ');
-    } else if (*s == '%') {
-      guint byte;
-      s++;
-      if (*s >= '0' && *s <= '9') {
-	byte = *s - '0';
-      } else if (*s >= 'A' && *s <= 'F') {
-	byte = *s - 'A' + 10;
-      } else if (*s >= 'a' && *s <= 'f') {
-	byte = *s - 'a' + 10;
-      } else {
-	g_string_free (ret, TRUE);
-	*out = s;
-	return NULL;
-      }
-      byte *= 16;
-      s++;
-      if (*s >= '0' && *s <= '9') {
-	byte += *s - '0';
-      } else if (*s >= 'A' && *s <= 'F') {
-	byte += *s - 'A' + 10;
-      } else if (*s >= 'a' && *s <= 'f') {
-	byte += *s - 'a' + 10;
-      } else {
-	g_string_free (ret, TRUE);
-	*out = s;
-	return NULL;
-      }
-      g_assert (byte < 256);
-      g_string_append_c (ret, byte);
-    } else {
-      break;
-    }
-    s++;
-  }
-  *out = s;
-  return g_string_free (ret, FALSE);
-}
-
 /**
  * swfdec_string_append_urlencoded:
  * @str: a #GString
@@ -673,61 +625,3 @@ swfdec_string_append_urlencoded (GString *str, const char *name, const char *val
     swfdec_urlencode_append_string (str, value);
 }
 
-/**
- * swfdec_urldecode_one:
- * @string: string in 'application/x-www-form-urlencoded' form
- * @name: pointer that will hold a newly allocated string for the name of the 
- *        parsed property or NULL
- * @value: pointer that will hold a newly allocated string containing the 
- *         value of the parsed property or NULL
- * @end: If not %NULL, on success, pointer to the first byte in @s that was 
- *       not parsed. On failure it will point to the byte causing the problem
- *
- * Tries to parse the given @string into a name/value pair, assuming the string 
- * is in the application/x-www-form-urlencoded format. If the parsing succeeds,
- * @name and @value will contain the parsed values and %TRUE will be returned.
- *
- * Returns: %TRUE if parsing the property succeeded, %FALSE otherwise
- */
-gboolean
-swfdec_urldecode_one (const char *string, char **name, char **value, const char **end)
-{
-  char *name_str, *value_str;
-
-  g_return_val_if_fail (string != NULL, FALSE);
-
-  name_str = swfdec_urldecode_one_string (string, &string);
-  if (name_str == NULL)
-    goto fail;
-  if (*string != '=') {
-    g_free (name_str);
-    goto fail;
-  }
-  string++;
-  value_str = swfdec_urldecode_one_string (string, &string);
-  if (value_str == NULL) {
-    g_free (name_str);
-    goto fail;
-  }
-
-  if (name)
-    *name = name_str;
-  else
-    g_free (name_str);
-  if (value)
-    *value = value_str;
-  else
-    g_free (value_str);
-  if (end)
-    *end = string;
-  return TRUE;
-
-fail:
-  if (name)
-    *name = NULL;
-  if (value)
-    *value = NULL;
-  if (end)
-    *end = string;
-  return FALSE;
-}
diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h
index 22b2421..21e0be8 100644
--- a/libswfdec/swfdec_loader_internal.h
+++ b/libswfdec/swfdec_loader_internal.h
@@ -45,10 +45,6 @@ void			swfdec_loader_set_target	(SwfdecLoader *		loader,
 void			swfdec_loader_set_data_type	(SwfdecLoader *		loader,
 							 SwfdecLoaderDataType	type);
 
-gboolean		swfdec_urldecode_one		(const char *		string,
-							 char **		name,
-							 char **		value,
-							 const char **		end);
 void			swfdec_string_append_urlencoded	(GString *		str,
 							 const char *		name,
 							 const char *		value);
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 57c18d0..2bf65ac 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -493,52 +493,6 @@ swfdec_movie_queue_script (SwfdecMovie *movie, SwfdecEventType condition)
   return ret;
 }
 
-/**
- * swfdec_movie_set_variables:
- * @script: a #SwfdecMovie
- * @variables: variables to set on @movie in application-x-www-form-urlencoded 
- *             format
- * 
- * Verifies @variables to be encoded correctly and sets them as string 
- * properties on the given @movie.
- **/
-void
-swfdec_movie_set_variables (SwfdecMovie *movie, const char *variables)
-{
-  SwfdecAsObject *as;
-
-  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
-  g_return_if_fail (variables != NULL);
-
-  as = SWFDEC_AS_OBJECT (movie);
-  SWFDEC_DEBUG ("setting variables on %p: %s", movie, variables);
-  while (TRUE) {
-    char *name, *value;
-    const char *asname;
-    SwfdecAsValue val;
-
-    while (*variables == '&')
-      variables++;
-    if (*variables == '\0')
-      break;
-    if (!swfdec_urldecode_one (variables, &name, &value, &variables)) {
-      SWFDEC_WARNING ("variables invalid at \"%s\"", variables);
-      break;
-    }
-    if (*variables != '\0' && *variables != '&') {
-      SWFDEC_WARNING ("variables not delimited with & at \"%s\"", variables);
-      g_free (name);
-      g_free (value);
-      break;
-    }
-    SWFDEC_LOG ("Set variable \"%s\" to \"%s\"", name, value);
-    asname = swfdec_as_context_give_string (as->context, name);
-    SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (as->context, value));
-    g_free (value);
-    swfdec_as_object_set_variable (as, asname, &val);
-  }
-}
-
 /* NB: coordinates are in movie's coordiante system. Use swfdec_movie_get_mouse
  * if you have global coordinates */
 gboolean
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 17a2f3b..00c414c 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -247,8 +247,6 @@ void		swfdec_movie_execute		(SwfdecMovie *		movie,
 						 SwfdecEventType	condition);
 gboolean      	swfdec_movie_queue_script	(SwfdecMovie *		movie,
   						 SwfdecEventType	condition);
-void		swfdec_movie_set_variables	(SwfdecMovie *		movie,
-						 const char *		variables);
 void		swfdec_movie_load_variables	(SwfdecMovie *		movie,
 						 const char *		url,
 						 SwfdecLoaderRequest	request,
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 6b7f540..a072108 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -223,11 +223,11 @@ swfdec_resource_loader_target_open (SwfdecLoaderTarget *target, SwfdecLoader *lo
   query = swfdec_url_get_query (swfdec_loader_get_url (loader));
   if (query) {
     SWFDEC_INFO ("set url query movie variables: %s", query);
-    swfdec_movie_set_variables (SWFDEC_MOVIE (instance->movie), query);
+    swfdec_as_object_decode (SWFDEC_AS_OBJECT (instance->movie), query);
   }
   if (instance->variables) {
     SWFDEC_INFO ("set manual movie variables: %s", instance->variables);
-    swfdec_movie_set_variables (SWFDEC_MOVIE (instance->movie), instance->variables);
+    swfdec_as_object_decode (SWFDEC_AS_OBJECT (instance->movie), instance->variables);
   }
   swfdec_resource_emit_signal (instance, SWFDEC_AS_STR_onLoadStart, FALSE, NULL, 0);
   instance->state = SWFDEC_RESOURCE_OPENED;
diff --git a/test/various/urlencode.c b/test/various/urlencode.c
deleted file mode 100644
index 46654b6..0000000
--- a/test/various/urlencode.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Swfdec
- * Copyright (C) 2006 Benjamin Otte <otte at gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "libswfdec/swfdec_loader_internal.h"
-
-typedef struct {
-  const char *  encoded;
-  const char *  names[10];
-  const char *  values[10];
-  guint		n_props;
-} Test;
-Test tests[] = {
-  { "a=b", { "a" }, { "b" }, 1 },
-  { "a=b&c=d", { "a", "c" }, { "b", "d" }, 2 },
-  { "owned=Your+Mom", { "owned" }, { "Your Mom" }, 1 },
-  { "numbers=0123456789&uppercase=ABCDEFGHIJKLMNOPQRSTUVWXYZ&lowercase=abcdefghijklmnopqrstuvwxyz&special+chars=.-_/", 
-    { "numbers", "uppercase", "lowercase", "special chars" }, 
-    { "0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", ".-_/" }, 4 }
-};
-
-#define ERROR(...) G_STMT_START { \
-  g_printerr ("ERROR (line %u): ", __LINE__); \
-  g_printerr (__VA_ARGS__); \
-  g_printerr ("\n"); \
-  errors++; \
-}G_STMT_END
-
-static guint
-run_test_encode (Test *test)
-{
-  GString *string;
-  guint i, errors = 0;
-
-  string = g_string_new ("");
-  for (i = 0; i < test->n_props; i++) {
-    swfdec_string_append_urlencoded (string, test->names[i], test->values[i]);
-  }
-  if (!g_str_equal (test->encoded, string->str)) {
-    ERROR ("encoded string is \"%s\", but should be \"%s\"", string->str, test->encoded);
-  }
-  g_string_free (string, TRUE);
-  return errors;
-}
-
-static guint
-run_test_decode (Test *test)
-{
-  guint i, errors = 0;
-  char *name, *value;
-  const char *s = test->encoded;
-
-  for (i = 0; i < test->n_props; i++) {
-    if (*s == '\0') {
-      ERROR ("string only contains %u properties, but should contain %u", i, test->n_props);
-      break;
-    }
-    if (i > 0) {
-      if (*s != '&') {
-	ERROR ("properties not delimited by &");
-      }
-      s++;
-    }
-    if (!swfdec_urldecode_one (s, &name, &value, &s)) {
-      ERROR ("could not decode property %u", i);
-      continue;
-    }
-    if (!g_str_equal (name, test->names[i])) {
-      ERROR ("names don't match: is %s, should be %s", name, test->names[i]);
-    }
-    if (!g_str_equal (value, test->values[i])) {
-      ERROR ("names don't match: is %s, should be %s", value, test->values[i]);
-    }
-    g_free (name);
-    g_free (value);
-  }
-  return errors;
-}
-
-int
-main (int argc, char **argv)
-{
-  guint i, errors = 0;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++) {
-    errors += run_test_encode (&tests[i]);
-    errors += run_test_decode (&tests[i]);
-  }
-
-  g_print ("TOTAL ERRORS: %u\n", errors);
-  return errors;
-}
-



-- 
Regards,
Andreas Henriksson



More information about the Swfdec mailing list