[Swfdec-commits] 9 commits - swfdec/Makefile.am swfdec/swfdec_as_context.c swfdec/swfdec_as_context.h swfdec/swfdec_as_frame.c swfdec/swfdec_as_frame_internal.h swfdec/swfdec_as_interpret.c swfdec/swfdec_constant_pool.c swfdec/swfdec_constant_pool.h swfdec/swfdec_resource.c swfdec/swfdec_script.c swfdec/swfdec_script_internal.h swfdec/swfdec_stream.c test/trace
Benjamin Otte
company at kemper.freedesktop.org
Tue Mar 25 14:56:43 PDT 2008
swfdec/Makefile.am | 2
swfdec/swfdec_as_context.c | 17 +
swfdec/swfdec_as_context.h | 3
swfdec/swfdec_as_frame.c | 15 -
swfdec/swfdec_as_frame_internal.h | 1
swfdec/swfdec_as_interpret.c | 24 +-
swfdec/swfdec_constant_pool.c | 199 +++++++++++++++++++++
swfdec/swfdec_constant_pool.h | 47 ++++
swfdec/swfdec_resource.c | 13 -
swfdec/swfdec_script.c | 77 --------
swfdec/swfdec_script_internal.h | 13 -
swfdec/swfdec_stream.c | 4
test/trace/crash-0.6.0-moviecliploader-7.swf.trace | 2
test/trace/crash-0.6.0-moviecliploader-8.swf.trace | 2
14 files changed, 298 insertions(+), 121 deletions(-)
New commits:
commit 87b32475634a25e9e22a087a00b14c631ab5ff6c
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 22:38:38 2008 +0100
really abort when it's not a Flash file
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index 88cef97..57cd544 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -322,14 +322,15 @@ swfdec_resource_stream_target_parse (SwfdecStreamTarget *target, SwfdecStream *s
return FALSE;
}
-static void
+static gboolean
swfdec_resource_abort_if_not_initialized (SwfdecResource *resource)
{
if (resource->sandbox)
- return;
+ return FALSE;
swfdec_as_context_abort (SWFDEC_AS_OBJECT (resource)->context,
"This is not a Flash file");
+ return TRUE;
}
static void
@@ -349,7 +350,8 @@ swfdec_resource_stream_target_close (SwfdecStreamTarget *target, SwfdecStream *s
SWFDEC_AS_VALUE_SET_INT (&val, 0); /* FIXME */
swfdec_resource_emit_signal (resource, SWFDEC_AS_STR_onLoadComplete, FALSE, &val, 1);
resource->state = SWFDEC_RESOURCE_COMPLETE;
- swfdec_resource_abort_if_not_initialized (resource);
+ if (swfdec_resource_abort_if_not_initialized (resource))
+ return;
if (resource->movie != NULL) {
swfdec_player_add_action (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (resource)->context),
commit 4de4ea0a7b3d6f3410e49dda31264654aaba7b01
Merge: bf8dfe1... 6cf304b...
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 22:18:54 2008 +0100
Merge branch '0.6'
Conflicts:
test/trace/crash-0.6.0-moviecliploader-7.swf.trace
test/trace/crash-0.6.0-moviecliploader-8.swf.trace
commit 6cf304b397fec8b7f500ab39d2e8aae468fbdf65
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 22:02:08 2008 +0100
cope better with errors during parsing that unset the target
diff --git a/swfdec/swfdec_stream.c b/swfdec/swfdec_stream.c
index de3d3ab..40944c9 100644
--- a/swfdec/swfdec_stream.c
+++ b/swfdec/swfdec_stream.c
@@ -215,9 +215,11 @@ swfdec_stream_process (gpointer streamp, gpointer unused)
if (swfdec_stream_target_parse (priv->target, stream)) {
swfdec_stream_queue_processing (stream);
goto out;
- } else {
+ } else if (priv->target) {
priv->processed_state = SWFDEC_STREAM_STATE_CLOSED;
swfdec_stream_target_close (priv->target, stream);
+ } else {
+ goto out;
}
}
}
commit 7276aa19b340f9dc817d3d604e2579e0268b1d6d
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 22:01:41 2008 +0100
if we get a security error, keep using the old sandbox
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index ed64f7d..e07b15b 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -76,7 +76,9 @@ swfdec_resource_stream_target_image (SwfdecResource *instance)
if (SWFDEC_IS_SWF_DECODER (instance->decoder)) {
SwfdecSwfDecoder *dec = SWFDEC_SWF_DECODER (instance->decoder);
+ SwfdecSandbox *old_sandbox;
+ old_sandbox = instance->sandbox;
instance->sandbox = swfdec_sandbox_get_for_url (player,
swfdec_loader_get_url (instance->loader), instance->version,
SWFDEC_SWF_DECODER (instance->decoder)->use_network);
@@ -95,7 +97,8 @@ swfdec_resource_stream_target_image (SwfdecResource *instance)
SWFDEC_FIXME ("cannot continue loading %s, invalid rights",
swfdec_url_get_url (swfdec_loader_get_url (instance->loader)));
swfdec_stream_set_target (SWFDEC_STREAM (instance->loader), NULL);
- /* FIXME: anyting on the movie we need to clear? */
+ instance->sandbox = old_sandbox;
+ /* FIXME: anyting else on the movie we need to clear? */
}
} else {
g_assert_not_reached ();
commit 7db2e30e6ad05c7d6753360d193db9e64bb6aa9a
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 22:00:35 2008 +0100
remove debugging info from traces
diff --git a/test/trace/crash-0.6.0-moviecliploader-7.swf.trace b/test/trace/crash-0.6.0-moviecliploader-7.swf.trace
index 9b2ccc2..7696e88 100644
--- a/test/trace/crash-0.6.0-moviecliploader-7.swf.trace
+++ b/test/trace/crash-0.6.0-moviecliploader-7.swf.trace
@@ -1,4 +1,2 @@
Start
-*** Security Sandbox Violation ***
-Connection to file:///home/medar/Projects/Flash/swfdec/test/pending/getvariable-exhaustive-8.swf halted - not permitted from file:///home/medar/Projects/Flash/swfdec/test/pending/crash-0.6.0-moviecliploader-7.swf
Done
diff --git a/test/trace/crash-0.6.0-moviecliploader-8.swf.trace b/test/trace/crash-0.6.0-moviecliploader-8.swf.trace
index e87c7b5..7696e88 100644
--- a/test/trace/crash-0.6.0-moviecliploader-8.swf.trace
+++ b/test/trace/crash-0.6.0-moviecliploader-8.swf.trace
@@ -1,4 +1,2 @@
Start
-*** Security Sandbox Violation ***
-Connection to file:///home/medar/Projects/Flash/swfdec/test/pending/getvariable-exhaustive-8.swf halted - not permitted from file:///home/medar/Projects/Flash/swfdec/test/pending/crash-0.6.0-moviecliploader-8.swf
Done
commit 34603bcdc4ab6d2f0ff8f4bb1b56965b97202907
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 21 22:16:54 2008 +0100
update to min API changes
diff --git a/vivified/core/vivi_ming.c b/vivified/core/vivi_ming.c
index a126455..c015c1a 100644
--- a/vivified/core/vivi_ming.c
+++ b/vivified/core/vivi_ming.c
@@ -88,7 +88,7 @@ vivi_ming_compile (const char *code, char **error)
{
byte *data;
SWFAction action;
- gsize len;
+ gssize len;
SwfdecBuffer *buffer;
SwfdecScript *script;
commit c366dd172877c5e2d04a901dd84eccb4bb334a0e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Tue Feb 26 14:44:10 2008 +0200
Add a test for assert in MovieClipLoader
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 3a26cbd..f6d1fdf 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -713,6 +713,11 @@ EXTRA_DIST = \
crash-0.5.90-empty-action.swf \
crash-0.5.90-empty-action.swf.trace \
crash-0.5.90-empty-action.xml \
+ crash-0.6.0-moviecliploader.as \
+ crash-0.6.0-moviecliploader-7.swf \
+ crash-0.6.0-moviecliploader-7.swf.trace \
+ crash-0.6.0-moviecliploader-8.swf \
+ crash-0.6.0-moviecliploader-8.swf.trace \
currentframe.swf \
currentframe.swf.trace \
dangling-compare.as \
diff --git a/test/trace/crash-0.6.0-moviecliploader-7.swf b/test/trace/crash-0.6.0-moviecliploader-7.swf
new file mode 100644
index 0000000..6439c1c
Binary files /dev/null and b/test/trace/crash-0.6.0-moviecliploader-7.swf differ
diff --git a/test/trace/crash-0.6.0-moviecliploader-7.swf.trace b/test/trace/crash-0.6.0-moviecliploader-7.swf.trace
new file mode 100644
index 0000000..9b2ccc2
--- /dev/null
+++ b/test/trace/crash-0.6.0-moviecliploader-7.swf.trace
@@ -0,0 +1,4 @@
+Start
+*** Security Sandbox Violation ***
+Connection to file:///home/medar/Projects/Flash/swfdec/test/pending/getvariable-exhaustive-8.swf halted - not permitted from file:///home/medar/Projects/Flash/swfdec/test/pending/crash-0.6.0-moviecliploader-7.swf
+Done
diff --git a/test/trace/crash-0.6.0-moviecliploader-8.swf b/test/trace/crash-0.6.0-moviecliploader-8.swf
new file mode 100644
index 0000000..aed18d2
Binary files /dev/null and b/test/trace/crash-0.6.0-moviecliploader-8.swf differ
diff --git a/test/trace/crash-0.6.0-moviecliploader-8.swf.trace b/test/trace/crash-0.6.0-moviecliploader-8.swf.trace
new file mode 100644
index 0000000..e87c7b5
--- /dev/null
+++ b/test/trace/crash-0.6.0-moviecliploader-8.swf.trace
@@ -0,0 +1,4 @@
+Start
+*** Security Sandbox Violation ***
+Connection to file:///home/medar/Projects/Flash/swfdec/test/pending/getvariable-exhaustive-8.swf halted - not permitted from file:///home/medar/Projects/Flash/swfdec/test/pending/crash-0.6.0-moviecliploader-8.swf
+Done
diff --git a/test/trace/crash-0.6.0-moviecliploader.as b/test/trace/crash-0.6.0-moviecliploader.as
new file mode 100644
index 0000000..5b62d8f
--- /dev/null
+++ b/test/trace/crash-0.6.0-moviecliploader.as
@@ -0,0 +1,16 @@
+// makeswf -n -v 7 -r 1 -o crash-0.6.0-moviecliploader.swf crash-0.6.0-moviecliploader.as
+
+// NOTE: Has to be compiled with -n
+
+trace ("Start");
+
+this.createEmptyMovieClip ("a", 0);
+var l = new MovieClipLoader ();
+l.loadClip ("getvariable-exhaustive-8.swf", a);
+
+function quit () {
+ trace ("Done");
+ loadMovie ("FSCommand:quit", "");
+}
+
+setInterval (quit, 2000);
commit bf8dfe10bbccc51c3d1928f555a5a577adbd279f
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 19:55:04 2008 +0100
rewrite constant pools
Constant pools are now automatically garbage collected and keep the buffer they
refer to available.
diff --git a/swfdec/swfdec_as_context.c b/swfdec/swfdec_as_context.c
index c75f15a..0d0bef3 100644
--- a/swfdec/swfdec_as_context.c
+++ b/swfdec/swfdec_as_context.c
@@ -36,6 +36,7 @@
#include "swfdec_as_stack.h"
#include "swfdec_as_strings.h"
#include "swfdec_as_types.h"
+#include "swfdec_constant_pool.h"
#include "swfdec_debug.h"
#include "swfdec_internal.h" /* for swfdec_player_preinit_global() */
#include "swfdec_script.h"
@@ -380,6 +381,18 @@ swfdec_as_context_mark_roots (gpointer key, gpointer value, gpointer data)
swfdec_as_object_mark (object);
}
+/* FIXME: replace this with refcounted strings? */
+static void
+swfdec_as_context_mark_constant_pools (gpointer key, gpointer value, gpointer unused)
+{
+ SwfdecConstantPool *pool = value;
+ guint i;
+
+ for (i = 0; i < swfdec_constant_pool_size (pool); i++) {
+ swfdec_as_string_mark (swfdec_constant_pool_get (pool, i));
+ }
+}
+
static void
swfdec_as_context_do_mark (SwfdecAsContext *context)
{
@@ -394,6 +407,7 @@ swfdec_as_context_do_mark (SwfdecAsContext *context)
if (context->exception)
swfdec_as_value_mark (&context->exception_value);
g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL);
+ g_hash_table_foreach (context->constant_pools, swfdec_as_context_mark_constant_pools, NULL);
}
/**
@@ -524,6 +538,8 @@ swfdec_as_context_dispose (GObject *object)
g_critical ("%zu bytes of memory left over\n", context->memory);
}
g_assert (g_hash_table_size (context->objects) == 0);
+ g_assert (g_hash_table_size (context->constant_pools) == 0);
+ g_hash_table_destroy (context->constant_pools);
g_hash_table_destroy (context->objects);
g_hash_table_destroy (context->strings);
g_rand_free (context->rand);
@@ -583,6 +599,7 @@ swfdec_as_context_init (SwfdecAsContext *context)
context->strings = g_hash_table_new (g_str_hash, g_str_equal);
context->objects = g_hash_table_new (g_direct_hash, g_direct_equal);
+ context->constant_pools = g_hash_table_new (g_direct_hash, g_direct_equal);
for (s = swfdec_as_strings; *s == '\2'; s += strlen (s) + 1) {
g_hash_table_insert (context->strings, (char *) s + 1, (char *) s);
diff --git a/swfdec/swfdec_as_context.h b/swfdec/swfdec_as_context.h
index 3f1ed1e..8cb877b 100644
--- a/swfdec/swfdec_as_context.h
+++ b/swfdec/swfdec_as_context.h
@@ -56,8 +56,9 @@ struct _SwfdecAsContext {
/* bookkeeping for GC */
gsize memory; /* total memory currently in use */
gsize memory_since_gc;/* memory allocated since last GC run */
- GHashTable * strings; /* string=>memory mapping the context manages */
+ GHashTable * strings; /* string => memory mapping the context manages */
GHashTable * objects; /* all objects the context manages */
+ GHashTable * constant_pools; /* memory address => SwfdecConstantPool for all gc'ed pools */
/* execution state */
unsigned int version; /* currently active version */
diff --git a/swfdec/swfdec_as_frame.c b/swfdec/swfdec_as_frame.c
index 39888b6..d4bf392 100644
--- a/swfdec/swfdec_as_frame.c
+++ b/swfdec/swfdec_as_frame.c
@@ -278,13 +278,9 @@ swfdec_as_frame_dispose (GObject *object)
/* clean up */
g_slice_free1 (sizeof (SwfdecAsValue) * frame->n_registers, frame->registers);
if (frame->constant_pool) {
- swfdec_constant_pool_free (frame->constant_pool);
+ swfdec_constant_pool_unref (frame->constant_pool);
frame->constant_pool = NULL;
}
- if (frame->constant_pool_buffer) {
- swfdec_buffer_unref (frame->constant_pool_buffer);
- frame->constant_pool_buffer = NULL;
- }
g_array_free (frame->blocks, TRUE);
g_slist_free (frame->scope_chain);
if (frame->script) {
@@ -409,12 +405,9 @@ swfdec_as_frame_new (SwfdecAsContext *context, SwfdecScript *script)
frame->n_registers = script->n_registers;
frame->registers = g_slice_alloc0 (sizeof (SwfdecAsValue) * frame->n_registers);
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->version);
- if (frame->constant_pool) {
- swfdec_constant_pool_attach_to_context (frame->constant_pool, context);
- } else {
+ frame->constant_pool = swfdec_constant_pool_new (context,
+ script->constant_pool, script->version);
+ if (frame->constant_pool == NULL) {
SWFDEC_ERROR ("couldn't create constant pool");
}
}
diff --git a/swfdec/swfdec_as_frame_internal.h b/swfdec/swfdec_as_frame_internal.h
index 07175a1..0dc9a5e 100644
--- a/swfdec/swfdec_as_frame_internal.h
+++ b/swfdec/swfdec_as_frame_internal.h
@@ -52,7 +52,6 @@ struct _SwfdecAsFrame {
SwfdecAsValue * registers; /* the registers */
guint n_registers; /* number of allocated registers */
SwfdecConstantPool * constant_pool; /* constant pool currently in use */
- SwfdecBuffer * constant_pool_buffer; /* buffer containing the raw data for constant_pool */
SwfdecAsValue * stack_begin; /* beginning of stack */
const guint8 * pc; /* program counter on stack */
/* native function */
diff --git a/swfdec/swfdec_as_interpret.c b/swfdec/swfdec_as_interpret.c
index ff0a66c..3544a1b 100644
--- a/swfdec/swfdec_as_interpret.c
+++ b/swfdec/swfdec_as_interpret.c
@@ -287,19 +287,19 @@ swfdec_action_constant_pool (SwfdecAsContext *cx, guint action, const guint8 *da
{
SwfdecConstantPool *pool;
SwfdecAsFrame *frame;
+ SwfdecBuffer *buffer;
frame = cx->frame;
- pool = swfdec_constant_pool_new_from_action (data, len, cx->version);
+ /* FIXME: lots of hackery to get at the buffer */
+ buffer = frame->script->buffer;
+ buffer = swfdec_buffer_new_subbuffer (buffer, data - buffer->data, len);
+ pool = swfdec_constant_pool_new (cx, buffer, cx->version);
+ swfdec_buffer_unref (buffer);
if (pool == NULL)
return;
- swfdec_constant_pool_attach_to_context (pool, cx);
if (frame->constant_pool)
- swfdec_constant_pool_free (frame->constant_pool);
+ swfdec_constant_pool_unref (frame->constant_pool);
frame->constant_pool = pool;
- if (frame->constant_pool_buffer)
- swfdec_buffer_unref (frame->constant_pool_buffer);
- frame->constant_pool_buffer = swfdec_buffer_new_subbuffer (frame->script->buffer,
- data - frame->script->buffer->data, len);
}
static void
@@ -1885,8 +1885,8 @@ swfdec_action_define_function (SwfdecAsContext *cx, guint action,
g_free (function_name);
return;
}
- if (frame->constant_pool_buffer)
- script->constant_pool = swfdec_buffer_ref (frame->constant_pool_buffer);
+ if (frame->constant_pool)
+ script->constant_pool = swfdec_buffer_ref (swfdec_constant_pool_get_buffer (frame->constant_pool));
script->flags = flags;
script->n_registers = n_registers;
script->n_arguments = n_args;
@@ -3059,9 +3059,11 @@ swfdec_action_print_constant_pool (guint action, const guint8 *data, guint len)
guint i;
GString *string;
SwfdecConstantPool *pool;
+ SwfdecBuffer *buffer;
/* FIXME: version */
- pool = swfdec_constant_pool_new_from_action (data, len, 6);
+ buffer = swfdec_buffer_new_static (data, len);
+ pool = swfdec_constant_pool_new (NULL, buffer, 6);
if (pool == NULL)
return g_strdup ("ConstantPool (invalid)");
string = g_string_new ("ConstantPool");
@@ -3070,6 +3072,8 @@ swfdec_action_print_constant_pool (guint action, const guint8 *data, guint len)
g_string_append (string, swfdec_constant_pool_get (pool, i));
g_string_append_printf (string, " (%u)", i);
}
+ swfdec_constant_pool_unref (pool);
+ swfdec_buffer_unref (buffer);
return g_string_free (string, FALSE);
}
diff --git a/swfdec/swfdec_constant_pool.c b/swfdec/swfdec_constant_pool.c
index 2834a63..487af45 100644
--- a/swfdec/swfdec_constant_pool.c
+++ b/swfdec/swfdec_constant_pool.c
@@ -22,80 +22,178 @@
#endif
#include "swfdec_constant_pool.h"
+#include "swfdec_bits.h"
#include "swfdec_debug.h"
struct _SwfdecConstantPool {
SwfdecAsContext * context; /* context we are attached to or NULL */
+ SwfdecBuffer * buffer; /* the buffer the strings were read from */
+ guint refcount; /* reference count */
guint n_strings; /* number of strings */
char * strings[1]; /* n_strings strings */
};
+/**
+ * swfdec_constant_pool_new:
+ * @context: a context to attach strings to or %NULL
+ * @buffer: buffer to read constant pool from
+ * @version: the Flash version to use when reading the strings
+ *
+ * Creates a new constant pool from the given @buffer. If the buffer is in the
+ * wrong format, %NULL is returned. If a @context was given, the strings are
+ * added to the context. This means the strings in the pool will be
+ * garbage-collected already. When using a non-%NULL @context, the pool does
+ * will not add a reference to the context. It is your responsibility to hold a
+ * reference to the context while you use the pool.
+ *
+ * Returns: a new constant pool or %NULL
+ **/
SwfdecConstantPool *
-swfdec_constant_pool_new_from_action (const guint8 *data, guint len, guint version)
+swfdec_constant_pool_new (SwfdecAsContext *context, SwfdecBuffer *buffer, guint version)
{
guint i, n;
+ gsize size;
SwfdecBits bits;
SwfdecConstantPool *pool;
- swfdec_bits_init_data (&bits, data, len);
+ g_return_val_if_fail (context == NULL || SWFDEC_IS_AS_CONTEXT (context), NULL);
+ g_return_val_if_fail (buffer != NULL, NULL);
+
+ /* try to find the pool in the context's cache */
+ if (context) {
+ pool = g_hash_table_lookup (context->constant_pools, buffer->data);
+ if (pool)
+ return swfdec_constant_pool_ref (pool);
+ }
+
+ swfdec_bits_init (&bits, buffer);
n = swfdec_bits_get_u16 (&bits);
if (n == 0)
return NULL;
- pool = g_malloc0 (sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *));
+ size = sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *);
+ pool = g_slice_alloc0 (size);
pool->n_strings = n;
for (i = 0; i < n; i++) {
pool->strings[i] = swfdec_bits_get_string (&bits, version);
if (pool->strings[i] == NULL) {
SWFDEC_ERROR ("not enough strings available");
- swfdec_constant_pool_free (pool);
+ g_slice_free1 (size, pool);
return NULL;
}
+ if (context)
+ pool->strings[i] = (char *) swfdec_as_context_give_string (context, pool->strings[i]);
}
if (swfdec_bits_left (&bits)) {
SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8);
}
+ pool->buffer = swfdec_buffer_ref (buffer);
+ pool->refcount = 1;
+ /* put pool into the context's cache */
+ if (context) {
+ pool->context = context;
+ g_hash_table_insert (context->constant_pools, buffer->data, pool);
+ }
+ return pool;
+}
+
+/**
+ * swfdec_constant_pool_ref:
+ * @pool: a constant pool
+ *
+ * Increases the constant pool's reference by one.
+ *
+ * Returns: the passed in @pool.
+ **/
+SwfdecConstantPool *
+swfdec_constant_pool_ref (SwfdecConstantPool *pool)
+{
+ g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
+
+ pool->refcount++;
+
return pool;
}
+/**
+ * swfdec_constant_pool_unref:
+ * @pool: the pool to unref
+ *
+ * Removes a reference from the pool. If no more references are left, the pool
+ * will be freed.
+ **/
void
-swfdec_constant_pool_attach_to_context (SwfdecConstantPool *pool, SwfdecAsContext *context)
+swfdec_constant_pool_unref (SwfdecConstantPool *pool)
{
- guint i;
+ g_return_if_fail (SWFDEC_IS_CONSTANT_POOL (pool));
+ g_return_if_fail (pool->refcount > 0);
- g_return_if_fail (pool != NULL);
- g_return_if_fail (pool->context == NULL);
- g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+ pool->refcount--;
+ if (pool->refcount)
+ return;
- pool->context = context;
- for (i = 0; i < pool->n_strings; i++) {
- pool->strings[i] = (char *) swfdec_as_context_give_string (context, pool->strings[i]);
+ if (pool->context) {
+ g_hash_table_remove (pool->context->constant_pools, pool->buffer->data);
+ } else {
+ guint i;
+ for (i = 0; i < pool->n_strings; i++) {
+ g_free (pool->strings[i]);
+ }
}
+ swfdec_buffer_unref (pool->buffer);
+ g_slice_free1 (sizeof (SwfdecConstantPool) + (pool->n_strings - 1) * sizeof (char *), pool);
}
+/**
+ * swfdec_constant_pool_size:
+ * @pool: a pool
+ *
+ * Queries the number of strings in this pool.
+ *
+ * Returns: The number of strings in this @pool
+ **/
guint
swfdec_constant_pool_size (SwfdecConstantPool *pool)
{
+ g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), 0);
+
return pool->n_strings;
}
+/**
+ * swfdec_constant_pool_get:
+ * @pool: a pool
+ * @i: index of the string to get
+ *
+ * Gets the requested string from the pool. The index must not excess the
+ * number of elements in the pool. If the constant pool was created with a
+ * context attached, the returned string will be garbage-collected already.
+ *
+ * Returns: the string at position @i
+ **/
const char *
swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
{
- g_assert (i < pool->n_strings);
+ g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
+ g_return_val_if_fail (i < pool->n_strings, NULL);
+
return pool->strings[i];
}
-void
-swfdec_constant_pool_free (SwfdecConstantPool *pool)
+/**
+ * swfdec_constant_pool_get_buffer:
+ * @pool: a constant pool
+ *
+ * Gets the buffer the pool was created from
+ *
+ * Returns: the buffer this pool was created from.
+ **/
+SwfdecBuffer *
+swfdec_constant_pool_get_buffer (SwfdecConstantPool *pool)
{
- if (pool->context == NULL) {
- guint i;
- for (i = 0; i < pool->n_strings; i++) {
- g_free (pool->strings[i]);
- }
- }
- g_free (pool);
+ g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
+
+ return pool->buffer;
}
diff --git a/swfdec/swfdec_constant_pool.h b/swfdec/swfdec_constant_pool.h
index 675fa00..3592dbc 100644
--- a/swfdec/swfdec_constant_pool.h
+++ b/swfdec/swfdec_constant_pool.h
@@ -21,26 +21,25 @@
#define _SWFDEC_CONSTANT_POOL_H_
#include <swfdec/swfdec.h>
-#include <swfdec/swfdec_as_types.h>
-#include <swfdec/swfdec_types.h>
-#include <swfdec/swfdec_bits.h>
G_BEGIN_DECLS
+#define SWFDEC_IS_CONSTANT_POOL(pool) ((pool) != NULL)
+
typedef struct _SwfdecConstantPool SwfdecConstantPool;
-SwfdecConstantPool *
- swfdec_constant_pool_new_from_action (const guint8 * data,
- guint len,
+SwfdecConstantPool * swfdec_constant_pool_new (SwfdecAsContext * context,
+ SwfdecBuffer * buffer,
guint version);
-void swfdec_constant_pool_free (SwfdecConstantPool * pool);
-guint swfdec_constant_pool_size (SwfdecConstantPool * pool);
-const char * swfdec_constant_pool_get (SwfdecConstantPool * pool,
+SwfdecConstantPool * swfdec_constant_pool_ref (SwfdecConstantPool * pool);
+void swfdec_constant_pool_unref (SwfdecConstantPool * pool);
+
+guint swfdec_constant_pool_size (SwfdecConstantPool * pool);
+const char * swfdec_constant_pool_get (SwfdecConstantPool * pool,
guint i);
-void swfdec_constant_pool_attach_to_context (SwfdecConstantPool * pool,
- SwfdecAsContext * context);
+SwfdecBuffer * swfdec_constant_pool_get_buffer (SwfdecConstantPool * pool);
G_END_DECLS
commit 5d0f9f19c37a8d6f7e0f54418b437bd393b3dd32
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 25 12:07:30 2008 +0100
split out constant pool handling into its own file
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 217b5c0..aacb161 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -64,6 +64,7 @@ libswfdec_source_files = \
swfdec_color_as.c \
swfdec_color_matrix_filter.c \
swfdec_color_transform.c \
+ swfdec_constant_pool.c \
swfdec_convolution_filter.c \
swfdec_debug.c \
swfdec_decoder.c \
@@ -231,6 +232,7 @@ noinst_HEADERS = \
swfdec_codec_audio.h \
swfdec_codec_video.h \
swfdec_color.h \
+ swfdec_constant_pool.h \
swfdec_debug.h \
swfdec_decoder.h \
swfdec_draw.h \
diff --git a/swfdec/swfdec_constant_pool.c b/swfdec/swfdec_constant_pool.c
new file mode 100644
index 0000000..2834a63
--- /dev/null
+++ b/swfdec/swfdec_constant_pool.c
@@ -0,0 +1,101 @@
+/* Swfdec
+ * Copyright (C) 2007 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 "swfdec_constant_pool.h"
+#include "swfdec_debug.h"
+
+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, guint version)
+{
+ guint i, n;
+ SwfdecBits bits;
+ SwfdecConstantPool *pool;
+
+ swfdec_bits_init_data (&bits, data, len);
+
+ n = swfdec_bits_get_u16 (&bits);
+ if (n == 0)
+ return NULL;
+
+ pool = g_malloc0 (sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *));
+ pool->n_strings = n;
+ for (i = 0; i < n; i++) {
+ pool->strings[i] = swfdec_bits_get_string (&bits, version);
+ if (pool->strings[i] == NULL) {
+ SWFDEC_ERROR ("not enough strings available");
+ swfdec_constant_pool_free (pool);
+ return NULL;
+ }
+ }
+ if (swfdec_bits_left (&bits)) {
+ SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8);
+ }
+ return pool;
+}
+
+void
+swfdec_constant_pool_attach_to_context (SwfdecConstantPool *pool, SwfdecAsContext *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));
+
+ 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->n_strings;
+}
+
+const char *
+swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
+{
+ g_assert (i < pool->n_strings);
+ return pool->strings[i];
+}
+
+void
+swfdec_constant_pool_free (SwfdecConstantPool *pool)
+{
+ if (pool->context == NULL) {
+ guint i;
+ for (i = 0; i < pool->n_strings; i++) {
+ g_free (pool->strings[i]);
+ }
+ }
+ g_free (pool);
+}
+
diff --git a/swfdec/swfdec_constant_pool.h b/swfdec/swfdec_constant_pool.h
new file mode 100644
index 0000000..675fa00
--- /dev/null
+++ b/swfdec/swfdec_constant_pool.h
@@ -0,0 +1,48 @@
+/* Swfdec
+ * Copyright (C) 2007 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
+ */
+
+#ifndef _SWFDEC_CONSTANT_POOL_H_
+#define _SWFDEC_CONSTANT_POOL_H_
+
+#include <swfdec/swfdec.h>
+#include <swfdec/swfdec_as_types.h>
+#include <swfdec/swfdec_types.h>
+#include <swfdec/swfdec_bits.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _SwfdecConstantPool SwfdecConstantPool;
+
+
+SwfdecConstantPool *
+ 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,
+ guint i);
+void swfdec_constant_pool_attach_to_context (SwfdecConstantPool * pool,
+ SwfdecAsContext * context);
+
+
+G_END_DECLS
+
+#endif
diff --git a/swfdec/swfdec_script.c b/swfdec/swfdec_script.c
index 66eeed0..d96b065 100644
--- a/swfdec/swfdec_script.c
+++ b/swfdec/swfdec_script.c
@@ -40,83 +40,6 @@
* but usually just causes a lot of spam. */
//#define SWFDEC_WARN_MISSING_PROPERTIES
-/*** 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, guint version)
-{
- guint i, n;
- SwfdecBits bits;
- SwfdecConstantPool *pool;
-
- swfdec_bits_init_data (&bits, data, len);
-
- n = swfdec_bits_get_u16 (&bits);
- if (n == 0)
- return NULL;
-
- pool = g_malloc0 (sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *));
- pool->n_strings = n;
- for (i = 0; i < n; i++) {
- pool->strings[i] = swfdec_bits_get_string (&bits, version);
- if (pool->strings[i] == NULL) {
- SWFDEC_ERROR ("not enough strings available");
- swfdec_constant_pool_free (pool);
- return NULL;
- }
- }
- if (swfdec_bits_left (&bits)) {
- SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8);
- }
- return pool;
-}
-
-void
-swfdec_constant_pool_attach_to_context (SwfdecConstantPool *pool, SwfdecAsContext *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));
-
- 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->n_strings;
-}
-
-const char *
-swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
-{
- g_assert (i < pool->n_strings);
- return pool->strings[i];
-}
-
-void
-swfdec_constant_pool_free (SwfdecConstantPool *pool)
-{
- if (pool->context == NULL) {
- guint i;
- for (i = 0; i < pool->n_strings; i++) {
- g_free (pool->strings[i]);
- }
- }
- g_free (pool);
-}
-
/*** SUPPORT FUNCTIONS ***/
char *
diff --git a/swfdec/swfdec_script_internal.h b/swfdec/swfdec_script_internal.h
index 8dc4308..3546b3d 100644
--- a/swfdec/swfdec_script_internal.h
+++ b/swfdec/swfdec_script_internal.h
@@ -24,11 +24,11 @@
#include <swfdec/swfdec_as_types.h>
#include <swfdec/swfdec_types.h>
#include <swfdec/swfdec_bits.h>
+#include <swfdec/swfdec_constant_pool.h>
G_BEGIN_DECLS
typedef struct _SwfdecScriptArgument SwfdecScriptArgument;
-typedef struct _SwfdecConstantPool SwfdecConstantPool;
typedef enum {
SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
@@ -68,17 +68,6 @@ struct _SwfdecScriptArgument {
const char * swfdec_action_get_name (guint action);
guint swfdec_action_get_from_name (const char * name);
-SwfdecConstantPool *
- 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,
- guint i);
-void swfdec_constant_pool_attach_to_context (SwfdecConstantPool * pool,
- SwfdecAsContext * context);
-
SwfdecScript * swfdec_script_new_from_bits (SwfdecBits * bits,
const char * name,
guint version);
More information about the Swfdec-commits
mailing list