ALPHInit: move assignment closer to first use

This fixes a spurious unsigned integer overflow with invalid content:

```
src/dec/alpha_dec.c:61:44: runtime error: unsigned integer overflow: 0 -
  1 cannot be represented in type 'size_t' (aka 'unsigned long')
```

Bug: 498965803, 498966235, 498966511, 498967090
Change-Id: I350d9144d0c1e4e35286e9e1ca68a574ff6f86a1
This commit is contained in:
James Zern
2026-04-02 10:20:09 -07:00
parent 0c9546f7ef
commit c696aadf69
5 changed files with 76 additions and 11 deletions

View File

@@ -58,7 +58,6 @@ WEBP_NODISCARD static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
uint8_t* output) {
int ok = 0;
const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
int rsrv;
VP8Io* const io = &dec->io;
@@ -101,6 +100,8 @@ WEBP_NODISCARD static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
io->crop_bottom = src_io->crop_bottom;
// No need to copy the scaling parameters.
{
const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
if (dec->method == ALPHA_NO_COMPRESSION) {
const size_t alpha_decoded_size = dec->width * dec->height;
ok = (alpha_data_size >= alpha_decoded_size);
@@ -113,6 +114,7 @@ WEBP_NODISCARD static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
ok = VP8LDecodeAlphaHeader(dec, bounded_alpha_data, alpha_data_size);
}
}
}
return ok;
}

View File

@@ -18,9 +18,11 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <string_view>
#include "./fuzz_utils.h"
#include "gtest/gtest.h"
#include "src/dec/webpi_dec.h"
#include "src/utils/rescaler_utils.h"
#include "webp/decode.h"
@@ -162,3 +164,25 @@ FUZZ_TEST(AdvancedApi, AdvancedApiTest)
#endif
/*incremental=*/fuzztest::Arbitrary<bool>(),
fuzz_utils::ArbitraryValidWebPDecoderOptions());
TEST(AdvancedApi, Buganizer498966235) {
AdvancedApiTest(
std::string(
"RIFF\014|"
"\000\000WEBPVP8X\n\000\000\000\020\000\000D\002\000\000\017\000\000A"
"LPH5\000\000\000\004\327\000\000\000\000\000\000c8\345S\000\243\000"
"\253c\311\000\027\000\000\000\200\000\000\000\000\240\"AE\001\000"
"\000\0008<"
"ALP\010\000s\002\000\000\000\000\000\000\000\000\000ALPH\000\000\000"
"\000VP8 "
"(\000\000\000\224\001\000\235\001*\003\000\020\000\003,\000~"
"\342\000\000se\002ionR\265Vq\302M}\"webp\"r\010\003\000\020#"
"\366\356\002\323\220\000 "
"\212N@\000\026\327A\367\266\201\201\"IFF@\"RIFF\"&\226!"
"VP\n8Rg\000\0001\"\335\"I\"XEBP\"\002\002\"\367\\x0\203\203\203\341"
"\341l,\203\\sectiqncJUN=\"sectistre\\x9D\\x01\\x2A\"JUKQ\"",
257),
68, 3, true,
fuzz_utils::WebPDecoderOptionsCpp{
0, 0, 1, 5, 10, 5, 9, 0, 1, 3, 0, 72, 0, 83, {0, 0, 0, 0, 0}});
}

View File

@@ -16,9 +16,11 @@
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include "./fuzz_utils.h"
#include "gtest/gtest.h"
#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/mux_types.h"
@@ -88,3 +90,15 @@ FUZZ_TEST(AnimationApi, AnimationApiTest)
// Animations only support 4 (out of 12) modes.
fuzztest::ElementOf<WEBP_CSP_MODE>({MODE_RGBA, MODE_BGRA,
MODE_rgbA, MODE_bgrA}));
TEST(AnimationApi, Buganizer498965803) {
AnimationApiTest(
std::string("ALPH\000\000\000\000\000\000\000\000\021\000\000\000\t\305"
"\006d\301\013\177\000\000webp\034\205\000#@VP8 "
"!\000\000\000v\003\000\235\001*\007\200\"\000\0020("
"\000\377\377\377\003\000\000\000\311\311\311\311\311\311\311"
"\311\311\311\311\311\311\311\311\311\311\311\311\311\311\211"
"\311\311\311\311\311\030\030\030\030\030\030\311\311",
98),
false, static_cast<WEBP_CSP_MODE>(1));
}

View File

@@ -16,10 +16,12 @@
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include "./fuzz_utils.h"
#include "./nalloc.h"
#include "gtest/gtest.h"
#include "imageio/imageio_util.h"
#include "webp/decode.h"
#include "webp/demux.h"
@@ -79,3 +81,12 @@ End:
FUZZ_TEST(AnimDecoder, AnimDecoderTest)
.WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
1));
TEST(AnimDecoder, Buganizer498967090) {
AnimDecoderTest(std::string(
"ALPH\000\000\000\000\000\000\000\000\003\000\000\000\014EBPVP8 "
"\030\000\000\0000\001\000\235\001*\002\000\001\000\003\0004%"
"\244\000\003~\000*\316\373\224\"AFM\"<0\334\"\231J\002`"
"\256\233\233\233\233\272\000\000",
72));
}

View File

@@ -17,9 +17,11 @@
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <string_view>
#include "./fuzz_utils.h"
#include "gtest/gtest.h"
#include "webp/decode.h"
#include "webp/types.h"
@@ -101,3 +103,15 @@ void SimpleApiTest(std::string_view data_in) {
FUZZ_TEST(SimpleApi, SimpleApiTest)
.WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
1));
TEST(SimpleApi, Buganizer498966511) {
SimpleApiTest(
std::string("ALPH\004\000\000\000A\377\377\377\377LP\010\000\000\000\000"
"\000\000\311H\006\000\000\000\"E\356PW\"ALPH\000\000\000\000"
"ALpH\004\000\000\000\004\010\000\200VP8 "
"T\000\000\000\266\003\000\235\001*"
"\001\000\002\000y\336n\366\001O\363\374\243\000\003LPS\"\002"
"iF\000FjRsa\232vP\"EO\"K\217OM;rOect\275n\"Wsection_JUNQ="
"\"JUNQ\"\250YO,_I\362\021\"ANIM\"",
150));
}