📄 swfdec_script.c
字号:
} } else if (((SwfdecScript *) cx->fp->swf)->version < 7) { if (isnan (r)) r = 0; } l = l / r; break; default: g_assert_not_reached (); return r; } return JS_NewNumberValue (cx, l, &cx->fp->sp[-1]);}static JSString *swfdec_action_to_string_5 (JSContext *cx, jsval val){ if (JSVAL_IS_VOID (val)) return cx->runtime->emptyString; return js_ValueToString (cx, val);}static JSBoolswfdec_action_add2_5 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval rval, lval; gboolean cond; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; if ((cond = JSVAL_IS_STRING (lval)) || JSVAL_IS_STRING (rval)) { JSString *str, *str2; if (cond) { str = JSVAL_TO_STRING (lval); if ((str2 = swfdec_action_to_string_5 (cx, rval)) == NULL) return JS_FALSE; } else { str2 = JSVAL_TO_STRING (rval); if ((str = swfdec_action_to_string_5 (cx, lval)) == NULL) return JS_FALSE; } str = js_ConcatStrings (cx, str, str2); if (!str) return JS_FALSE; cx->fp->sp--; cx->fp->sp[-1] = STRING_TO_JSVAL (str); } else { double d, d2; d = swfdec_value_to_number (cx, lval); d2 = swfdec_value_to_number (cx, rval); d += d2; cx->fp->sp--; return JS_NewNumberValue(cx, d, &cx->fp->sp[-1]); } return JS_TRUE;}static JSBoolswfdec_action_add2_7 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval rval, lval; gboolean cond; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; if ((cond = JSVAL_IS_STRING (lval)) || JSVAL_IS_STRING (rval)) { JSString *str, *str2; if (cond) { str = JSVAL_TO_STRING (lval); if ((str2 = js_ValueToString (cx, rval)) == NULL) return JS_FALSE; } else { str2 = JSVAL_TO_STRING (rval); if ((str = js_ValueToString (cx, lval)) == NULL) return JS_FALSE; } str = js_ConcatStrings (cx, str, str2); if (!str) return JS_FALSE; cx->fp->sp--; cx->fp->sp[-1] = STRING_TO_JSVAL (str); } else { double d, d2; if (!swfdec_value_to_number_7 (cx, lval, &d) || !swfdec_value_to_number_7 (cx, rval, &d2)) return JS_FALSE; d += d2; cx->fp->sp--; return JS_NewNumberValue(cx, d, &cx->fp->sp[-1]); } return JS_TRUE;}static JSBoolswfdec_action_get_member (JSContext *cx, guint action, const guint8 *data, guint len){ const char *s; jsval o; s = swfdec_js_to_string (cx, cx->fp->sp[-1]); if (s == NULL) return JS_FALSE; o = cx->fp->sp[-2]; if (JSVAL_IS_OBJECT (o) && !JSVAL_IS_NULL (o)) { if (!JS_GetProperty (cx, JSVAL_TO_OBJECT (o), s, &cx->fp->sp[-2])) return JS_FALSE;#ifdef SWFDEC_WARN_MISSING_PROPERTIES if (cx->fp->sp[-2] == JSVAL_VOID) { const JSClass *clasp = JS_GetClass (JSVAL_TO_OBJECT (o)); if (clasp != &js_ObjectClass) { SWFDEC_WARNING ("no variable named %s:%s", clasp->name, s); } }#endif } else { cx->fp->sp[-2] = JSVAL_VOID; } cx->fp->sp--; return JS_TRUE;}static JSBoolswfdec_action_set_member (JSContext *cx, guint action, const guint8 *data, guint len){ const char *s; s = swfdec_js_to_string (cx, cx->fp->sp[-2]); if (s == NULL) return JS_FALSE; if (JSVAL_IS_OBJECT (cx->fp->sp[-3]) && !JSVAL_IS_NULL (cx->fp->sp[-3])) { if (!JS_SetProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[-3]), s, &cx->fp->sp[-1])) return JS_FALSE; } cx->fp->sp -= 3; return JS_TRUE;}static JSBoolswfdec_action_new_comparison_6 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval lval, rval; double d, d2; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; cx->fp->sp--; d = swfdec_value_to_number (cx, lval); d2 = swfdec_value_to_number (cx, rval); if (action == 0x48) cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d < d2); else cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d > d2); return JS_TRUE;}static JSBoolswfdec_action_new_comparison_7 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval lval, rval; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; cx->fp->sp--; if (JSVAL_IS_VOID (rval) || JSVAL_IS_VOID (lval)) { cx->fp->sp[-1] = JSVAL_VOID; } else if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) { int comp = JS_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)); cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? comp < 0 : comp > 0); } else { double d, d2; if (!JS_ValueToNumber(cx, lval, &d) || !JS_ValueToNumber(cx, rval, &d2)) return JS_FALSE; cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (action == 0x48 ? d < d2 : d > d2); } return JS_TRUE;}static JSBoolswfdec_action_not_4 (JSContext *cx, guint action, const guint8 *data, guint len){ double d; d = swfdec_value_to_number (cx, cx->fp->sp[-1]); cx->fp->sp[-1] = INT_TO_JSVAL (d == 0 ? 1 : 0); return JS_TRUE;}static JSBoolswfdec_action_not_5 (JSContext *cx, guint action, const guint8 *data, guint len){ double d; d = swfdec_value_to_number (cx, cx->fp->sp[-1]); cx->fp->sp[-1] = d == 0 ? JSVAL_TRUE : JSVAL_FALSE; return JS_TRUE;}static JSBoolswfdec_action_jump (JSContext *cx, guint action, const guint8 *data, guint len){ if (len != 2) { SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len); return JS_FALSE; } cx->fp->pc += 5 + GINT16_FROM_LE (*((gint16*) data)); return JS_TRUE;}static JSBoolswfdec_action_if (JSContext *cx, guint action, const guint8 *data, guint len){ double d; if (len != 2) { SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len); return JS_FALSE; } d = swfdec_value_to_number (cx, cx->fp->sp[-1]); cx->fp->sp--; if (d != 0) cx->fp->pc += 5 + GINT16_FROM_LE (*((gint16*) data)); return JS_TRUE;}static JSBoolswfdec_action_decrement (JSContext *cx, guint action, const guint8 *data, guint len){ double d; d = swfdec_value_to_number (cx, cx->fp->sp[-1]); d--; return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_increment (JSContext *cx, guint action, const guint8 *data, guint len){ double d; d = swfdec_value_to_number (cx, cx->fp->sp[-1]); d++; return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_get_url (JSContext *cx, guint action, const guint8 *data, guint len){ SwfdecMovie *movie; 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"); } movie = swfdec_action_get_target (cx); if (movie) swfdec_root_movie_load (SWFDEC_ROOT_MOVIE (movie->root), url, target); else SWFDEC_WARNING ("no movie to load"); return JS_TRUE;}static JSBoolswfdec_action_get_url2 (JSContext *cx, guint action, const guint8 *data, guint len){ const char *target, *url; guint method; SwfdecMovie *movie; if (len != 1) { SWFDEC_ERROR ("GetURL2 requires 1 byte of data, not %u", len); return JS_FALSE; } target = swfdec_js_to_string (cx, cx->fp->sp[-1]); url = swfdec_js_to_string (cx, cx->fp->sp[-2]); if (target == NULL || url == NULL) return JS_FALSE; 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"); } if (data[0] & 2) { SWFDEC_ERROR ("FIXME: implement LoadTarget"); } if (data[0] & 1) { SWFDEC_ERROR ("FIXME: implement LoadVariables"); } movie = swfdec_action_get_target (cx); if (movie) swfdec_root_movie_load (SWFDEC_ROOT_MOVIE (movie->root), url, target); else SWFDEC_WARNING ("no movie to load"); cx->fp->sp -= 2; return JS_TRUE;}static JSBoolswfdec_action_string_add (JSContext *cx, guint action, const guint8 *data, guint len){ JSString *lval, *rval; rval = JS_ValueToString (cx, cx->fp->sp[-1]); lval = JS_ValueToString (cx, cx->fp->sp[-2]); if (lval == NULL || rval == NULL) return FALSE; lval = JS_ConcatStrings (cx, lval, rval); if (lval == NULL) return FALSE; cx->fp->sp--; cx->fp->sp[-1] = STRING_TO_JSVAL (lval); return JS_TRUE;}static JSBoolswfdec_action_push_duplicate (JSContext *cx, guint action, const guint8 *data, guint len){ cx->fp->sp++; cx->fp->sp[-1] = cx->fp->sp[-2]; return JS_TRUE;}static JSBoolswfdec_action_random_number (JSContext *cx, guint action, const guint8 *data, guint len){ gint32 max, result; if (!JS_ValueToECMAInt32 (cx, cx->fp->sp[-1], &max)) return JS_FALSE; if (max <= 0) result = 0; else result = g_random_int_range (0, max); return JS_NewNumberValue(cx, result, &cx->fp->sp[-1]);}static JSBoolswfdec_action_old_compare (JSContext *cx, guint action, const guint8 *data, guint len){ jsval rval, lval; double l, r; JSBool cond; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; l = swfdec_value_to_number (cx, lval); r = swfdec_value_to_number (cx, rval); switch (action) { case 0x0e: cond = l == r; break; case 0x0f: cond = l < r; break; default: g_assert_not_reached (); return JS_FALSE; } cx->fp->sp--; if (((SwfdecScript *) cx->fp->swf)->version < 5) { cx->fp->sp[-1] = INT_TO_JSVAL (cond ? 1 : 0); } else { cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond); } return JS_TRUE;}static JSBoolswfdec_action_equals2 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval rval, lval; int ltag, rtag; JSBool cond; rval = cx->fp->sp[-1]; lval = cx->fp->sp[-2]; ltag = JSVAL_TAG(lval); rtag = JSVAL_TAG(rval); if (ltag == rtag) { if (ltag == JSVAL_STRING) { cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0; } else if (ltag == JSVAL_DOUBLE) { cond = *JSVAL_TO_DOUBLE(lval) == *JSVAL_TO_DOUBLE(rval); } else { cond = lval == rval; } } else { if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) { cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)); } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) { cond = JS_FALSE; } else { if (ltag == JSVAL_OBJECT) { if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(lval), 0, &lval)) return JS_FALSE; ltag = JSVAL_TAG(lval); } else if (rtag == JSVAL_OBJECT) { if (!OBJ_DEFAULT_VALUE (cx, JSVAL_TO_OBJECT(rval), 0, &rval)) return JS_FALSE; rtag = JSVAL_TAG(rval); } if (ltag == JSVAL_STRING && rtag == JSVAL_STRING) { cond = js_CompareStrings (JSVAL_TO_STRING (lval), JSVAL_TO_STRING (rval)) == 0; } else { double d, d2; if (!JS_ValueToNumber (cx, lval, &d) || !JS_ValueToNumber (cx, rval, &d2)) return JS_FALSE; cond = d == d2; } } } cx->fp->sp--; cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (cond); return JS_TRUE;}static JSBoolswfdec_action_do_set_target (JSContext *cx, JSObject *target){ JSObject *with; /* FIXME: this whole function stops working the moment it's used together * with With */ with = js_NewObject(cx, &js_WithClass, target, cx->fp->scopeChain); if (!with) return JS_FALSE; cx->fp->scopeChain = with; return JS_TRUE;}static JSBoolswfdec_action_do_unset_target (JSContext *cx){ if (JS_GetClass (cx->fp->scopeChain) != &js_WithClass) { SWFDEC_ERROR ("Cannot unset target: scope chain contains no with object"); return JS_TRUE; } cx->fp->scopeChain = JS_GetParent (cx, cx->fp->scopeChain); return JS_TRUE;}static JSBoolswfdec_action_set_target (JSContext *cx, guint action, const guint8 *data, guint len){ jsval target; if (!memchr (data, 0, len)) { SWFDEC_ERROR ("SetTarget action does not specify a string"); return JS_FALSE; } if (*data == '\0') return swfdec_action_do_unset_target (cx); target = swfdec_js_eval (cx, NULL, (const char *) data); if (!JSVAL_IS_OBJECT (target) || JSVAL_IS_NULL (target)) { SWFDEC_WARNING ("target is not an object"); return JS_TRUE; } return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (target));}static JSBoolswfdec_action_set_target2 (JSContext *cx, guint action, const guint8 *data, guint len){ jsval val; val = cx->fp->sp[-1]; cx->fp->sp--; if (!JSVAL_IS_OBJECT (val) || JSVAL_IS_NULL (val)) { SWFDEC_WARNING ("target is not an object"); return JS_TRUE; } return swfdec_action_do_set_target (cx, JSVAL_TO_OBJECT (val));}static JSBoolswfdec_action_start_drag (JSContext *cx, guint action, const guint8 *data, guint len){ JSStackFrame *fp = cx->fp; guint n_args = 1; if (!swfdec_script_ensure_stack (cx, 3))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -