Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
- This file is distributed under the GPL, see file COPYING for details
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-*/
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../rfxswf.h"
u: url (string)
t: target (string)
l: label (string)
-C: constant pool header (byte)
+C: constant pool header (word)
c: constant pool entry (string)
s: skip (byte) (number of actions)
m: method (byte) swf_GetUrl2:(0=none, 1=get, 2=post)/GotoFrame2:(1=play)
{5,"Less2", 0x48,""},
{6,"Greater", 0x67,""},
{6,"StringGreater", 0x68,""},
-{6,"Enumerate2", 0x55,""}
-{6,"InstanceOf", 0x54,""}
+{6,"Enumerate2", 0x55,""},
+{6,"InstanceOf", 0x54,""},
{6,"StrictEquals", 0x66,""}
};
static int definedactions = sizeof(actions)/sizeof(struct Action);
U8*data;
while(op)
{
- action->next = (ActionTAG*)malloc(sizeof(ActionTAG));
+ action->next = (ActionTAG*)rfx_calloc(sizeof(ActionTAG));
action->next->prev = action;
action->next->next = 0;
+ action->next->parent = tmp.next;
action = action->next;
op = swf_GetU8(tag);
length = swf_GetU16(tag);
if(length) {
- data = malloc(length);
+ data = (U8*)rfx_alloc(length);
swf_GetBlock(tag, data, length);
} else {
data = 0;
void swf_ActionFree(ActionTAG*action)
{
+ if(!action) {
+ return;
+ }
+ action = action->parent;
+ if(!action) {
+ fprintf(stderr, "Warning: freeing zero action (no parent)");
+ return;
+ }
+
while(action)
{
ActionTAG*tmp;
- if(action->data && action->data != action->tmp)
- free(action->data);
+ if(action->data && action->data != action->tmp) {
+ rfx_free(action->data);
+ action->data = 0;
+ }
+ action->len = 0;
tmp = action;
action=action->next;
- free(tmp);
+ rfx_free(tmp);
}
}
void swf_ActionSet(TAG*tag, ActionTAG*action)
{
+ if(!action) {
+ return;
+ }
action=action->parent;
while(action)
{
case 'f':
return 2;
case 'u':
- return strlen(data)+1;
+ return strlen((const char*)data)+1;
case 't':
- return strlen(data)+1;
+ return strlen((const char*)data)+1;
case 'l':
- return strlen(data)+1;
+ return strlen((const char*)data)+1;
case 'c':
- return strlen(data)+1;
+ return strlen((const char*)data)+1;
case 'C':
return 2;
case 's':
case 'p': {
U8 type = *data++;
if(type == 0) {
- return 1+strlen(data)+1; //string
+ return 1+strlen((const char*)data)+1; //string
} else if (type == 1) {
return 1+4; //float
} else if (type == 2) {
return 1+0; //NULL
+ } else if (type == 3) {
+ return 1+0; //Undefined
} else if (type == 4) {
return 1+1; //register
} else if (type == 5) {
return 1+4; //int
} else if (type == 8) {
return 1+1; //lookup
+ } else if (type == 9) {
+ return 1+2; //lookup 16
} else return 1;
break;
}
while(atag)
{
char*indent = &spaces[sizeof(spaces)-1-countpos*4];
- U8 poollen = 0;
+ U16 poollen = 0;
for(t=0;t<definedactions;t++)
if(actions[t].op == atag->op)
break;
printf(" String:\"%s\"", data);
#ifdef MAX_LOOKUP
if (entry<MAX_LOOKUP)
- lookup[entry++] = strdup(data);
+ lookup[entry++] = strdup((const char*)data);
#endif
} break;
case 'C': {
- poollen = *data;
+ poollen = data[0]+256*data[1];
entry = 0;
printf("(%d entries)", poollen);
} break;
num = (data[s++]); //num
num += (data[s++])*256;
for(t=0;t<num;t++) {
- printf("%s",data);
+ printf("%s",data+s); // 10/22/04 MD: added +s to
if(t<num-1)
printf(", ");
while(data[s++]); //param
printf(" Float:%f", *(float*)&f);
} else if (type == 2) {
printf(" NULL");
+ } else if (type == 3) {
+ printf(" Undefined");
} else if (type == 4) {
printf(" register:%d", *value);
} else if (type == 5) {
printf(" bool:%s", *value?"true":"false");
} else if (type == 6) {
U8 a[8];
- int t;
memcpy(&a[4],value,4);
memcpy(a,&value[4],4);
#ifdef WORDS_BIGENDIAN
+ int t;
for(t=0;t<4;t++) {
U8 tmp = a[t];
a[t]=a[7-t];
if (lookup[*value])
printf(" (\"%s\")",lookup[*value]);
#endif
+ } else if (type == 9) {
+ U32 offset = value[0]+(value[1]<<8);
+ printf(" Lookup16:%d", offset);
+#ifdef MAX_LOOKUP
+ if (lookup[offset])
+ printf(" (\"%s\")",lookup[offset]);
+#endif
} else {
printf(" UNKNOWN[%02x]",type);
}
}
#ifdef MAX_LOOKUP
- for (t=0;t<MAX_LOOKUP;t++) if (lookup[t]) free(lookup[t]);
+ for (t=0;t<MAX_LOOKUP;t++) if (lookup[t]) rfx_free(lookup[t]);
#endif
}
int count = 0;
while(atag)
{
- U8 poollen = 0;
+ U16 poollen = 0;
for(t=0;t<definedactions;t++)
if(actions[t].op == atag->op)
break;
case 'u': {
if(type&TYPE_URL)
{
- replacelen = strlen(data);
+ replacelen = strlen((const char*)data);
replacepos = data;
- replacement = callback(data); // may be null
+ replacement = (U8*)callback((char*)data); // may be null
}
} break;
case 't': {
if(type&TYPE_TARGET)
{
- replacelen = strlen(data);
+ replacelen = strlen((const char*)data);
replacepos = data;
- replacement = callback(data); // may be null
+ replacement = (U8*)callback((char*)data); // may be null
}
} break;
case 'c': {
if(type&TYPE_STRING)
{
- replacelen = strlen(data);
+ replacelen = strlen((const char*)data);
replacepos = data;
- replacement = callback(data); // may be null
+ replacement = (U8*)callback((char*)data); // may be null
}
} break;
case 'C': {
- poollen = (*data);
+ poollen = (data[0]+256*data[1]);
} break;
case 'o': {
} break;
case 'p': {
U8 datatype = *data;
- char*value = &data[1];
+ char*value = (char*)&data[1];
if(datatype == 0) { //string
if(type&TYPE_STRING)
{
replacelen = strlen(value);
- replacepos = value;
- replacement = callback(value); // may be null
+ replacepos = (U8*)value;
+ replacement = (U8*)callback(value); // may be null
}
} else if (datatype == 8) { //lookup
}
if(replacement)
{
- int newlen = strlen(replacement);
- char * newdata = malloc(atag->len - replacelen + newlen);
+ int newlen = strlen((const char *)replacement);
+ char * newdata = (char*)rfx_alloc(atag->len - replacelen + newlen);
int rpos = replacepos - atag->data;
memcpy(newdata, atag->data, rpos);
memcpy(&newdata[rpos], replacement, newlen);
memcpy(&newdata[rpos+newlen], &replacepos[replacelen],
&data[atag->len] - &replacepos[replacelen]);
- free(atag->data);
- atag->data = newdata;
+ rfx_free(atag->data);
+ atag->data = (U8*)newdata;
data = &atag->data[rpos+newlen+1];
}
}
/*static ActionTAG* swf_ActionStart()
{
ActionTAG*atag;
- atag = (ActionTAG*)malloc(sizeof(ActionTAG));
+ atag = (ActionTAG*)rfx_alloc(sizeof(ActionTAG));
atag->prev = 0;
atag->next = 0;
atag->parent = 0;
}
last->prev->next = 0;
- free(last);
+ rfx_free(last);
}*/
static ActionTAG*lastATAG(ActionTAG*atag)
{
- ActionTAG*last;
+ ActionTAG*last = 0;
while(atag) {
last = atag;
atag=atag->next;
ActionTAG* swf_AddActionTAG(ActionTAG*atag, U8 op, U8*data, U16 len)
{
ActionTAG*tmp;
- tmp = (ActionTAG*)malloc(sizeof(ActionTAG));
+ tmp = (ActionTAG*)rfx_alloc(sizeof(ActionTAG));
tmp->next = 0;
if(atag) {
tmp->prev = atag;
tmp->prev = 0;
tmp->parent = tmp;
}
- if(data || !len)
+ if(data || !len) {
tmp->data = data;
- else
+ } else {
tmp->data = tmp->tmp;
+ }
tmp->len = len;
tmp->op = op;
if (a1->op == ACTION_IF || a1->op == ACTION_JUMP)
{
- *(U16*)(a1->data) = SWAP16(len);
+ *(U16*)(a1->data) = LE_16_TO_NATIVE(len);
}
else if(a1->op == ACTION_WAITFORFRAME)
{
ActionTAG* action_GotoFrame(ActionTAG*atag, U16 frame)
{
atag = swf_AddActionTAG(atag, ACTION_GOTOFRAME, 0, 2);
- *(U16*)atag->tmp = SWAP16(frame);
+ *(U16*)atag->tmp = LE_16_TO_NATIVE(frame);
return atag;
}
ActionTAG* action_Jump(ActionTAG*atag, U16 branch)
{
atag = swf_AddActionTAG(atag, ACTION_JUMP, 0, 2);
- *(U16*)atag->tmp = SWAP16(branch);
+ *(U16*)atag->tmp = LE_16_TO_NATIVE(branch);
return atag;
}
ActionTAG* action_If(ActionTAG*atag, U16 branch)
{
atag = swf_AddActionTAG(atag, ACTION_IF, 0, 2);
- *(U16*)atag->tmp = SWAP16(branch);
+ *(U16*)atag->tmp = LE_16_TO_NATIVE(branch);
return atag;
}
ActionTAG* action_StoreRegister(ActionTAG*atag, U8 reg)
ActionTAG* action_WaitForFrame(ActionTAG*atag, U16 frame, U8 skip)
{
atag = swf_AddActionTAG(atag, ACTION_WAITFORFRAME, 0, 3);
- *(U16*)atag->tmp = SWAP16(frame);
+ *(U16*)atag->tmp = LE_16_TO_NATIVE(frame);
*(U8*)&atag->tmp[2] = skip;
return atag;
}
-ActionTAG* action_SetTarget(ActionTAG*atag, char* target)
+ActionTAG* action_SetTarget(ActionTAG*atag, const char* target)
{
char*ptr = strdup(target);
return swf_AddActionTAG(atag, ACTION_SETTARGET, (U8*)ptr, strlen(ptr)+1);
*(U8*)atag->tmp = 2; //NULL
return atag;
}
+ActionTAG* action_PushUndefined(ActionTAG*atag)
+{
+ atag = swf_AddActionTAG(atag, ACTION_PUSH, 0, 1);
+ *(U8*)atag->tmp = 3; //Undefined
+ return atag;
+}
ActionTAG* action_PushBoolean(ActionTAG*atag, char c)
{
atag = swf_AddActionTAG(atag, ACTION_PUSH, 0, 2);
*(U8*)&atag->tmp[1] = index;
return atag;
}
-ActionTAG* action_PushString(ActionTAG*atag, char*str)
+ActionTAG* action_PushLookup16(ActionTAG*atag, U16 index)
+{
+ atag = swf_AddActionTAG(atag, ACTION_PUSH, 0, 3);
+ *(U8*)atag->tmp = 9; //lookup
+ *(U8*)&atag->tmp[1] = (U8)index;
+ *(U8*)&atag->tmp[2] = index>>8;
+ return atag;
+}
+ActionTAG* action_PushString(ActionTAG*atag, const char*str)
{
int l = strlen(str);
- char*ptr = (char*)malloc(l+2);
+ char*ptr = (char*)rfx_alloc(l+2);
ptr[0] = 0; // string
strcpy(&ptr[1], str);
return swf_AddActionTAG(atag, ACTION_PUSH, (U8*)ptr, l+2);
}
ActionTAG* action_PushFloat(ActionTAG*atag, float f)
{
- char*ptr = (char*)malloc(5);
+ char*ptr = (char*)rfx_alloc(5);
U32 fd = *(U32*)&f;
ptr[0] = 1; //float
ptr[1] = fd;
}
ActionTAG* action_PushDouble(ActionTAG*atag, double d)
{
- char*ptr = (char*)malloc(9);
+ char*ptr = (char*)rfx_alloc(9);
U8*dd = (U8*)&d;
ptr[0] = 6; //double
#ifdef WORDS_BIGENDIAN
ActionTAG* action_PushInt(ActionTAG*atag, int i)
{
atag = swf_AddActionTAG(atag, ACTION_PUSH, 0, 5);
- *(U8*)atag->tmp = 7; //int
+ atag->tmp[0] = 7; //int
atag->tmp[1] = i;
atag->tmp[2] = i>>8;
atag->tmp[3] = i>>16;
char*ptr = strdup(label);
return swf_AddActionTAG(atag, ACTION_GOTOLABEL, (U8*)ptr, strlen(ptr));
}
-ActionTAG* action_GetUrl(ActionTAG*atag, char* url, char* label)
+ActionTAG* action_GetUrl(ActionTAG*atag, const char* url, char* label)
{
int l1= strlen(url);
int l2= strlen(label);
- char*ptr = malloc(l1+l2+2);
+ char*ptr = (char*)rfx_alloc(l1+l2+2);
strcpy(ptr, url);
strcpy(&ptr[l1+1], label);
- return swf_AddActionTAG(atag, ACTION_GETURL, ptr, l1+l2+2);
+ return swf_AddActionTAG(atag, ACTION_GETURL, (U8*)ptr, l1+l2+2);
}
//TODO:
ActionTAG* action_DefineFunction(ActionTAG*atag, U8*data, int len) {return atag;}
ActionTAG* action_Constantpool(ActionTAG*atag, char* constantpool) {return atag;}
ActionTAG* action_With(ActionTAG*atag, char*object) {return atag;}
+#include "../action/actioncompiler.h"
+
+ActionTAG* swf_ActionCompile(const char* source, int version)
+{
+ TAG* tag;
+ ActionTAG* a = 0;
+ void*buffer = 0;
+ int len = 0;
+ int ret;
+
+ tag = swf_InsertTag(NULL, ST_DOACTION);
+ ret = compileSWFActionCode(source, version, &buffer, &len);
+ if(!ret || buffer==0 || len == 0)
+ return 0;
+
+ swf_SetBlock(tag, (U8*)buffer, len);
+ swf_SetU8(tag, 0);
+
+ rfx_free(buffer);
+
+ a = swf_ActionGet(tag);
+ swf_DeleteTag(0, tag);
+ return a;
+}
+
+
/*
Properties: