Benjamin Otte
2007-Jan-18 06:06 UTC
[Swfdec] Branch 'interpreter' - 4 commits - libswfdec/js libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_image.c libswfdec/swfdec_script.c libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_tag.c
libswfdec/js/jsinterp.h | 1 libswfdec/swfdec_bits.c | 28 +++ libswfdec/swfdec_bits.h | 9 - libswfdec/swfdec_codec_screen.c | 2 libswfdec/swfdec_image.c | 98 ++++-------- libswfdec/swfdec_script.c | 315 ++++++++++++++++++++++++++++++++++++++-- libswfdec/swfdec_swf_decoder.c | 2 libswfdec/swfdec_tag.c | 23 -- 8 files changed, 371 insertions(+), 107 deletions(-) New commits: diff-tree 878ec656b0711cd19c11554d0617109a058af799 (from 8a1b77a18b9266e33c5e92ebeb0a8edbb7b6e643) Author: Benjamin Otte <otte@gnome.org> Date: Thu Jan 18 15:05:37 2007 +0100 implement GetVariable, fix a missing break in print_push and add better debugging diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index a27f037..49ad92f 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -29,6 +29,7 @@ #include <string.h> #include "swfdec_decoder.h" +#include "swfdec_js.h" #include "swfdec_movie.h" #include "swfdec_root_movie.h" @@ -305,6 +306,18 @@ swfdec_action_push (JSContext *cx, guint return swfdec_bits_left (&bits) ? JS_TRUE : JS_FALSE; } +static JSBool +swfdec_action_get_variable (JSContext *cx, guint action, const guint8 *data, guint len) +{ + const char *s; + + s = swfdec_js_to_string (cx, cx->fp->sp[-1]); + if (s == NULL) + return JS_FALSE; + cx->fp->sp[-1] = swfdec_js_eval (cx, cx->fp->scopeChain, s); + return JS_TRUE; +} + /*** PRINT FUNCTIONS ***/ static char * @@ -352,6 +365,7 @@ swfdec_action_print_push (guint action, break; case 7: /* 32bit int */ g_string_append_printf (string, "%u", swfdec_bits_get_u32 (&bits)); + break; case 8: /* 8bit ConstantPool address */ g_string_append_printf (string, "Pool %u", swfdec_bits_get_u8 (&bits)); break; @@ -450,7 +464,7 @@ static const SwfdecActionSpec actions[25 [0x15] = { "StringExtract", NULL }, [0x17] = { "Pop", NULL }, [0x18] = { "ToInteger", NULL }, - [0x1c] = { "GetVariable", NULL }, + [0x1c] = { "GetVariable", NULL, 1, 1, { NULL, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable, swfdec_action_get_variable } }, [0x1d] = { "SetVariable", NULL }, [0x20] = { "SetTarget2", NULL }, [0x21] = { "StringAdd", NULL }, @@ -604,8 +618,9 @@ validate_action (guint action, const gui /* ensure there's a function to execute this opcode, otherwise fail */ if (actions[action].exec[version] == NULL) { - SWFDEC_ERROR ("no opcode for %u %s", action, - actions[action].name ? actions[action].name : "Unknown"); + SWFDEC_ERROR ("no function for %u %s in v%u", action, + actions[action].name ? actions[action].name : "Unknown", + script->version); return FALSE; } /* we might want to do stuff here for certain actions */ diff-tree 8a1b77a18b9266e33c5e92ebeb0a8edbb7b6e643 (from c41b8582293535b64bf83c19843bd4eae8662e6f) Author: Benjamin Otte <otte@gnome.org> Date: Thu Jan 18 12:52:36 2007 +0100 implement ConstantPool and Push diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 5b01510..a27f037 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -27,18 +27,86 @@ #include "js/jscntxt.h" #include "js/jsinterp.h" -/*** SUPPORT FUNCTIONS ***/ - +#include <string.h> #include "swfdec_decoder.h" #include "swfdec_movie.h" #include "swfdec_root_movie.h" +/*** CONSTANT POOLS ***/ + +typedef GPtrArray SwfdecConstantPool; + +static SwfdecConstantPool * +swfdec_constant_pool_new_from_action (const guint8 *data, guint len) +{ + guint8 *next; + guint i, n; + GPtrArray *pool; + + if (len < 2) { + SWFDEC_ERROR ("constant pool too small"); + return NULL; + } + n = GUINT16_FROM_LE (*((guint16*) data)); + data += 2; + len -= 2; + pool = g_ptr_array_sized_new (n); + g_ptr_array_set_size (pool, n); + for (i = 0; i < n; i++) { + next = memchr (data, 0, len); + if (next == NULL) { + SWFDEC_ERROR ("not enough strings available"); + g_ptr_array_free (pool, TRUE); + return NULL; + } + next++; + g_ptr_array_index (pool, i) = (gpointer) data; + len -= next - data; + data = next; + } + if (len != 0) { + SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", len); + } + return pool; +} + +static guint +swfdec_constant_pool_size (SwfdecConstantPool *pool) +{ + return pool->len; +} + +static const char * +swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i) +{ + g_assert (i < pool->len); + return g_ptr_array_index (pool, i); +} + +static void +swfdec_constant_pool_free (SwfdecConstantPool *pool) +{ + g_ptr_array_free (pool, TRUE); +} + +/*** SUPPORT FUNCTIONS ***/ + static SwfdecMovie * swfdec_action_get_target (JSContext *cx) { return swfdec_scriptable_from_jsval (cx, OBJECT_TO_JSVAL (cx->fp->scopeChain), SWFDEC_TYPE_MOVIE); } +static JSBool +swfdec_action_push_string (JSContext *cx, const char *s) +{ + JSString *string = JS_NewStringCopyZ (cx, s); + if (string == NULL) + return JS_FALSE; + *cx->fp->sp++ = STRING_TO_JSVAL (string); + return JS_TRUE; +} + /*** ALL THE ACTION IS HERE ***/ static JSBool @@ -130,9 +198,194 @@ swfdec_action_wait_for_frame (JSContext return JS_TRUE; } +static JSBool +swfdec_action_constant_pool (JSContext *cx, guint action, const guint8 *data, guint len) +{ + SwfdecConstantPool *pool; + + pool = swfdec_constant_pool_new_from_action (data, len); + if (pool == NULL) + return JS_FALSE; + if (cx->fp->constant_pool) + swfdec_constant_pool_free (cx->fp->constant_pool); + cx->fp->constant_pool = pool; + return JS_TRUE; +} + +static JSBool +swfdec_action_push (JSContext *cx, guint stackspace, const guint8 *data, guint len) +{ + /* FIXME: supply API for this */ + SwfdecBits bits; + + swfdec_bits_init_data (&bits, data, len); + while (swfdec_bits_left (&bits) && stackspace-- > 0) { + guint type = swfdec_bits_get_u8 (&bits); + SWFDEC_LOG ("push type %u", type); + switch (type) { + case 0: /* string */ + { + const char *s = swfdec_bits_skip_string (&bits); + if (!swfdec_action_push_string (cx, s)) + return JS_FALSE; + break; + } + case 1: /* float */ + { + double d = swfdec_bits_get_float (&bits); + if (!JS_NewDoubleValue (cx, d, cx->fp->sp)) + return JS_FALSE; + cx->fp->sp++; + break; + } + case 2: /* null */ + *cx->fp->sp++ = JSVAL_NULL; + break; + case 3: /* undefined */ + *cx->fp->sp++ = JSVAL_VOID; + break; + case 5: /* boolean */ + *cx->fp->sp++ = swfdec_bits_get_u8 (&bits) ? JSVAL_TRUE : JSVAL_FALSE; + break; + case 6: /* double */ + { + double d = swfdec_bits_get_float (&bits); + if (!JS_NewDoubleValue (cx, d, cx->fp->sp)) + return JS_FALSE; + cx->fp->sp++; + break; + } + case 7: /* 32bit int */ + { + /* FIXME: spec says U32, do they mean this? */ + guint i = swfdec_bits_get_u32 (&bits); + *cx->fp->sp++ = INT_TO_JSVAL (i); + break; + } + case 8: /* 8bit ConstantPool address */ + { + guint i = swfdec_bits_get_u8 (&bits); + SwfdecConstantPool *pool = cx->fp->constant_pool; + if (pool == NULL) { + SWFDEC_ERROR ("no constant pool to push from"); + return JS_FALSE; + } + if (i >= swfdec_constant_pool_size (pool)) { + SWFDEC_ERROR ("constant pool index %u too high - only %u elements", + i, swfdec_constant_pool_size (pool)); + return JS_FALSE; + } + if (!swfdec_action_push_string (cx, swfdec_constant_pool_get (pool, i))) + return JS_FALSE; + break; + } + case 9: /* 16bit ConstantPool address */ + { + guint i = swfdec_bits_get_u16 (&bits); + SwfdecConstantPool *pool = cx->fp->constant_pool; + if (pool == NULL) { + SWFDEC_ERROR ("no constant pool to push from"); + return JS_FALSE; + } + if (i >= swfdec_constant_pool_size (pool)) { + SWFDEC_ERROR ("constant pool index %u too high - only %u elements", + i, swfdec_constant_pool_size (pool)); + return JS_FALSE; + } + if (!swfdec_action_push_string (cx, swfdec_constant_pool_get (pool, i))) + return JS_FALSE; + break; + } + case 4: /* register */ + default: + SWFDEC_ERROR ("Push: type %u not implemented", type); + return JS_FALSE; + } + } + return swfdec_bits_left (&bits) ? JS_TRUE : JS_FALSE; +} + /*** PRINT FUNCTIONS ***/ static char * +swfdec_action_print_push (guint action, const guint8 *data, guint len) +{ + gboolean first = TRUE; + SwfdecBits bits; + GString *string = g_string_new ("Push"); + + swfdec_bits_init_data (&bits, data, len); + while (swfdec_bits_left (&bits)) { + guint type = swfdec_bits_get_u8 (&bits); + if (first) + g_string_append (string, " "); + else + g_string_append (string, ", "); + first = FALSE; + switch (type) { + case 0: /* string */ + { + const char *s = swfdec_bits_skip_string (&bits); + if (!s) { + g_string_free (string, TRUE); + return NULL; + } + g_string_append_c (string, '"'); + g_string_append (string, s); + g_string_append_c (string, '"'); + break; + } + case 1: /* float */ + g_string_append_printf (string, "%g", swfdec_bits_get_float (&bits)); + break; + case 2: /* null */ + g_string_append (string, "null"); + break; + case 3: /* undefined */ + g_string_append (string, "void"); + break; + case 5: /* boolean */ + g_string_append (string, swfdec_bits_get_u8 (&bits) ? "True" : "False"); + break; + case 6: /* double */ + g_string_append_printf (string, "%g", swfdec_bits_get_double (&bits)); + break; + case 7: /* 32bit int */ + g_string_append_printf (string, "%u", swfdec_bits_get_u32 (&bits)); + case 8: /* 8bit ConstantPool address */ + g_string_append_printf (string, "Pool %u", swfdec_bits_get_u8 (&bits)); + break; + case 9: /* 16bit ConstantPool address */ + g_string_append_printf (string, "Pool %u", swfdec_bits_get_u16 (&bits)); + break; + case 4: /* register */ + default: + SWFDEC_ERROR ("Push: type %u not implemented", type); + return JS_FALSE; + } + } + return g_string_free (string, FALSE); +} + +static char * +swfdec_action_print_constant_pool (guint action, const guint8 *data, guint len) +{ + guint i; + GString *string; + SwfdecConstantPool *pool; + + pool = swfdec_constant_pool_new_from_action (data, len); + if (pool == NULL) + return JS_FALSE; + string = g_string_new ("ConstantPool"); + for (i = 0; i < swfdec_constant_pool_size (pool); i++) { + g_string_append (string, i ? ", " : " "); + g_string_append (string, swfdec_constant_pool_get (pool, i)); + } + return g_string_free (string, FALSE); +} + +static char * swfdec_action_print_goto_frame (guint action, const guint8 *data, guint len) { guint frame; @@ -162,13 +415,14 @@ swfdec_action_print_wait_for_frame (guin /* defines minimum and maximum versions for which we have seperate scripts */ #define MINSCRIPTVERSION 3 #define MAXSCRIPTVERSION 7 +#define EXTRACT_VERSION(v) MAX ((v) - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION) typedef JSBool (* SwfdecActionExec) (JSContext *cx, guint action, const guint8 *data, guint len); typedef struct { const char * name; /* name identifying the action */ char * (* print) (guint action, const guint8 *data, guint len); int remove; /* values removed from stack or -1 for dynamic */ - guint add; /* values added to the stack */ + int add; /* values added to the stack or -1 for dynamic */ SwfdecActionExec exec[MAXSCRIPTVERSION - MINSCRIPTVERSION + 1]; /* array is for version 3, 4, 5, 6, 7+ */ } SwfdecActionSpec; @@ -270,7 +524,7 @@ static const SwfdecActionSpec actions[25 [0x83] = { "GetURL", NULL }, /* version 5 */ [0x87] = { "StoreRegister", NULL }, - [0x88] = { "ConstantPool", NULL }, + [0x88] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } }, /* version 3 */ [0x8a] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } }, [0x8b] = { "SetTarget", NULL }, @@ -283,7 +537,7 @@ static const SwfdecActionSpec actions[25 /* version 5 */ [0x94] = { "With", NULL }, /* version 4 */ - [0x96] = { "Push", NULL }, + [0x96] = { "Push", swfdec_action_print_push, 0, -1, { NULL, swfdec_action_push, swfdec_action_push, swfdec_action_push, swfdec_action_push } }, [0x99] = { "Jump", NULL }, [0x9a] = { "GetURL2", NULL }, /* version 5 */ @@ -320,7 +574,7 @@ static gboolean swfdec_script_foreach (SwfdecBits *bits, SwfdecScriptForeachFunc func, gpointer user_data) { guint action, len; - guint8 *data; + const guint8 *data; while ((action = swfdec_bits_get_u8 (bits))) { if (action & 0x80) { @@ -343,10 +597,19 @@ swfdec_script_foreach (SwfdecBits *bits, /*** PUBLIC API ***/ static gboolean -validate_action (guint action, const guint8 *data, guint len, gpointer script) +validate_action (guint action, const guint8 *data, guint len, gpointer scriptp) { + SwfdecScript *script = scriptp; + int version = EXTRACT_VERSION (script->version); + + /* ensure there's a function to execute this opcode, otherwise fail */ + if (actions[action].exec[version] == NULL) { + SWFDEC_ERROR ("no opcode for %u %s", action, + actions[action].name ? actions[action].name : "Unknown"); + return FALSE; + } /* we might want to do stuff here for certain actions */ -#if 0 +#if 1 { char *foo = swfdec_script_print_action (action, data, len); if (foo == NULL) @@ -361,7 +624,7 @@ SwfdecScript * swfdec_script_new (SwfdecBits *bits, const char *name, unsigned int version) { SwfdecScript *script; - guchar *start; + const guchar *start; g_return_val_if_fail (bits != NULL, NULL); if (version < MINSCRIPTVERSION) { @@ -442,7 +705,7 @@ swfdec_script_interpret (SwfdecScript *s /* set up general stuff */ swfdec_script_ref (script); - version = MAX (script->version - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION); + version = EXTRACT_VERSION (script->version); *rval = JSVAL_VOID; fp = cx->fp; /* set up the script */ @@ -506,9 +769,13 @@ swfdec_script_interpret (SwfdecScript *s spec->name, spec->remove, fp->sp - fp->spbase); goto internal_error; } - if (fp->sp + spec->add - MAX (spec->remove, 0) > endsp) { - SWFDEC_ERROR ("FIXME: implement stack expansion, we got an overflow"); - goto internal_error; + if (spec->add < 0) { + action = endsp - fp->sp; + } else { + if (fp->sp + spec->add - MAX (spec->remove, 0) > endsp) { + SWFDEC_ERROR ("FIXME: implement stack expansion, we got an overflow"); + goto internal_error; + } } ok = spec->exec[version] (cx, action, data, len); if (!ok) @@ -574,6 +841,7 @@ swfdec_script_execute (SwfdecScript *scr frame.varobj = obj; frame.fun = NULL; frame.swf = script; + frame.constant_pool = NULL; frame.thisp = obj; frame.argc = frame.nvars = 0; frame.argv = frame.vars = NULL; @@ -604,6 +872,10 @@ swfdec_script_execute (SwfdecScript *scr */ ok = swfdec_script_interpret (script, cx, &frame.rval); + /* FIXME: where to clean this up? */ + if (frame.constant_pool) + swfdec_constant_pool_free (frame.constant_pool); + cx->fp = oldfp; if (oldfp) { g_assert (cx->dormantFrameChain == oldfp); diff-tree c41b8582293535b64bf83c19843bd4eae8662e6f (from 539f1f3151a6deb4f231f3289d3c8c232eb21bc7) Author: Benjamin Otte <otte@gnome.org> Date: Thu Jan 18 12:51:56 2007 +0100 add the constant pool to the stack frame diff --git a/libswfdec/js/jsinterp.h b/libswfdec/js/jsinterp.h index b22166d..88bab68 100644 --- a/libswfdec/js/jsinterp.h +++ b/libswfdec/js/jsinterp.h @@ -56,6 +56,7 @@ struct JSStackFrame { JSObject *varobj; /* variables object, where vars go */ JSScript *script; /* script being interpreted or NULL */ void *swf; /* SwfdecScript being executed if script is NULL */ + void *constant_pool; /* constant pool used by SwfdecScript */ JSFunction *fun; /* function being called or null */ JSObject *thisp; /* "this" pointer if in method */ uintN argc; /* actual argument count */ diff-tree 539f1f3151a6deb4f231f3289d3c8c232eb21bc7 (from c3f0eaf5706a0d972132a0ea4fcaff5aa79ec122) Author: Benjamin Otte <otte@gnome.org> Date: Thu Jan 18 12:47:17 2007 +0100 implement swfdec_bits_init_from_data to use SwfdecBits without a buffer Also make bits.ptr and bits.end const variables. This required cleaning up lots of old code that still accessed SwfdecBits directly I bet there were a lot of security issues there ;) diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c index f9f2749..72cc3df 100644 --- a/libswfdec/swfdec_bits.c +++ b/libswfdec/swfdec_bits.c @@ -43,6 +43,27 @@ swfdec_bits_init (SwfdecBits *bits, Swfd bits->end = buffer->data + buffer->length; } +/** + * swfdec_bits_init_data: + * @bits: the #SwfdecBits to initialize + * @data: data to initialize with + * @len: length of the data + * + * Initializes @bits for use with the given @data. All operations on @bits will + * return copies of the data, so after use, you can free the supplied data. + **/ +void +swfdec_bits_init_data (SwfdecBits *bits, const guint8 *data, guint len) +{ + g_return_if_fail (bits != NULL); + g_return_if_fail (data != NULL); + + bits->buffer = NULL; + bits->ptr = data; + bits->idx = 0; + bits->end = bits->ptr + len; +} + unsigned int swfdec_bits_left (SwfdecBits *b) { @@ -557,7 +578,12 @@ swfdec_bits_get_buffer (SwfdecBits *bits if (len == 0) return NULL; } - buffer = swfdec_buffer_new_subbuffer (bits->buffer, bits->ptr - bits->buffer->data, len); + if (bits->buffer) { + buffer = swfdec_buffer_new_subbuffer (bits->buffer, bits->ptr - bits->buffer->data, len); + } else { + buffer = swfdec_buffer_new_and_alloc (len); + memcpy (buffer->data, bits->ptr, len); + } bits->ptr += len; return buffer; } diff --git a/libswfdec/swfdec_bits.h b/libswfdec/swfdec_bits.h index 86440f7..08ae1d8 100644 --- a/libswfdec/swfdec_bits.h +++ b/libswfdec/swfdec_bits.h @@ -32,13 +32,14 @@ typedef struct _SwfdecBits SwfdecBits; struct _SwfdecBits { - SwfdecBuffer *buffer; - unsigned char *ptr; - unsigned int idx; - unsigned char *end; + SwfdecBuffer * buffer; /* buffer data is taken from or NULL */ + const unsigned char * ptr; /* current location to read from */ + unsigned int idx; /* bits already read from ptr */ + const unsigned char * end; /* pointer after last byte */ }; void swfdec_bits_init (SwfdecBits *bits, SwfdecBuffer *buffer); +void swfdec_bits_init_data (SwfdecBits *bits, const guint8 *data, guint len); unsigned int swfdec_bits_left (SwfdecBits *b); int swfdec_bits_getbit (SwfdecBits * b); unsigned int swfdec_bits_getbits (SwfdecBits * b, unsigned int n); diff --git a/libswfdec/swfdec_codec_screen.c b/libswfdec/swfdec_codec_screen.c index 305db49..de21d21 100644 --- a/libswfdec/swfdec_codec_screen.c +++ b/libswfdec/swfdec_codec_screen.c @@ -140,7 +140,7 @@ swfdec_codec_screen_decode (gpointer cod if (inflateReset(&screen->z) != Z_OK) { SWFDEC_ERROR ("error resetting zlib decoder: %s", screen->z.msg); } - screen->z.next_in = bits.ptr; + screen->z.next_in = (void *) bits.ptr; if (swfdec_bits_skip_bytes (&bits, size) != size) { SWFDEC_ERROR ("not enough bytes available"); return NULL; diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c index 6c2dcae..c9df0de 100644 --- a/libswfdec/swfdec_image.c +++ b/libswfdec/swfdec_image.c @@ -99,46 +99,30 @@ zfree (void *opaque, void *addr) g_free (addr); } -static void * -lossless (void *zptr, int zlen, int *plen) +static guint8 * +lossless (const guint8 *zptr, int zlen, int len) { - void *data; - int len; - z_stream *z; + guint8 *data; + z_stream z = { NULL, }; int ret; - z = g_new0 (z_stream, 1); - z->zalloc = zalloc; - z->zfree = zfree; - z->opaque = NULL; - - z->next_in = zptr; - z->avail_in = zlen; - - data = NULL; - len = 0; - ret = inflateInit (z); - while (z->avail_in > 0) { - if (z->avail_out == 0) { - len += 1024; - data = g_realloc (data, len); - z->next_out = data + z->total_out; - z->avail_out += 1024; - } - ret = inflate (z, Z_SYNC_FLUSH); - if (ret != Z_OK) - break; - } + z.zalloc = zalloc; + z.zfree = zfree; + z.opaque = NULL; + + data = g_malloc (len); + z.next_in = (Bytef *) zptr; + z.avail_in = zlen; + z.next_out = data; + z.avail_out = len; + + ret = inflateInit (&z); + ret = inflate (&z, Z_SYNC_FLUSH); if (ret != Z_STREAM_END) { SWFDEC_WARNING ("lossless: ret == %d", ret); } + inflateEnd (&z); - if (plen) - (*plen) = z->total_out; - - inflateEnd (z); - - g_free (z); return data; } @@ -278,11 +262,8 @@ int tag_func_define_bits_jpeg_3 (SwfdecSwfDecoder * s) { SwfdecBits *bits = &s->b; - int id; + guint id; SwfdecImage *image; - unsigned char *endptr; - - endptr = bits->ptr + bits->buffer->length; id = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" id = %d", id); @@ -292,9 +273,7 @@ tag_func_define_bits_jpeg_3 (SwfdecSwfDe return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_JPEG3; - image->raw_data = swfdec_buffer_ref (bits->buffer); - - bits->ptr += bits->buffer->length - 2; + image->raw_data = swfdec_bits_get_buffer (bits, -1); return SWFDEC_STATUS_OK; } @@ -306,21 +285,20 @@ swfdec_image_jpeg3_load (SwfdecImage *im unsigned char *image_data; unsigned char *alpha_data; SwfdecBits bits; - int len; + SwfdecBuffer *buffer; int jpeg_length; - bits.buffer = image->raw_data; - bits.ptr = image->raw_data->data; - bits.idx = 0; - bits.end = bits.ptr + image->raw_data->length; - - bits.ptr += 2; + swfdec_bits_init (&bits, image->raw_data); jpeg_length = swfdec_bits_get_u32 (&bits); + buffer = swfdec_bits_get_buffer (&bits, jpeg_length); + if (buffer == NULL) + return; dec = jpeg_rgb_decoder_new (); - jpeg_rgb_decoder_addbits (dec, bits.ptr, jpeg_length); + jpeg_rgb_decoder_addbits (dec, buffer->data, buffer->length); + swfdec_buffer_unref (buffer); jpeg_rgb_decoder_parse (dec); jpeg_rgb_decoder_get_image_size (dec, &image->width, &image->height); if (image->width == 0 || image->height == 0) { @@ -332,9 +310,9 @@ swfdec_image_jpeg3_load (SwfdecImage *im &image->rowstride, &image->width, &image->height); jpeg_rgb_decoder_free (dec); - bits.ptr += jpeg_length; - - alpha_data = lossless (bits.ptr, bits.end - bits.ptr, &len); + buffer = swfdec_bits_get_buffer (&bits, -1); + alpha_data = lossless (buffer->data, buffer->length, image->width * image->height); + swfdec_buffer_unref (buffer); merge_alpha (image, image_data, alpha_data); g_free (alpha_data); @@ -372,19 +350,12 @@ swfdec_image_lossless_load (SwfdecImage int format; int color_table_size; unsigned char *ptr; - int len; unsigned char *endptr; SwfdecBits bits; unsigned char *image_data = NULL; int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2); - bits.buffer = image->raw_data; - bits.ptr = image->raw_data->data; - bits.idx = 0; - bits.end = bits.ptr + image->raw_data->length; - endptr = bits.ptr + bits.buffer->length; - - bits.ptr += 2; + swfdec_bits_init (&bits, image->raw_data); format = swfdec_bits_get_u8 (&bits); SWFDEC_LOG (" format = %d", format); @@ -406,7 +377,7 @@ swfdec_image_lossless_load (SwfdecImage if (image->width == 0 || image->height == 0) return; swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); - ptr = lossless (bits.ptr, endptr - bits.ptr, &len); + ptr = lossless (bits.ptr, endptr - bits.ptr, image->width * image->height); bits.ptr = endptr; if (format == 3) { @@ -531,9 +502,8 @@ tag_func_define_bits_lossless (SwfdecSwf return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_LOSSLESS; - image->raw_data = swfdec_buffer_ref (bits->buffer); + image->raw_data = swfdec_bits_get_buffer (bits, -1); - bits->ptr += bits->buffer->length - 2; return SWFDEC_STATUS_OK; } @@ -552,9 +522,7 @@ tag_func_define_bits_lossless_2 (SwfdecS return SWFDEC_STATUS_OK; image->type = SWFDEC_IMAGE_TYPE_LOSSLESS2; - image->raw_data = swfdec_buffer_ref (bits->buffer); - - bits->ptr += bits->buffer->length - 2; + image->raw_data = swfdec_bits_get_buffer (bits, -1); return SWFDEC_STATUS_OK; } diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c index e7be205..a43c9ac 100644 --- a/libswfdec/swfdec_swf_decoder.c +++ b/libswfdec/swfdec_swf_decoder.c @@ -239,7 +239,7 @@ swfdec_swf_decoder_parse (SwfdecDecoder { SwfdecSwfDecoder *s = SWFDEC_SWF_DECODER (dec); int ret = SWFDEC_STATUS_OK; - unsigned char *endptr; + const unsigned char *endptr; SwfdecBuffer *buffer; s->b = s->parse; diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c index 4f57b1a..3896101 100644 --- a/libswfdec/swfdec_tag.c +++ b/libswfdec/swfdec_tag.c @@ -212,7 +212,6 @@ tag_func_define_sprite (SwfdecSwfDecoder s->parse_sprite = sprite; while (1) { - unsigned char *endptr; int x; int tag; guint tag_len; @@ -258,7 +257,7 @@ tag_func_define_sprite (SwfdecSwfDecoder SWFDEC_ERROR ("invalid tag %d %s during DefineSprite", tag, swfdec_swf_decoder_get_tag_name (tag)); } else { - endptr = parse.ptr + tag_len; + const unsigned char *endptr = parse.ptr + tag_len; ret = func (s); swfdec_bits_syncbits (bits); @@ -311,22 +310,11 @@ int tag_func_do_init_action (SwfdecSwfDecoder * s) { SwfdecBits *bits = &s->b; - int len; SwfdecBuffer *buffer; SwfdecCharacter *character; - unsigned char *endptr; - //int retcode = SWF_ERROR; - - endptr = bits->ptr + bits->buffer->length; character = swfdec_swf_decoder_get_character (s, swfdec_bits_get_u16 (bits)); - - len = bits->end - bits->ptr; - - buffer = swfdec_buffer_new_subbuffer (bits->buffer, - bits->ptr - bits->buffer->data, len); - - bits->ptr += len; + buffer = swfdec_bits_get_buffer (bits, -1); if (SWFDEC_IS_SPRITE (character)) { SWFDEC_WARNING ("init actions not implemented yet"); @@ -339,7 +327,6 @@ tag_func_do_init_action (SwfdecSwfDecode } swfdec_buffer_unref (buffer); - //return retcode; return SWFDEC_STATUS_OK; } @@ -389,11 +376,8 @@ tag_func_define_button_2 (SwfdecSwfDecod int flags; int offset; SwfdecButton *button; - unsigned char *endptr; char *script_name; - endptr = bits->ptr + bits->buffer->length; - id = swfdec_bits_get_u16 (bits); button = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_BUTTON); if (!button) @@ -476,11 +460,8 @@ tag_func_define_button (SwfdecSwfDecoder SwfdecBits *bits = &s->b; int id; SwfdecButton *button; - unsigned char *endptr; char *script_name; - endptr = bits->ptr + bits->buffer->length; - id = swfdec_bits_get_u16 (bits); button = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_BUTTON); if (!button)
Possibly Parallel Threads
- 109 commits - configure.ac libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_codec_screen.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h
- Branch 'as' - 9 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_stack.c libswfdec/swfdec_as_stack.h
- Branch 'as' - 4 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_interpret.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h
- Branch 'as' - 9 commits - libswfdec-gtk/swfdec_playback_alsa.c libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c
- Branch 'interpreter' - 8 commits - libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_js.c libswfdec/swfdec_js.h libswfdec/swfdec_script.c test/swfdec_out.c test/swfdec_out.h test/swfedit_tag.c test/swfedit_token.c test/swfedit_token.h