WebPHandler: Read all of the VP8L canvas height

In WebP lossless chunks (identified by VP8L), width-minus-1 and height-minus-1 of the canvas are sequentially encoded as 14-bit integers. (spec: https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#3_riff_header)

WebPHandler, when decoding the canvas height, has been skipping two most-significant bits. This results in bogus values being read from larger losslessly-encoded files.

Change-Id: Ib5b26f36a15fa65e7990da2ebd94157faccc70c2
(cherry picked from commit 442b73cebbea6db7b7fc945189d5776602fabc8a)
This commit is contained in:
alex4401 2025-07-18 17:47:03 +02:00 committed by jenkins-bot
parent c2566f2164
commit 849577a9b8
3 changed files with 18 additions and 2 deletions

View file

@ -277,13 +277,13 @@ class WebPHandler extends BitmapHandler {
return [];
}
// Bytes 9-12 contain the image size
// Bits 0-13 are width-1; bits 15-27 are height-1
// Bits 0-13 are width-1; bits 14-27 are height-1
$imageSize = unpack( 'C4', substr( $header, 9, 4 ) );
return [
'compression' => 'lossless',
'width' => ( $imageSize[1] | ( ( $imageSize[2] & 0x3F ) << 8 ) ) + 1,
'height' => ( ( ( $imageSize[2] & 0xC0 ) >> 6 ) |
( $imageSize[3] << 2 ) | ( ( $imageSize[4] & 0x03 ) << 10 ) ) + 1
( $imageSize[3] << 2 ) | ( ( $imageSize[4] & 0x0F ) << 10 ) ) + 1
];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -284,6 +284,22 @@ class WebPHandlerTest extends MediaWikiIntegrationTestCase {
]
]
],
// Lossless red square at max resolution to confirm height decoding
[
__DIR__ . '/../../data/media/webp_ll_large.webp',
[
'width' => 16383,
'height' => 16383,
'metadata' => [
'compression' => 'lossless',
'width' => 16383,
'height' => 16383,
'metadata' => [
'_MW_WEBP_VERSION' => 2,
],
],
]
],
// Error cases
[