OSDN Git Service

replaceActionString の実装
authoryoya <yoya@7c90b180-03d5-4157-b861-58a559ae9d1e>
Wed, 8 Jun 2011 11:25:34 +0000 (11:25 +0000)
committeryoya <yoya@7c90b180-03d5-4157-b861-58a559ae9d1e>
Wed, 8 Jun 2011 11:25:34 +0000 (11:25 +0000)
但し、バイトコードで push される文字列 (変数代入や関数へ渡す引数の文字列等)のみ対応
定数プールや getURL に渡す文字列は未実装。(TODO)

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/swfed/trunk@578 7c90b180-03d5-4157-b861-58a559ae9d1e

src/php_swfed.c
src/php_swfed.h
src/swf_action.c
src/swf_action.h
src/swf_object.c
src/swf_object.h
src/swf_tag.c
src/swf_tag.h
src/swf_tag_action.c
src/swf_tag_action.h

index 2492aae..f91394b 100644 (file)
@@ -92,6 +92,7 @@ zend_function_entry swfed_functions[] = {
     PHP_ME(swfed,  getActionData, NULL, 0)
     PHP_ME(swfed,  disasmActionData, NULL, 0)
     PHP_ME(swfed,  setActionVariables, NULL, 0)
+    PHP_ME(swfed,  replaceActionString, NULL, 0)
     PHP_ME(swfed,  replaceMovieClip, NULL, 0)
 
     PHP_ME(swfed,  setCompressLevel, NULL, 0)
@@ -1308,6 +1309,49 @@ PHP_METHOD(swfed, setActionVariables) {
     RETURN_TRUE;
 }
 
+PHP_METHOD(swfed, replaceActionString) {
+    zval *zid, *arr, **entry;
+    HashTable *arr_hash;
+    HashPosition    pos;
+    char            *str_key, *str_value;
+    uint            str_key_len, str_value_len;
+    ulong tmp;
+    char tmp_str[17];
+    int ret;
+    y_keyvalue_t *kv;
+    swf_object_t *swf = get_swf_object(getThis() TSRMLS_CC);
+    
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
+        RETURN_FALSE;
+    }
+    kv = y_keyvalue_open();
+
+    arr_hash = Z_ARRVAL_P(arr);
+    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
+    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &
+                                         pos) == SUCCESS) {
+        str_value = Z_STRVAL_PP(entry);
+        str_value_len = Z_STRLEN_PP(entry);
+        ret = zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &str_key, &
+                                           str_key_len, &tmp, 0, &pos);
+        switch (ret) {
+        case HASH_KEY_IS_STRING:
+            y_keyvalue_set(kv, str_key, str_key_len - 1, str_value, str_value_len);
+            break;
+        case HASH_KEY_IS_LONG:
+            snprintf(tmp_str, 17, "%ld\0", tmp);
+            y_keyvalue_set(kv, tmp_str, strlen(tmp_str), str_value, str_value_len);
+            break;
+        default:
+            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array keys invalid type(%d).", ret);
+        }
+        zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
+    }
+    swf_object_replace_action_string(swf, kv);
+    y_keyvalue_close(kv);
+    RETURN_TRUE;
+}
+
 PHP_METHOD(swfed, replaceMovieClip) {
     char *instance_name = NULL, *swf_data = NULL;
     int  instance_name_len = 0, swf_data_len = 0;
index 3149333..86769f3 100644 (file)
@@ -85,6 +85,7 @@ PHP_METHOD(swfed, replaceEditString);
 PHP_METHOD(swfed, getActionData);
 PHP_METHOD(swfed, disasmActionData);
 PHP_METHOD(swfed, setActionVariables);
+PHP_METHOD(swfed, replaceActionString);
 PHP_METHOD(swfed, replaceMovieClip);
 
 PHP_METHOD(swfed, setCompressLevel);
index 5e74ab0..2a785c8 100644 (file)
@@ -341,6 +341,47 @@ swf_action_data_print(unsigned char *action_data, unsigned short action_data_len
 }
 
 int
+swf_action_list_replace_string(swf_action_list_t *action_list, y_keyvalue_t *kv) {
+    swf_action_t *action;
+    for (action=action_list->head ; action ; action=action->next) {
+        if (action->action_id < 0x80) {
+           continue; // skip (no string)
+       }
+       switch(action->action_id) {
+         unsigned char *action_data;
+         unsigned char type;
+       case 0x83: // Get URL
+         // todo
+           break;
+       case 0x88: // ActionConstantPool
+         // todo
+           break;
+       case 0x96: // Push Data
+           action_data = action->action_data;
+           type = action_data[0] & 0xff;
+           if (type == 0x00) { // Type: String 
+               unsigned char *data = action_data + 1;
+               int data_len = action->action_length - 2;
+               unsigned char *value;
+               int value_len;
+               value = y_keyvalue_get(kv, data, data_len, &value_len);
+               if (value) {
+                   action_data = malloc(1 + value_len + 1);
+                   action_data[0] = 0x00; // Type: String
+                   memcpy(action_data + 1, value, value_len);
+                   action_data[1 + value_len] = '\0';
+                   free(action->action_data);
+                   action->action_data = action_data;
+                   action->action_length = 1 + value_len + 1;
+               }
+           }
+           break;
+       }
+    }
+    return 0;
+}
+
+int
 swf_action_list_append_top(swf_action_list_t *list, int action_id,
                            unsigned char *action_data, int action_data_length) {
     swf_action_t *action;
@@ -361,3 +402,4 @@ swf_action_list_append_top(swf_action_list_t *list, int action_id,
     }
     return 0;
 }
+
index e6f1b2e..c744419 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef __SWF_ACTION_H__
 #define __SWF_ACTION_H__
 
+#include "y_keyvalue.h"
+
 typedef struct swf_action_ {
     unsigned char  action_id;
     unsigned short action_length;
@@ -38,6 +40,8 @@ extern void swf_action_list_print(swf_action_list_t *act_list,
 
 extern int swf_action_data_print(unsigned char *action_data,
                                  unsigned short action_data_len);
+extern int swf_action_replace_string(swf_action_list_t *action_list,
+                                    y_keyvalue_t *kv);
 
 extern int swf_action_list_append_top(swf_action_list_t *list,
                                       int action_id,
index 3848a64..1d9d94b 100644 (file)
@@ -1181,6 +1181,34 @@ swf_object_insert_action_setvariables(swf_object_t *swf,
     return 0; // SUCCESS
 }
 
+int
+swf_object_replace_action_string(swf_object_t *swf, y_keyvalue_t *kv) {
+    swf_tag_t *tag;
+    int ret = 0;
+    if (swf == NULL) {
+        fprintf(stderr, "swf_object_replace_action_string: swf == NULL\n");
+        return 1; // NG
+    }
+    if (kv == NULL) {
+        fprintf(stderr, "swf_object_replace_action_string: kv == NULL\n");
+        return 1; // NG
+    }
+    for (tag=swf->tag_head ; tag ; tag=tag->next) {
+        if (isActionTag(tag->code)) {
+           ret = swf_tag_replace_action_string(tag, kv, swf);
+           if (ret) {
+               fprintf(stderr, "swf_object_replace_action_string: swf_tag_replace_action_string failed");
+               break;
+           }
+           if (tag->data) {
+               free(tag->data);
+               tag->data = NULL;
+           }
+       }
+    }
+    return ret;
+}
+
 /*
  * 参照側の cid 値を入れ替える
  */
index 8377078..5887f40 100644 (file)
@@ -125,6 +125,9 @@ extern unsigned char *swf_object_get_actiondata(swf_object_t *swf, unsigned long
 extern int swf_object_insert_action_setvariables(swf_object_t *swf,
                                                  y_keyvalue_t *kv);
 
+extern int swf_object_replace_action_string(swf_object_t *swf,
+                                           y_keyvalue_t *kv);
+
 extern int swf_object_replace_movieclip(swf_object_t *swf,
                                         unsigned char *instance_name,
                                         int instancee_name_len,
index 1fb006b..c1db9e5 100644 (file)
@@ -992,6 +992,34 @@ swf_tag_put_action_setvariables(swf_tag_t *tag, y_keyvalue_t *kv,
     return 0;
 }
 
+int
+swf_tag_replace_action_string(swf_tag_t *tag, y_keyvalue_t *kv,
+                             struct swf_object_ *swf) {
+    int ret;
+    if (tag == NULL) {
+        fprintf(stderr, "swf_tag_replace_action_string: tag == NULL\n");
+        return 1; // NG
+    }
+    if (kv == NULL) {
+        fprintf(stderr, "swf_tag_replace_action_string: kv == NULL\n");
+        return 1; // NG
+    }
+    if (swf == NULL) {
+        fprintf(stderr, "swf_tag_replace_action_string: swf == NULL\n");
+        return 1; // NG
+    }
+    if (swf_tag_create_input_detail(tag, swf) == NULL) {
+        fprintf(stderr, "swf_tag_replace_action_string: swf_tag_create_input_detail failed\n");
+        return 1; // NG
+    }
+    ret = swf_tag_action_replace_string(tag, kv);
+    if (ret) {
+      fprintf(stderr, "swf_tag_replace_action_string: swf_tag_action_replace_string failed\n");
+    }
+    return ret;
+}
+
+
 // タグの中味を移し替える
 swf_tag_t *
 swf_tag_move(swf_tag_t *from_tag) {
index 941e9f7..9ec8255 100644 (file)
@@ -116,6 +116,10 @@ extern int swf_tag_put_action_setvariables(swf_tag_t *tag,
                                            y_keyvalue_t *kv,
                                            struct swf_object_ *swf);
 
+extern int swf_tag_replace_action_string(swf_tag_t *tag,
+                                        y_keyvalue_t *kv,
+                                        struct swf_object_ *swf);
+
 extern swf_tag_t * swf_tag_move(swf_tag_t *tag);
 
 #endif /* __SWF_TAG_H__ */
index 04eefcb..a65d547 100644 (file)
@@ -117,8 +117,10 @@ void
 swf_tag_action_destroy_detail(swf_tag_t *tag) {
     swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
     if (swf_tag_action) {
-        swf_action_list_destroy(swf_tag_action->action_list);
-        swf_tag_action->action_list = NULL;
+        if (swf_tag_action->action_list) {
+           swf_action_list_destroy(swf_tag_action->action_list);
+           swf_tag_action->action_list = NULL;
+       }
         free(swf_tag_action);
         tag->detail = NULL;
     }
@@ -178,3 +180,16 @@ swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv) {
     free(action_data);
     return 0;
 }
+
+
+int
+swf_tag_action_replace_string(swf_tag_t *tag, y_keyvalue_t *kv) {
+    bitstream_t *bs;
+    int ret;
+    swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
+    ret = swf_action_list_replace_string(swf_tag_action->action_list, kv);
+    if (ret) {
+        fprinft(stderr, "swf_tag_action_replace_string: swf_action_list_replace_string failed\n");
+    }
+    return ret;
+}
index 5e95649..024631b 100644 (file)
@@ -31,5 +31,6 @@ extern void swf_tag_action_print_detail(swf_tag_t *tag,
 extern void swf_tag_action_destroy_detail(swf_tag_t *tag);
 
 extern int swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv);
+extern int swf_tag_action_replace_string(swf_tag_t *tag, y_keyvalue_t *kv);
 
 #endif /* __SWF_TAG_ACTION__H__ */