From: yoya Date: Wed, 8 Jun 2011 07:52:20 +0000 (+0000) Subject: DoAction, DoInitAction を parse/build する時の内部仕様変更。 X-Git-Tag: v0_60~179 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=401b6652106b93ffb92f882c17fa715f170e2256;p=swfed%2Fswfed.git DoAction, DoInitAction を parse/build する時の内部仕様変更。 Actionレコードのバイナリ全体でなく、Actionの配列として保持するようにした。 - swf_tag_action 構造体から action_data, action_length、has_length を削除してaction_list を追加 - detail input, output に action_list 処理を追加 - setvariable を action_list に対する処理に変更 - getTagDetail で Action タグの時に埋めるキーを action_record_data,len から action_list_count に変更 - getActionData で参照でなく malloc したデータが返るので、その対応 - swf_tag_action_create_setvaribles, swf_tag_action_put_setvaribles の処理が重複してたので swf_tag_action_top_append_varibles にまとめた。 - action_has_length で判断する場所を action_id >= 0x80 で判断するよう変更 git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/swfed/trunk@575 7c90b180-03d5-4157-b861-58a559ae9d1e --- diff --git a/src/php_swfed.c b/src/php_swfed.c index 56a748e..2492aae 100644 --- a/src/php_swfed.c +++ b/src/php_swfed.c @@ -474,6 +474,8 @@ PHP_METHOD(swfed, getTagDetail) { swf_tag_sprite_detail_t *tag_sprite; swf_tag_shape_detail_t *tag_shape; swf_tag_place_detail_t *tag_place; + swf_action_t *action; + int action_list_count; zval *data = NULL; case 6: // DefineBitsJPEG case 21: // DefineBitsJPEG2 @@ -517,8 +519,12 @@ PHP_METHOD(swfed, getTagDetail) { if (tag->code == 59) { // DoInitAction add_assoc_long(return_value, "action_sprite", tag_action->action_sprite); } - if (tag_action->action_record && tag_action->action_record_len) { - add_assoc_long(return_value, "action_record_len", tag_action->action_record_len); + action = tag_action->action_list->head; + if (action) { + for (action_list_count = 0 ; action ; action_list_count++) { + action = action->next; + } + add_assoc_long(return_value, "action_list_count", action_list_count); } break; case 37: // DefineEditText; @@ -1208,7 +1214,7 @@ PHP_METHOD(swfed, replaceEditString) { PHP_METHOD(swfed, getActionData) { long tag_seqno = 0; swf_object_t *swf = NULL; - unsigned char *data_ref = NULL; + unsigned char *data = NULL; char *new_buff = NULL; unsigned long data_len = 0; @@ -1216,17 +1222,19 @@ PHP_METHOD(swfed, getActionData) { RETURN_FALSE; } swf = get_swf_object(getThis() TSRMLS_CC); - data_ref = swf_object_get_actiondata(swf, &data_len, tag_seqno); - if (data_ref == NULL) { + data = swf_object_get_actiondata(swf, &data_len, tag_seqno); + if (data == NULL) { fprintf(stderr, "getActionData: Can't get_actiondata\n"); RETURN_FALSE; } new_buff = emalloc(data_len); if (new_buff == NULL) { fprintf(stderr, "getActionData: Can't emalloc new_buff\n"); + free(data); RETURN_FALSE; } - memcpy(new_buff, data_ref, data_len); + memcpy(new_buff, data, data_len); + free(data); RETURN_STRINGL(new_buff, data_len, 0); } @@ -1242,7 +1250,8 @@ PHP_METHOD(swfed, disasmActionData) { array_init(return_value); bs = bitstream_open(); bitstream_input(bs, (unsigned char*) data, data_len); - action_list = swf_action_list_create(bs); + action_list = swf_action_list_create(); + swf_action_list_parse(bs, action_list); bitstream_close(bs); if (action_list) { swf_action_t *action = action_list->head; diff --git a/src/swf_action.c b/src/swf_action.c index 2df7207..5e74ab0 100644 --- a/src/swf_action.c +++ b/src/swf_action.c @@ -139,11 +139,6 @@ swf_action_parse(bitstream_t *bs, swf_action_t *act) { bitstream_align(bs); act->action_id = bitstream_getbyte(bs); if (act->action_id & 0x80) { - act->action_has_length = 1; - } else { - act->action_has_length = 0; - } - if (act->action_has_length) { act->action_length = bitstream_getbytesLE(bs, 2); offset = bitstream_getbytepos(bs); act->action_data = malloc(act->action_length); @@ -159,9 +154,8 @@ swf_action_parse(bitstream_t *bs, swf_action_t *act) { int swf_action_build(bitstream_t *bs, swf_action_t *act) { bitstream_align(bs); - /* bitstream_putbits(bs, act->action_has_length, 1); no need */ bitstream_putbyte(bs, act->action_id); - if (act->action_has_length) { + if (act->action_id & 0x80) { if (act->action_data == NULL) { return 1; // error } @@ -181,7 +175,7 @@ swf_action_print(swf_action_t *act, int indent_depth) { print_indent(indent_depth); printf("0x%02x", act->action_id); } - if (act->action_has_length) { + if (act->action_id & 0x80) { int i, n; unsigned char *d; switch(act->action_id) { @@ -214,21 +208,31 @@ swf_action_print(swf_action_t *act, int indent_depth) { } swf_action_list_t * -swf_action_list_create(bitstream_t *bs) { +swf_action_list_create(void) { swf_action_list_t *action_list; - swf_action_t *action; action_list = calloc(sizeof(*action_list), 1); if (action_list == NULL) { fprintf(stderr, "Can't alloc memory for action_list\n"); return NULL; } - do { + action_list->head = NULL; + action_list->tail = NULL; + return action_list; +} + +int +swf_action_list_parse(bitstream_t *bs, swf_action_list_t *action_list) { + swf_action_t *action; + while (1) { action = calloc(sizeof(*action), 1); if (action == NULL) { fprintf(stderr, "Can't alloc memory for action\n"); break; } - swf_action_parse(bs, action); + if (swf_action_parse(bs, action)) { + fprintf(stderr, "swf_action_list_parse: swf_action_parse failed"); + return 1; // NG + } if (action_list->head == NULL) { action_list->head = action_list->tail = action; } else { @@ -236,23 +240,26 @@ swf_action_list_create(bitstream_t *bs) { action_list->tail = action; } action->next = NULL; - } while(action->action_id != 0); // End Action; - return action_list; + if (action->action_id == 0) { // End Action; + break; + } + } + return 0; } -unsigned char * -swf_action_list_output(swf_action_list_t *list, unsigned long *length) { + +int +swf_action_list_build(bitstream_t *bs, swf_action_list_t *list) { swf_action_t *action; - bitstream_t *bs; - unsigned char *data; - *length = 0; - bs = bitstream_open(); for (action=list->head ; action ; action=action->next) { - swf_action_build(bs, action); + if (swf_action_build(bs, action) != 0) { + fprintf(stderr, "swf_action_list_build: swf_action_build failed\n"); + bitstream_putbyte(bs, 0); + return 1; + } } - data = bitstream_steal(bs, length); - bitstream_close(bs); - return data; + return 0; } + void swf_action_list_destroy(swf_action_list_t *action_list) { @@ -332,3 +339,25 @@ swf_action_data_print(unsigned char *action_data, unsigned short action_data_len } return result; } + +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; + action = calloc(sizeof(*action), 1); + action->action_id = action_id; + if (action_id >= 0x80) { + action->action_data = malloc(action_data_length); + memcpy(action->action_data, action_data, action_data_length); + action->action_length = action_data_length; + } else { + action->action_data = NULL; + action->action_length = action_data_length; + } + action->next = list->head; + list->head = action; + if (list->tail == NULL) { + list->tail = action; + } + return 0; +} diff --git a/src/swf_action.h b/src/swf_action.h index 6c16275..e6f1b2e 100644 --- a/src/swf_action.h +++ b/src/swf_action.h @@ -8,7 +8,6 @@ #define __SWF_ACTION_H__ typedef struct swf_action_ { - unsigned char action_has_length; unsigned char action_id; unsigned short action_length; unsigned char *action_data; @@ -30,9 +29,9 @@ extern int swf_action_parse(bitstream_t *bs, swf_action_t *act); extern int swf_action_build(bitstream_t *bs, swf_action_t *act); extern int swf_action_print(swf_action_t *act, int indent_depth); -extern swf_action_list_t *swf_action_list_create(bitstream_t *bs); -extern unsigned char *swf_action_list_output(swf_action_list_t *list, - unsigned long *length); +extern swf_action_list_t *swf_action_list_create(void); +extern int swf_action_list_parse(bitstream_t *bs, swf_action_list_t *list); +extern int swf_action_list_build(bitstream_t *bs, swf_action_list_t *list); extern void swf_action_list_destroy(swf_action_list_t *act_list); extern void swf_action_list_print(swf_action_list_t *act_list, int indent_depth); @@ -40,4 +39,9 @@ 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_list_append_top(swf_action_list_t *list, + int action_id, + unsigned char *action_data, + int action_data_length); + #endif /* __SWF_ACTION_H__ */ diff --git a/src/swf_object.c b/src/swf_object.c index 16b454b..3848a64 100644 --- a/src/swf_object.c +++ b/src/swf_object.c @@ -1080,6 +1080,8 @@ unsigned char * swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqno) { swf_tag_t *tag; swf_tag_action_detail_t *swf_tag_action; + bitstream_t *bs; + unsigned char *data; int i = 0; if (swf == NULL) { fprintf(stderr, "swf_object_get_actiondata: swf == NULL\n"); @@ -1102,8 +1104,11 @@ swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqn fprintf(stderr, "swf_object_get_actiondata: swf_tag_create_input_detail failed"); return NULL; } - *length = swf_tag_action->action_record_len; - return swf_tag_action->action_record; + bs = bitstream_open(); + swf_action_list_build(bs,swf_tag_action->action_list); + data = bitstream_steal(bs, length); + bitstream_close(bs); + return data; } int diff --git a/src/swf_tag.c b/src/swf_tag.c index b9c92e8..1fb006b 100644 --- a/src/swf_tag.c +++ b/src/swf_tag.c @@ -938,6 +938,7 @@ swf_tag_t * swf_tag_create_action_setvariables(y_keyvalue_t *kv) { int ret; swf_tag_t *tag = NULL; + swf_tag_action_detail_t *swf_tag_action; if (kv == NULL) { fprintf(stderr, "swf_tag_create_action_setvariables: kv == NULL\n"); return NULL; @@ -947,7 +948,15 @@ swf_tag_create_action_setvariables(y_keyvalue_t *kv) { swf_tag_info_t *tag_info = get_swf_tag_info(tag->code); swf_tag_detail_handler_t *detail_handler = tag_info->detail_handler(); tag->detail = detail_handler->create(); - ret = swf_tag_action_create_setvaribles(tag, kv); + swf_tag_action = (swf_tag_action_detail_t*) tag->detail; + swf_tag_action->action_list = swf_action_list_create(); + if (swf_tag_action->action_list == NULL) { + fprintf(stderr, "swf_tag_create_action_setvariables: swf_action_list_create failed\n"); + swf_tag_destroy(tag); + return NULL; + } + swf_action_list_append_top(swf_tag_action->action_list, 0, NULL, 0); // End Action + ret = swf_tag_action_top_append_varibles(tag, kv); if (ret) { swf_tag_destroy(tag); return NULL; @@ -971,7 +980,7 @@ swf_tag_put_action_setvariables(swf_tag_t *tag, y_keyvalue_t *kv, fprintf(stderr, "swf_tag_put_action_setvariables: swf_tag_create_input_detail failed\n"); return 1; } - ret = swf_tag_action_put_setvaribles(tag, kv); + ret = swf_tag_action_top_append_varibles(tag, kv); if (ret) { swf_tag_destroy(tag); return 1; // NG diff --git a/src/swf_tag_action.c b/src/swf_tag_action.c index 6ba2d4f..04eefcb 100644 --- a/src/swf_tag_action.c +++ b/src/swf_tag_action.c @@ -33,8 +33,7 @@ swf_tag_action_create_detail(void) { return NULL; } swf_tag_action->action_sprite = 0; - swf_tag_action->action_record = NULL; - swf_tag_action->action_record_len = 0; + swf_tag_action->action_list = NULL; return swf_tag_action; } @@ -44,10 +43,16 @@ swf_tag_action_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { unsigned char *data = tag->data; unsigned long length = tag->length; bitstream_t *bs; - unsigned long pos, len; (void) swf; + if (tag == NULL) { + fprintf(stderr, "ERROR: swf_tag_action_input_detail: tag == NULL\n"); + return 1; + } + swf_tag_action = tag->detail; + data = tag->data; + length = tag->length; if (swf_tag_action == NULL) { - fprintf(stderr, "ERROR: swf_tag_action_create_detail: swf_tag_action == NULL\n"); + fprintf(stderr, "ERROR: swf_tag_action_input_detail: swf_tag_action == NULL\n"); return 1; } @@ -59,10 +64,17 @@ swf_tag_action_input_detail(swf_tag_t *tag, struct swf_object_ *swf) { } else { // DoAction swf_tag_action->action_sprite = 0; // fail safe } - pos = bitstream_getbytepos(bs); - len = bitstream_length(bs) - pos; - swf_tag_action->action_record = bitstream_output_sub(bs, pos, len); - swf_tag_action->action_record_len = len; + swf_tag_action->action_list = swf_action_list_create(); + if (swf_tag_action->action_list == NULL) { + fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_create failed\n"); + bitstream_close(bs); + return 1; + } + if (swf_action_list_parse(bs, swf_tag_action->action_list)) { + fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_parse failed\n"); + bitstream_close(bs); + return 1; + } bitstream_close(bs); return 0; } @@ -82,18 +94,14 @@ swf_tag_action_output_detail(swf_tag_t *tag, unsigned long *length, } else { // DoAction ; // nothing } - bitstream_putstring(bs, swf_tag_action->action_record, - swf_tag_action->action_record_len); + swf_action_list_build(bs,swf_tag_action->action_list); data = bitstream_steal(bs, length); - bitstream_close(bs); return data; } void swf_tag_action_print_detail(swf_tag_t *tag, struct swf_object_ *swf, int indent_depth) { - bitstream_t *bs; - swf_action_list_t *action_list; swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail; (void) swf; print_indent(indent_depth); @@ -101,13 +109,7 @@ swf_tag_action_print_detail(swf_tag_t *tag, printf("action_sprite=%d ", swf_tag_action->action_sprite); } printf("action_record =\n"); - bs = bitstream_open(); - bitstream_input(bs, swf_tag_action->action_record, - swf_tag_action->action_record_len); - action_list = swf_action_list_create(bs); - bitstream_close(bs); - swf_action_list_print(action_list, indent_depth + 1); - swf_action_list_destroy(action_list); + swf_action_list_print(swf_tag_action->action_list, indent_depth + 1); return ; } @@ -115,8 +117,8 @@ 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) { - free(swf_tag_action->action_record); - swf_tag_action->action_record = NULL; + swf_action_list_destroy(swf_tag_action->action_list); + swf_tag_action->action_list = NULL; free(swf_tag_action); tag->detail = NULL; } @@ -124,72 +126,55 @@ swf_tag_action_destroy_detail(swf_tag_t *tag) { } int -swf_tag_action_create_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv) { - bitstream_t *bs; +swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv) { char *key, *value; int key_len, value_len; - unsigned long data_len; + int key_maxlen, value_maxlen, maxlen; swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail; - swf_tag_action->action_sprite = 0; - bs = bitstream_open(); - - y_keyvalue_rewind(kv); - while (y_keyvalue_next(kv)) { - key = y_keyvalue_get_currentkey(kv, &key_len); - value = y_keyvalue_get_currentvalue(kv, &value_len); - bitstream_putbyte(bs, 0x96); // Push Data - bitstream_putbytesLE(bs, key_len + 2 , 2); - bitstream_putbyte(bs, 0); - bitstream_putstring(bs, (unsigned char*) key, key_len); - bitstream_putbyte(bs, 0); - bitstream_putbyte(bs, 0x96); // Push Data - bitstream_putbytesLE(bs, value_len + 2 , 2); - bitstream_putbyte(bs, 0); - bitstream_putstring(bs, (unsigned char*) value, value_len); - bitstream_putbyte(bs, 0); - bitstream_putbyte(bs, 0x1d); // Set Variable + unsigned char *action_data = NULL; + if (tag == NULL) { + fprintf(stderr, "swf_tag_action_top_append_varibles: tag == NULL\n"); + return 1; // NG } - bitstream_putbyte(bs, 0); // End - if (swf_tag_action->action_record) { - free(swf_tag_action->action_record); + if (! isActionTag(tag->code)) { + fprintf(stderr, "swf_tag_action_top_append_varibles: isnot ActionTag code=%d\n", tag->code); + return 1; // NG } - swf_tag_action->action_record = bitstream_steal(bs, &data_len); - swf_tag_action->action_record_len = data_len; - bitstream_close(bs); - return 0; -} - -int -swf_tag_action_put_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv) { - bitstream_t *bs; - char *key, *value; - int key_len, value_len; - unsigned long data_len; - swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail; + key_maxlen = y_keyvalue_get_maxkeylength(kv); + value_maxlen = y_keyvalue_get_maxvaluelength(kv); + maxlen = (key_maxlen>value_maxlen)?key_maxlen:value_maxlen; + action_data = malloc(1 + maxlen + 1); swf_tag_action->action_sprite = 0; - bs = bitstream_open(); - y_keyvalue_rewind(kv); - while (y_keyvalue_next(kv)) { - key = y_keyvalue_get_currentkey(kv, &key_len); + // Reversible itelator for append top method. + y_keyvalue_seeklast(kv); + while (1) { + key = y_keyvalue_get_currentkey(kv, &key_len); + if (key == NULL) { + break; + } value = y_keyvalue_get_currentvalue(kv, &value_len); - bitstream_putbyte(bs, 0x96); // Push Data - bitstream_putbytesLE(bs, key_len + 2 , 2); - bitstream_putbyte(bs, 0); - bitstream_putstring(bs, (unsigned char *)key, key_len); - bitstream_putbyte(bs, 0); - bitstream_putbyte(bs, 0x96); // Push Data - bitstream_putbytesLE(bs, value_len + 2 , 2); - bitstream_putbyte(bs, 0); - bitstream_putstring(bs, (unsigned char *)value, value_len); - bitstream_putbyte(bs, 0); - bitstream_putbyte(bs, 0x1d); // Set Variable - } - if (swf_tag_action->action_record) { - bitstream_putstring(bs, swf_tag_action->action_record, swf_tag_action->action_record_len); - free(swf_tag_action->action_record); + + // Push Data(key), Push Data(value), Set Variable. + // But reversible order for append top method. + // + // Set Variable + swf_action_list_append_top(swf_tag_action->action_list, 0x1d, NULL, 0); + // Push Data (value); + action_data[0] = 0; // type string; + memcpy(action_data + 1, value, value_len); + action_data[value_len + 1] = '\0'; + swf_action_list_append_top(swf_tag_action->action_list, 0x96, + action_data, 1 + value_len + 1); + // Push Data (key); + action_data[0] = 0; // type string; + memcpy(action_data + 1, key, key_len); + action_data[key_len + 1] = '\0'; + swf_action_list_append_top(swf_tag_action->action_list, 0x96, + action_data, 1 + key_len + 1); + if (y_keyvalue_prev(kv) == 0) { + break; + } } - swf_tag_action->action_record = bitstream_steal(bs, &data_len); - swf_tag_action->action_record_len = data_len; - bitstream_close(bs); + free(action_data); return 0; } diff --git a/src/swf_tag_action.h b/src/swf_tag_action.h index 5752157..5e95649 100644 --- a/src/swf_tag_action.h +++ b/src/swf_tag_action.h @@ -12,8 +12,7 @@ typedef struct swf_tag_action_detail_ { unsigned short action_sprite; - unsigned char *action_record; - unsigned long action_record_len; + swf_action_list_t *action_list; } swf_tag_action_detail_t; extern swf_tag_detail_handler_t *swf_tag_action_detail_handler(void); @@ -31,7 +30,6 @@ extern void swf_tag_action_print_detail(swf_tag_t *tag, int indent_depth); extern void swf_tag_action_destroy_detail(swf_tag_t *tag); -extern int swf_tag_action_create_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv); -extern int swf_tag_action_put_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv); +extern int swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv); #endif /* __SWF_TAG_ACTION__H__ */