summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-11-07 21:07:58 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-11-07 21:20:34 +0100
commit80cfd990740aef314b7943a3fa18c27a23f40566 (patch)
treed66dbed95c4eb72a5123217f6c616616a1ca4867
parent11649a6d779997fac59f487c76dd361cdefe73fb (diff)
downloadphp-git-80cfd990740aef314b7943a3fa18c27a23f40566.tar.gz
Reduce reallocations in exif parsing
Instead of reallocating lists element by element, increase the allocated list size exponentially.
-rw-r--r--ext/exif/exif.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 418e658bf7..53087417aa 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -1760,6 +1760,7 @@ typedef struct {
typedef struct {
int count;
+ int alloc_count;
image_info_data *list;
} image_info_list;
/* }}} */
@@ -1880,6 +1881,7 @@ typedef struct {
typedef struct {
int count;
+ int alloc_count;
file_section *list;
} file_section_list;
@@ -2004,11 +2006,14 @@ typedef struct {
*/
static int exif_file_sections_add(image_info_type *ImageInfo, int type, size_t size, uchar *data)
{
- file_section *tmp;
- int count = ImageInfo->file.count;
+ int count = ImageInfo->file.count;
+ if (count == ImageInfo->file.alloc_count) {
+ int new_alloc_count = ImageInfo->file.alloc_count ? ImageInfo->file.alloc_count * 2 : 1;
+ ImageInfo->file.list = safe_erealloc(
+ ImageInfo->file.list, new_alloc_count, sizeof(file_section), 0);
+ ImageInfo->file.alloc_count = new_alloc_count;
+ }
- tmp = safe_erealloc(ImageInfo->file.list, (count+1), sizeof(file_section), 0);
- ImageInfo->file.list = tmp;
ImageInfo->file.list[count].type = 0xFFFF;
ImageInfo->file.list[count].data = NULL;
ImageInfo->file.list[count].size = 0;
@@ -2064,6 +2069,16 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
}
/* }}} */
+static image_info_data *exif_alloc_image_info_data(image_info_list *info_list) {
+ if (info_list->count == info_list->alloc_count) {
+ int new_alloc_count = info_list->alloc_count ? info_list->alloc_count * 2 : 1;
+ info_list->list = safe_erealloc(
+ info_list->list, new_alloc_count, sizeof(image_info_data), 0);
+ info_list->alloc_count = new_alloc_count;
+ }
+ return &info_list->list[info_list->count++];
+}
+
/* {{{ exif_iif_add_value
Add a value to image_info
*/
@@ -2073,16 +2088,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
void *vptr, *vptr_end;
image_info_value *info_value;
image_info_data *info_data;
- image_info_data *list;
if (length < 0) {
return;
}
- list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
- image_info->info_list[section_index].list = list;
-
- info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ info_data = exif_alloc_image_info_data(&image_info->info_list[section_index]);
memset(info_data, 0, sizeof(image_info_data));
info_data->tag = tag;
info_data->format = format;
@@ -2205,7 +2216,6 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
}
}
image_info->sections_found |= 1<<section_index;
- image_info->info_list[section_index].count++;
}
/* }}} */
@@ -2223,20 +2233,13 @@ static void exif_iif_add_tag(image_info_type *image_info, int section_index, cha
*/
static void exif_iif_add_int(image_info_type *image_info, int section_index, char *name, int value)
{
- image_info_data *info_data;
- image_info_data *list;
-
- list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
- image_info->info_list[section_index].list = list;
-
- info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ image_info_data *info_data = exif_alloc_image_info_data(&image_info->info_list[section_index]);
info_data->tag = TAG_NONE;
info_data->format = TAG_FMT_SLONG;
info_data->length = 1;
info_data->name = estrdup(name);
info_data->value.i = value;
image_info->sections_found |= 1<<section_index;
- image_info->info_list[section_index].count++;
}
/* }}} */
@@ -2245,20 +2248,15 @@ static void exif_iif_add_int(image_info_type *image_info, int section_index, cha
*/
static void exif_iif_add_str(image_info_type *image_info, int section_index, char *name, char *value)
{
- image_info_data *info_data;
- image_info_data *list;
-
if (value) {
- list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
- image_info->info_list[section_index].list = list;
- info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ image_info_data *info_data =
+ exif_alloc_image_info_data(&image_info->info_list[section_index]);
info_data->tag = TAG_NONE;
info_data->format = TAG_FMT_STRING;
info_data->length = 1;
info_data->name = estrdup(name);
info_data->value.s = estrdup(value);
image_info->sections_found |= 1<<section_index;
- image_info->info_list[section_index].count++;
}
}
/* }}} */
@@ -2286,13 +2284,9 @@ static void exif_iif_add_fmt(image_info_type *image_info, int section_index, cha
*/
static void exif_iif_add_buffer(image_info_type *image_info, int section_index, char *name, int length, char *value)
{
- image_info_data *info_data;
- image_info_data *list;
-
if (value) {
- list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
- image_info->info_list[section_index].list = list;
- info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ image_info_data *info_data =
+ exif_alloc_image_info_data(&image_info->info_list[section_index]);
info_data->tag = TAG_NONE;
info_data->format = TAG_FMT_UNDEFINED;
info_data->length = length;
@@ -2301,7 +2295,6 @@ static void exif_iif_add_buffer(image_info_type *image_info, int section_index,
memcpy(info_data->value.s, value, length);
info_data->value.s[length] = 0;
image_info->sections_found |= 1<<section_index;
- image_info->info_list[section_index].count++;
}
}
/* }}} */