📄 swfdec_script.c
字号:
static JSBoolswfdec_action_store_register (JSContext *cx, guint action, const guint8 *data, guint len){ if (len != 1) { SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); return JS_FALSE; } if (!swfdec_action_has_register (cx, *data)) { SWFDEC_ERROR ("Cannot store into register %u, not enough registers", (guint) *data); return JS_FALSE; } cx->fp->vars[*data] = cx->fp->sp[-1]; return JS_TRUE;}static JSBoolswfdec_action_modulo_5 (JSContext *cx, guint action, const guint8 *data, guint len){ double x, y; x = swfdec_value_to_number (cx, cx->fp->sp[-1]); y = swfdec_value_to_number (cx, cx->fp->sp[-2]); cx->fp->sp--; errno = 0; x = fmod (x, y); if (errno != 0) { cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN); return JS_TRUE; } else { return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]); }}static JSBoolswfdec_action_modulo_7 (JSContext *cx, guint action, const guint8 *data, guint len){ double x, y; if (!swfdec_value_to_number_7 (cx, cx->fp->sp[-1], &x) || !swfdec_value_to_number_7 (cx, cx->fp->sp[-2], &y)) return JS_FALSE; cx->fp->sp--; errno = 0; x = fmod (x, y); if (errno != 0) { cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN); return JS_TRUE; } else { return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]); }}static JSBoolswfdec_action_swap (JSContext *cx, guint action, const guint8 *data, guint len){ jsval tmp = cx->fp->sp[-2]; cx->fp->sp[-2] = cx->fp->sp[-1]; cx->fp->sp[-1] = tmp; return JS_TRUE;}static JSBoolswfdec_action_to_number (JSContext *cx, guint action, const guint8 *data, guint len){ double d; if (!JS_ValueToNumber (cx, cx->fp->sp[-1], &d)) return JS_FALSE; return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_to_string (JSContext *cx, guint action, const guint8 *data, guint len){ JSString *s; s = JS_ValueToString(cx, cx->fp->sp[-1]); if (!s) return JS_FALSE; cx->fp->sp[-1] = STRING_TO_JSVAL (s); return JS_TRUE;}static JSBoolswfdec_action_type_of (JSContext *cx, guint action, const guint8 *data, guint len){ jsval val; const char *type; JSString *string; val = cx->fp->sp[-1]; if (JSVAL_IS_NUMBER (val)) { type = "number"; } else if (JSVAL_IS_BOOLEAN (val)) { type = "boolean"; } else if (JSVAL_IS_STRING (val)) { type = "string"; } else if (JSVAL_IS_VOID (val)) { type = "undefined"; } else if (JSVAL_IS_NULL (val)) { type = "null"; } else if (JSVAL_IS_OBJECT (val)) { JSObject *obj = JSVAL_TO_OBJECT (val); if (swfdec_js_is_movieclip (cx, obj)) { type = "movieclip"; } else if (JS_ObjectIsFunction (cx, obj)) { type = "function"; } else { type = "object"; } } else { g_assert_not_reached (); return JS_FALSE; } /* can't use InternString here because of case sensitivity issues */ string = JS_NewStringCopyZ (cx, type); if (string == NULL) return JS_FALSE; cx->fp->sp[-1] = STRING_TO_JSVAL (string); return JS_TRUE;}static JSBoolswfdec_action_get_time (JSContext *cx, guint action, const guint8 *data, guint len){ SwfdecPlayer *player = JS_GetContextPrivate (cx); *cx->fp->sp++ = INT_TO_JSVAL ((int) SWFDEC_TICKS_TO_MSECS (player->time)); return JS_TRUE;}static JSBoolswfdec_action_extends (JSContext *cx, guint action, const guint8 *data, guint len){ jsval superclass, subclass, proto; JSObject *prototype; superclass = cx->fp->sp[-1]; subclass = cx->fp->sp[-2]; cx->fp->sp -= 2; if (!JSVAL_IS_OBJECT (superclass) || superclass == JSVAL_NULL || !JSVAL_IS_OBJECT (subclass) || subclass == JSVAL_NULL) { SWFDEC_ERROR ("superclass or subclass aren't objects"); return JS_TRUE; } if (!JS_GetProperty (cx, JSVAL_TO_OBJECT (superclass), "prototype", &proto) || !JSVAL_IS_OBJECT (proto)) return JS_FALSE; prototype = JS_NewObject (cx, NULL, JSVAL_TO_OBJECT (proto), NULL); if (prototype == NULL) return JS_FALSE; proto = OBJECT_TO_JSVAL (prototype); if (!JS_SetProperty (cx, prototype, "__constructor__", &superclass) || !JS_SetProperty (cx, JSVAL_TO_OBJECT (subclass), "prototype", &proto)) return JS_FALSE; return JS_TRUE;}static JSBoolswfdec_action_enumerate2 (JSContext *cx, guint action, const guint8 *data, guint len){ JSObject *obj; JSIdArray *array; guint i; if (!JSVAL_IS_OBJECT (cx->fp->sp[-1]) || cx->fp->sp[-1] == JSVAL_NULL) { SWFDEC_ERROR ("Enumerate2 called without an object"); cx->fp->sp[-1] = JSVAL_NULL; return JS_TRUE; } obj = JSVAL_TO_OBJECT (cx->fp->sp[-1]); cx->fp->sp[-1] = JSVAL_NULL; array = JS_Enumerate (cx, obj); if (!array) return JS_FALSE; if ((guint) (cx->fp->spend - cx->fp->sp) < array->length) { SWFDEC_ERROR ("FIXME: not enough stack space, need %u, got %td", array->length, cx->fp->spend - cx->fp->sp); JS_DestroyIdArray (cx, array); return JS_FALSE; } for (i = 0; i < array->length; i++) { if (!JS_IdToValue (cx, array->vector[i], cx->fp->sp++)) { JS_DestroyIdArray (cx, array); return JS_FALSE; } } JS_DestroyIdArray (cx, array); return JS_TRUE;}static JSBoolswfdec_action_logical_5 (JSContext *cx, guint action, const guint8 *data, guint len){ JSBool l, r; l = swfdec_value_to_boolean_5 (cx, cx->fp->sp[-1]); r = swfdec_value_to_boolean_5 (cx, cx->fp->sp[-2]); cx->fp->sp--; if (action == 0x10) cx->fp->sp[-1] = l && r ? JSVAL_TRUE : JSVAL_FALSE; else cx->fp->sp[-1] = l || r ? JSVAL_TRUE : JSVAL_FALSE; return JS_TRUE;}static JSBoolswfdec_action_logical_7 (JSContext *cx, guint action, const guint8 *data, guint len){ JSBool l, r; l = swfdec_value_to_boolean_7 (cx, cx->fp->sp[-1]); r = swfdec_value_to_boolean_7 (cx, cx->fp->sp[-2]); cx->fp->sp--; if (action == 0x10) cx->fp->sp[-1] = l && r ? JSVAL_TRUE : JSVAL_FALSE; else cx->fp->sp[-1] = l || r ? JSVAL_TRUE : JSVAL_FALSE; return JS_TRUE;}/*** PRINT FUNCTIONS ***/static char *swfdec_action_print_store_register (guint action, const guint8 *data, guint len){ if (len != 1) { SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); return NULL; } return g_strdup_printf ("StoreRegister %u", (guint) *data);}static char *swfdec_action_print_set_target (guint action, const guint8 *data, guint len){ if (!memchr (data, 0, len)) { SWFDEC_ERROR ("SetTarget action does not specify a string"); return JS_FALSE; } return g_strconcat ("SetTarget ", data, NULL);}static char *swfdec_action_print_define_function (guint action, const guint8 *data, guint len){ SwfdecBits bits; GString *string; const char *function_name; guint i, n_args, size; gboolean v2 = (action == 0x8e); string = g_string_new (v2 ? "DefineFunction2 " : "DefineFunction "); swfdec_bits_init_data (&bits, data, len); function_name = swfdec_bits_get_string (&bits); if (function_name == NULL) { SWFDEC_ERROR ("could not parse function name"); g_string_free (string, TRUE); return NULL; } if (*function_name) { g_string_append (string, function_name); g_string_append_c (string, ' '); } n_args = swfdec_bits_get_u16 (&bits); g_string_append_c (string, '('); if (v2) { /* n_regs = */ swfdec_bits_get_u8 (&bits); /* flags = */ swfdec_bits_get_u16 (&bits); } for (i = 0; i < n_args; i++) { guint preload; const char *arg_name; if (v2) preload = swfdec_bits_get_u8 (&bits); else preload = 0; arg_name = swfdec_bits_get_string (&bits); if (preload == 0 && (arg_name == NULL || *arg_name == '\0')) { SWFDEC_ERROR ("empty argument name not allowed"); g_string_free (string, TRUE); return NULL; } if (i) g_string_append (string, ", "); if (preload) g_string_append_printf (string, "PRELOAD %u", preload); else g_string_append (string, arg_name); } g_string_append_c (string, ')'); size = swfdec_bits_get_u16 (&bits); g_string_append_printf (string, " %u", size); return g_string_free (string, FALSE);}static char *swfdec_action_print_get_url2 (guint action, const guint8 *data, guint len){ guint method; if (len != 1) { SWFDEC_ERROR ("GetURL2 requires 1 byte of data, not %u", len); return NULL; } method = data[0] >> 6; if (method == 3) { SWFDEC_ERROR ("GetURL method 3 invalid"); method = 0; } if (method) { SWFDEC_ERROR ("FIXME: implement encoding variables using %s", method == 1 ? "GET" : "POST"); } return g_strdup_printf ("GetURL2%s%s%s", method == 0 ? "" : (method == 1 ? " GET" : " POST"), data[0] & 2 ? " LoadTarget" : "", data[0] & 1 ? " LoadVariables" : "");}static char *swfdec_action_print_get_url (guint action, const guint8 *data, guint len){ SwfdecBits bits; const char *url, *target; swfdec_bits_init_data (&bits, data, len); url = swfdec_bits_skip_string (&bits); target = swfdec_bits_skip_string (&bits); if (swfdec_bits_left (&bits)) { SWFDEC_WARNING ("leftover bytes in GetURL action"); } return g_strdup_printf ("GetURL %s %s", url, target);}static char *swfdec_action_print_if (guint action, const guint8 *data, guint len){ if (len != 2) { SWFDEC_ERROR ("If action length invalid (is %u, should be 2", len); return NULL; } return g_strdup_printf ("If %d", GINT16_FROM_LE (*((gint16*) data)));}static char *swfdec_action_print_jump (guint action, const guint8 *data, guint len){ if (len != 2) { SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len); return NULL; } return g_strdup_printf ("Jump %d", GINT16_FROM_LE (*((gint16*) data)));}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 4: /* register */ g_string_append_printf (string, "Register %u", swfdec_bits_get_u8 (&bits)); 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, "%d", swfdec_bits_get_u32 (&bits)); break; 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; default: SWFDEC_ERROR ("Push: type %u not implemented", type); return JS_FALSE; } } return g_string_free (string, FALSE);}/* NB: constant pool actions are special in that they are called at init time */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)); g_string_append_printf (string, " (%u)", i); } return g_string_free (string, FALSE);}static char *swfdec_action_print_wait_for_frame2 (guint action, const guint8 *data, guint len){ if (len != 1) { SWFDEC_ERROR ("WaitForFrame2 needs a 1-byte data"); return NULL; } return g_strdup_printf ("WaitForFrame2 %u", (guint) *data);}static char *swfdec_action_print_goto_frame2 (guint action, const guint8 *data, guint len){ gboolean play, bias; SwfdecBits bits; swfdec_bits_init_data (&bits, data, len); if (swfdec_bits_getbits (&bits, 6)) { SWFDEC_WARNING ("reserved bits in GotoFrame2 aren't 0"); } bias = swfdec_bits_getbit (&bits); play = swfdec_bits_getbit (&bits); if (bias) { return g_strdup_printf ("GotoFrame2 %s +%u", play ? "play" : "stop", swfdec_bits_get_u16 (&bits)); } else { return g_strdup_printf ("GotoFrame2 %s", play ? "play" : "stop"); }}static char *swfdec_action_print_goto_frame (guint action, const guint8 *data, guint len){ guint frame; if (len != 2) return NULL; frame = GUINT16_FROM_LE (*((guint16 *) data)); return g_strdup_printf ("GotoFrame %u", frame);}static char *swfdec_action_print_goto_label (guint action, const guint8 *data, guint len){ if (!memchr (data, 0, len)) { SWFDEC_ERROR ("GotoLabel action does not specify a string"); return NULL; } return g_strdup_printf ("GotoLabel %s", data);}static
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -