summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmb@php.net>2015-07-19 17:32:53 +0200
committerChristoph M. Becker <cmb@php.net>2015-07-19 17:38:04 +0200
commit96e42403d5e5e3e9c39522bda3017b03a8fe2ebc (patch)
tree4a78c6fe48c93fc4a3101ae641b914d5d1befc7f
parentabc3598f4729a5e4e3a787d2610a03e978199941 (diff)
downloadphp-git-96e42403d5e5e3e9c39522bda3017b03a8fe2ebc.tar.gz
Fix #66590: imagewebp() doesn't pad to even length
The code in the bundled libgd uses libvpx and writes the riff manually. The code generates the correct even size, but neglects the padding. It's possible older versions of libwebp would decode this, but libwebp 0.4.0 does not. Let's apply the patch supplied by one of the WebP developers.
-rw-r--r--ext/gd/libgd/webpimg.c13
-rw-r--r--ext/gd/tests/bug66590.phpt27
2 files changed, 40 insertions, 0 deletions
diff --git a/ext/gd/libgd/webpimg.c b/ext/gd/libgd/webpimg.c
index 4962c22e6c..1b160232f2 100644
--- a/ext/gd/libgd/webpimg.c
+++ b/ext/gd/libgd/webpimg.c
@@ -779,6 +779,19 @@ WebPResult WebPEncode(const uint8* Y,
(chunk_size >> 24) & 255 };
memcpy(*p_out, kRiffHeader, kRiffHeaderSize);
+ if (img_size_bytes & 1) { /* write a padding byte */
+ const int new_size = *p_out_size_bytes + 1;
+ unsigned char* p = (unsigned char*)realloc(*p_out, new_size);
+ if (p == NULL) {
+ free(*p_out);
+ *p_out = NULL;
+ *p_out_size_bytes = 0;
+ return webp_failure;
+ }
+ p[new_size - 1] = 0;
+ *p_out_size_bytes = new_size;
+ }
+
if (psnr) {
*psnr = WebPGetPSNR(Y, U, V, *p_out, *p_out_size_bytes);
}
diff --git a/ext/gd/tests/bug66590.phpt b/ext/gd/tests/bug66590.phpt
new file mode 100644
index 0000000000..a3c5409d6b
--- /dev/null
+++ b/ext/gd/tests/bug66590.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #66590 (imagewebp() doesn't pad to even length)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+if (!function_exists('imagewebp')) die('skip WebP support not available');
+?>
+--FILE--
+<?php
+$filename = __DIR__ . '/bug66590.webp';
+$im = imagecreatetruecolor(75, 75);
+$red = imagecolorallocate($im, 255, 0, 0);
+imagefilledrectangle($im, 0, 0, 74, 74, $red);
+imagewebp($im, $filename);
+$stream = fopen($filename, 'rb');
+fread($stream, 4); // skip "RIFF"
+$length = fread($stream, 4);
+fclose($stream);
+$length = unpack('V', $length)[1] + 8;
+var_dump($length === filesize($filename));
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/bug66590.webp');
+?>
+--EXPECT--
+bool(true)