mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-02-04 14:30:55 +08:00
avcode: Use av_fast_realloc() in ff_lzf_uncompress()
Fixes: 438961582/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DXV_DEC_fuzzer-5850827739955200
Fixes: mixed up realloc() functions
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Co-Authored-by: James Almer <jamrial@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 0a5046c099)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
@@ -42,7 +42,7 @@ typedef struct DXVContext {
|
||||
uint8_t *ctex_data; // Compressed chroma texture
|
||||
unsigned ctex_data_size;
|
||||
|
||||
int64_t tex_size; // Texture size
|
||||
size_t tex_size; // Texture size
|
||||
int64_t ctex_size; // Chroma texture size
|
||||
|
||||
uint8_t *op_data[4]; // Opcodes
|
||||
@@ -828,7 +828,7 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx)
|
||||
static int dxv_decompress_lzf(AVCodecContext *avctx)
|
||||
{
|
||||
DXVContext *ctx = avctx->priv_data;
|
||||
return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size);
|
||||
return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size, &ctx->tex_data_size);
|
||||
}
|
||||
|
||||
static int dxv_decompress_raw(AVCodecContext *avctx)
|
||||
|
||||
@@ -37,7 +37,22 @@
|
||||
#define LZF_LITERAL_MAX (1 << 5)
|
||||
#define LZF_LONG_BACKREF 7 + 2
|
||||
|
||||
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
|
||||
|
||||
static inline int lzf_realloc(uint8_t **buf, size_t *size, int addition, unsigned *allocated_size)
|
||||
{
|
||||
void *ptr = av_fast_realloc(*buf, allocated_size, *size + addition);
|
||||
|
||||
if (!ptr) {
|
||||
av_freep(buf); //probably not needed
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
*buf = ptr;
|
||||
*size += addition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned *allocated_size)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t *p = *buf;
|
||||
@@ -49,8 +64,7 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
|
||||
if (s < LZF_LITERAL_MAX) {
|
||||
s++;
|
||||
if (s > *size - len) {
|
||||
*size += s + *size /2;
|
||||
ret = av_reallocp(buf, *size);
|
||||
ret = lzf_realloc(buf, size, s, allocated_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
p = *buf + len;
|
||||
@@ -75,8 +89,7 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (l > *size - len) {
|
||||
*size += l + *size / 2;
|
||||
ret = av_reallocp(buf, *size);
|
||||
ret = lzf_realloc(buf, size, l, allocated_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
p = *buf + len;
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size);
|
||||
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned *allocated_size);
|
||||
|
||||
#endif /* AVCODEC_LZF_H */
|
||||
|
||||
@@ -40,7 +40,8 @@ typedef struct NotchLCContext {
|
||||
unsigned uncompressed_size;
|
||||
|
||||
uint8_t *lzf_buffer;
|
||||
int64_t lzf_size;
|
||||
size_t lzf_size;
|
||||
unsigned lzf_alloc_size;
|
||||
|
||||
unsigned texture_size_x;
|
||||
unsigned texture_size_y;
|
||||
@@ -490,7 +491,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
|
||||
return AVERROR_PATCHWELCOME;
|
||||
|
||||
if (s->format == 0) {
|
||||
ret = ff_lzf_uncompress(gb, &s->lzf_buffer, &s->lzf_size);
|
||||
ret = ff_lzf_uncompress(gb, &s->lzf_buffer, &s->lzf_size, &s->lzf_alloc_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user