diff options
Diffstat (limited to 'ext/gd/libgd/gd_webp.c')
-rw-r--r-- | ext/gd/libgd/gd_webp.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/ext/gd/libgd/gd_webp.c b/ext/gd/libgd/gd_webp.c index 889f5f10a6..bf9ac9dd0e 100644 --- a/ext/gd/libgd/gd_webp.c +++ b/ext/gd/libgd/gd_webp.c @@ -58,11 +58,13 @@ gdImagePtr gdImageCreateFromWebpPtr (int size, void *data) return im; } +#define GD_WEBP_ALLOC_STEP (4*1024) + gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) { int width, height, ret; - unsigned char *filedata; - unsigned char dummy[1024]; + unsigned char *filedata = NULL; + unsigned char *read, *temp; unsigned char *Y = NULL; unsigned char *U = NULL; unsigned char *V = NULL; @@ -70,16 +72,25 @@ gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile) gdImagePtr im; do { - n = gdGetBuf(dummy, 1024, infile); - size += n; - } while (n != EOF); + temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP); + if (temp) { + filedata = temp; + read = temp + size; + } else { + if (filedata) { + gdFree(filedata); + } + php_gd_error("WebP decode: realloc failed"); + return NULL; + } + + n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile); + /* differs from upstream where gdGetBuf return 0 instead of EOF */ + if (n>0 && n!=EOF) { + size += n; + } + } while (n>0 && n!=EOF); - filedata = gdMalloc(size); - if (!filedata) { - php_gd_error("WebP decode: alloc failed"); - return NULL; - } - gdGetBuf(filedata, size, infile); ret = WebPDecode(filedata, size, &Y, &U, &V, &width, &height); gdFree(filedata); if (ret != webp_success) { |