forked from enlightenment/efl
make sure eet doesn't leak on "bad decoding". this means api changes though -
sorry. SVN revision: 7112
This commit is contained in:
parent
1bf1f933a9
commit
f54245420a
|
@ -56,24 +56,30 @@ encdectest(void)
|
||||||
evas_list_next,
|
evas_list_next,
|
||||||
evas_list_append,
|
evas_list_append,
|
||||||
evas_list_data,
|
evas_list_data,
|
||||||
evas_hash_foreach,
|
evas_list_free,
|
||||||
evas_hash_add);
|
evas_hash_foreach,
|
||||||
|
evas_hash_add,
|
||||||
|
evas_hash_free);
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(edd3, Blah3, "string3", string, EET_T_STRING);
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd3, Blah3, "string3", string, EET_T_STRING);
|
||||||
|
|
||||||
edd2 = eet_data_descriptor_new("blah2", sizeof(Blah2),
|
edd2 = eet_data_descriptor_new("blah2", sizeof(Blah2),
|
||||||
evas_list_next,
|
evas_list_next,
|
||||||
evas_list_append,
|
evas_list_append,
|
||||||
evas_list_data,
|
evas_list_data,
|
||||||
evas_hash_foreach,
|
evas_list_free,
|
||||||
evas_hash_add);
|
evas_hash_foreach,
|
||||||
|
evas_hash_add,
|
||||||
|
evas_hash_free);
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(edd2, Blah2, "string2", string, EET_T_STRING);
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd2, Blah2, "string2", string, EET_T_STRING);
|
||||||
|
|
||||||
edd = eet_data_descriptor_new("blah", sizeof(Blah),
|
edd = eet_data_descriptor_new("blah", sizeof(Blah),
|
||||||
evas_list_next,
|
evas_list_next,
|
||||||
evas_list_append,
|
evas_list_append,
|
||||||
evas_list_data,
|
evas_list_data,
|
||||||
evas_hash_foreach,
|
evas_list_free,
|
||||||
evas_hash_add);
|
evas_hash_foreach,
|
||||||
|
evas_hash_add,
|
||||||
|
evas_hash_free);
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "character", character, EET_T_CHAR);
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "character", character, EET_T_CHAR);
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "sixteen", sixteen, EET_T_SHORT);
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "sixteen", sixteen, EET_T_SHORT);
|
||||||
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "integer", integer, EET_T_INT);
|
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "integer", integer, EET_T_INT);
|
||||||
|
|
|
@ -394,24 +394,30 @@ extern "C" {
|
||||||
* evas_list_next,
|
* evas_list_next,
|
||||||
* evas_list_append,
|
* evas_list_append,
|
||||||
* evas_list_data,
|
* evas_list_data,
|
||||||
|
* evas_list_free,
|
||||||
* evas_hash_foreach,
|
* evas_hash_foreach,
|
||||||
* evas_hash_add);
|
* evas_hash_add,
|
||||||
|
* evas_hash_free);
|
||||||
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd3, Blah3, "string3", string, EET_T_STRING);
|
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd3, Blah3, "string3", string, EET_T_STRING);
|
||||||
*
|
*
|
||||||
* edd2 = eet_data_descriptor_new("blah2", sizeof(Blah2),
|
* edd2 = eet_data_descriptor_new("blah2", sizeof(Blah2),
|
||||||
* evas_list_next,
|
* evas_list_next,
|
||||||
* evas_list_append,
|
* evas_list_append,
|
||||||
* evas_list_data,
|
* evas_list_data,
|
||||||
|
* evas_list_free,
|
||||||
* evas_hash_foreach,
|
* evas_hash_foreach,
|
||||||
* evas_hash_add);
|
* evas_hash_add,
|
||||||
|
* evas_hash_free);
|
||||||
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd2, Blah2, "string2", string, EET_T_STRING);
|
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd2, Blah2, "string2", string, EET_T_STRING);
|
||||||
*
|
*
|
||||||
* edd = eet_data_descriptor_new("blah", sizeof(Blah),
|
* edd = eet_data_descriptor_new("blah", sizeof(Blah),
|
||||||
* evas_list_next,
|
* evas_list_next,
|
||||||
* evas_list_append,
|
* evas_list_append,
|
||||||
* evas_list_data,
|
* evas_list_data,
|
||||||
|
* evas_list_free,
|
||||||
* evas_hash_foreach,
|
* evas_hash_foreach,
|
||||||
* evas_hash_add);
|
* evas_hash_add,
|
||||||
|
* evas_hash_free);
|
||||||
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "character", character, EET_T_CHAR);
|
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "character", character, EET_T_CHAR);
|
||||||
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "sixteen", sixteen, EET_T_SHORT);
|
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "sixteen", sixteen, EET_T_SHORT);
|
||||||
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "integer", integer, EET_T_INT);
|
* EET_DATA_DESCRIPTOR_ADD_BASIC(edd, Blah, "integer", integer, EET_T_INT);
|
||||||
|
@ -484,7 +490,7 @@ extern "C" {
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Eet_Data_Descriptor *eet_data_descriptor_new(char *name, int size, void *(*func_list_next) (void *l), void *(*func_list_append) (void *l, void *d), void *(*func_list_data) (void *l), void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt), void *(*func_hash_add) (void *h, const char *k, void *d));
|
Eet_Data_Descriptor *eet_data_descriptor_new(char *name, int size, void *(*func_list_next) (void *l), void *(*func_list_append) (void *l, void *d), void *(*func_list_data) (void *l), void *(*func_list_free) (void *l), void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt), void *(*func_hash_add) (void *h, const char *k, void *d), void (*func_hash_free) (void *h));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function frees a data descriptor when it is not needed anymore.
|
* This function frees a data descriptor when it is not needed anymore.
|
||||||
|
|
|
@ -78,8 +78,10 @@ struct _Eet_Data_Descriptor
|
||||||
void *(*list_next) (void *l);
|
void *(*list_next) (void *l);
|
||||||
void *(*list_append) (void *l, void *d);
|
void *(*list_append) (void *l, void *d);
|
||||||
void *(*list_data) (void *l);
|
void *(*list_data) (void *l);
|
||||||
|
void *(*list_free) (void *l);
|
||||||
void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
|
void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
|
||||||
void *(*hash_add) (void *h, const char *k, void *d);
|
void *(*hash_add) (void *h, const char *k, void *d);
|
||||||
|
void (*hash_free) (void *h);
|
||||||
} func;
|
} func;
|
||||||
struct {
|
struct {
|
||||||
int num;
|
int num;
|
||||||
|
@ -1274,7 +1276,7 @@ eet_data_image_read(Eet_File *ef, char *name,
|
||||||
int size;
|
int size;
|
||||||
unsigned int *d = NULL;
|
unsigned int *d = NULL;
|
||||||
int header[8];
|
int header[8];
|
||||||
|
|
||||||
data = eet_read(ef, name, &size);
|
data = eet_read(ef, name, &size);
|
||||||
if (!data) return NULL;
|
if (!data) return NULL;
|
||||||
d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy);
|
d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy);
|
||||||
|
@ -1428,8 +1430,10 @@ eet_data_descriptor_new(char *name,
|
||||||
void *(*func_list_next) (void *l),
|
void *(*func_list_next) (void *l),
|
||||||
void *(*func_list_append) (void *l, void *d),
|
void *(*func_list_append) (void *l, void *d),
|
||||||
void *(*func_list_data) (void *l),
|
void *(*func_list_data) (void *l),
|
||||||
|
void *(*func_list_free) (void *l),
|
||||||
void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
|
void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
|
||||||
void *(*func_hash_add) (void *h, const char *k, void *d))
|
void *(*func_hash_add) (void *h, const char *k, void *d),
|
||||||
|
void (*func_hash_free) (void *h))
|
||||||
{
|
{
|
||||||
Eet_Data_Descriptor *edd;
|
Eet_Data_Descriptor *edd;
|
||||||
|
|
||||||
|
@ -1440,8 +1444,10 @@ eet_data_descriptor_new(char *name,
|
||||||
edd->func.list_next = func_list_next;
|
edd->func.list_next = func_list_next;
|
||||||
edd->func.list_append = func_list_append;
|
edd->func.list_append = func_list_append;
|
||||||
edd->func.list_data = func_list_data;
|
edd->func.list_data = func_list_data;
|
||||||
|
edd->func.list_free = func_list_free;
|
||||||
edd->func.hash_foreach = func_hash_foreach;
|
edd->func.hash_foreach = func_hash_foreach;
|
||||||
edd->func.hash_add = func_hash_add;
|
edd->func.hash_add = func_hash_add;
|
||||||
|
edd->func.hash_free = func_hash_free;
|
||||||
return edd;
|
return edd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1512,6 +1518,82 @@ eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, char *name, void *data, i
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int freelist_len = 0;
|
||||||
|
static int freelist_num = 0;
|
||||||
|
static void **freelist = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_add(void *data)
|
||||||
|
{
|
||||||
|
freelist_num++;
|
||||||
|
if (freelist_num > freelist_len)
|
||||||
|
{
|
||||||
|
freelist_len += 16;
|
||||||
|
freelist = realloc(freelist, freelist_len * sizeof(void *));
|
||||||
|
}
|
||||||
|
freelist[freelist_num - 1] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_reset(void)
|
||||||
|
{
|
||||||
|
freelist_len = 0;
|
||||||
|
freelist_num = 0;
|
||||||
|
if (freelist) free(freelist);
|
||||||
|
freelist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_free(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < freelist_num; i++)
|
||||||
|
free(freelist[i]);
|
||||||
|
_eet_freelist_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int freelist_list_len = 0;
|
||||||
|
static int freelist_list_num = 0;
|
||||||
|
static void ***freelist_list = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_list_add(void **data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < freelist_list_num; i++)
|
||||||
|
{
|
||||||
|
if (freelist_list[i] == data) return;
|
||||||
|
}
|
||||||
|
freelist_list_num++;
|
||||||
|
if (freelist_list_num > freelist_list_len)
|
||||||
|
{
|
||||||
|
freelist_list_len += 16;
|
||||||
|
freelist_list = realloc(freelist_list, freelist_list_len * sizeof(void *));
|
||||||
|
}
|
||||||
|
freelist_list[freelist_list_num - 1] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_list_reset(void)
|
||||||
|
{
|
||||||
|
freelist_list_len = 0;
|
||||||
|
freelist_list_num = 0;
|
||||||
|
if (freelist_list) free(freelist_list);
|
||||||
|
freelist_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eet_freelist_list_free(Eet_Data_Descriptor *edd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < freelist_list_num; i++)
|
||||||
|
edd->func.list_free(*(freelist_list[i]));
|
||||||
|
_eet_freelist_list_reset();
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
void *data_in,
|
void *data_in,
|
||||||
|
@ -1533,16 +1615,19 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
|
|
||||||
data = calloc(1, edd->size);
|
data = calloc(1, edd->size);
|
||||||
if (!data) return NULL;
|
if (!data) return NULL;
|
||||||
|
_eet_freelist_add(data);
|
||||||
chnk = eet_data_chunk_get(data_in, size_in);
|
chnk = eet_data_chunk_get(data_in, size_in);
|
||||||
if (!chnk)
|
if (!chnk)
|
||||||
{
|
{
|
||||||
free(data);
|
_eet_freelist_free();
|
||||||
|
_eet_freelist_list_free(edd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strcmp(chnk->name, edd->name))
|
if (strcmp(chnk->name, edd->name))
|
||||||
{
|
{
|
||||||
eet_data_chunk_free(chnk);
|
eet_data_chunk_free(chnk);
|
||||||
free(data);
|
_eet_freelist_free();
|
||||||
|
_eet_freelist_list_free(edd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p = chnk->data;
|
p = chnk->data;
|
||||||
|
@ -1556,8 +1641,8 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
echnk = eet_data_chunk_get(p, size);
|
echnk = eet_data_chunk_get(p, size);
|
||||||
if (!echnk)
|
if (!echnk)
|
||||||
{
|
{
|
||||||
/* FIXME: partially built data struct - leak!!!! */
|
_eet_freelist_free();
|
||||||
free(data);
|
_eet_freelist_list_free(edd);
|
||||||
eet_data_chunk_free(chnk);
|
eet_data_chunk_free(chnk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1588,6 +1673,13 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
data_ret = eet_data_descriptor_decode(ede->subtype,
|
data_ret = eet_data_descriptor_decode(ede->subtype,
|
||||||
echnk->data,
|
echnk->data,
|
||||||
echnk->size);
|
echnk->size);
|
||||||
|
if (!data_ret)
|
||||||
|
{
|
||||||
|
_eet_freelist_free();
|
||||||
|
_eet_freelist_list_free(edd);
|
||||||
|
eet_data_chunk_free(chnk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
ptr = (void **)(((char *)data) + ede->offset);
|
ptr = (void **)(((char *)data) + ede->offset);
|
||||||
*ptr = (void *)data_ret;
|
*ptr = (void *)data_ret;
|
||||||
}
|
}
|
||||||
|
@ -1618,16 +1710,26 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
data_ret = calloc(1, eet_coder[ede->type].size);
|
data_ret = calloc(1, eet_coder[ede->type].size);
|
||||||
if (data_ret)
|
if (data_ret)
|
||||||
{
|
{
|
||||||
|
_eet_freelist_add(data_ret);
|
||||||
ret = eet_data_get_type(ede->type,
|
ret = eet_data_get_type(ede->type,
|
||||||
echnk->data,
|
echnk->data,
|
||||||
((char *)echnk->data) + echnk->size,
|
((char *)echnk->data) + echnk->size,
|
||||||
data_ret);
|
data_ret);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
free(data_ret);
|
_eet_freelist_free();
|
||||||
data_ret = NULL;
|
_eet_freelist_list_free(edd);
|
||||||
|
eet_data_chunk_free(chnk);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_eet_freelist_free();
|
||||||
|
_eet_freelist_list_free(edd);
|
||||||
|
eet_data_chunk_free(chnk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ede->subtype)
|
else if (ede->subtype)
|
||||||
{
|
{
|
||||||
|
@ -1639,6 +1741,14 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
{
|
{
|
||||||
list = edd->func.list_append(list, data_ret);
|
list = edd->func.list_append(list, data_ret);
|
||||||
*ptr = list;
|
*ptr = list;
|
||||||
|
_eet_freelist_list_add(ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_eet_freelist_free();
|
||||||
|
_eet_freelist_list_free(edd);
|
||||||
|
eet_data_chunk_free(chnk);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1658,6 +1768,8 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
eet_data_chunk_free(echnk);
|
eet_data_chunk_free(echnk);
|
||||||
}
|
}
|
||||||
eet_data_chunk_free(chnk);
|
eet_data_chunk_free(chnk);
|
||||||
|
_eet_freelist_reset();
|
||||||
|
_eet_freelist_list_reset();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue