mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-27 05:00:37 +00:00
Merge commit '0a467a9b594dd67aa96bad687d05f8845b009f18'
* commit '0a467a9b594dd67aa96bad687d05f8845b009f18':
tiffdec: use bytestream2 to simplify overread/overwrite protection
Conflicts:
libavcodec/tiff.c
See: 1ec83d9a9e
Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
94cf83ff91
@ -383,9 +383,10 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
|
||||
static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
|
||||
const uint8_t *src, int size, int lines)
|
||||
{
|
||||
PutByteContext pb;
|
||||
int c, line, pixels, code, ret;
|
||||
const uint8_t *ssrc = src;
|
||||
int width = ((s->width * s->bpp) + 7) >> 3;
|
||||
int width = ((s->width * s->bpp) + 7) >> 3;
|
||||
|
||||
if (s->planar)
|
||||
width /= s->bppcount;
|
||||
@ -416,21 +417,42 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
|
||||
return ret;
|
||||
}
|
||||
for (line = 0; line < lines; line++) {
|
||||
pixels = ff_lzw_decode(s->lzw, dst, width);
|
||||
if (pixels < width) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
|
||||
pixels, width);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
|
||||
horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
|
||||
dst += stride;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (s->compr == TIFF_CCITT_RLE ||
|
||||
s->compr == TIFF_G3 ||
|
||||
s->compr == TIFF_G4) {
|
||||
return tiff_unpack_fax(s, dst, stride, src, size, width, lines);
|
||||
}
|
||||
|
||||
bytestream2_init(&s->gb, src, size);
|
||||
bytestream2_init_writer(&pb, dst, stride * lines);
|
||||
|
||||
for (line = 0; line < lines; line++) {
|
||||
if (src - ssrc > size) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (bytestream2_get_bytes_left(&s->gb) == 0 || bytestream2_get_eof(&pb))
|
||||
break;
|
||||
bytestream2_seek_p(&pb, stride * line, SEEK_SET);
|
||||
switch (s->compr) {
|
||||
case TIFF_RAW:
|
||||
if (ssrc + size - src < width)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (!s->fill_order) {
|
||||
horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
|
||||
dst, 1, src, 0, width, 0);
|
||||
@ -479,16 +501,6 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
|
||||
dst[i] = ff_reverse[dst[i]];
|
||||
}
|
||||
break;
|
||||
case TIFF_LZW:
|
||||
pixels = ff_lzw_decode(s->lzw, dst, width);
|
||||
if (pixels < width) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
|
||||
pixels, width);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
|
||||
horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
|
||||
break;
|
||||
}
|
||||
dst += stride;
|
||||
}
|
||||
@ -580,7 +592,8 @@ static void set_sar(TiffContext *s, unsigned tag, unsigned num, unsigned den)
|
||||
static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
|
||||
{
|
||||
unsigned tag, type, count, off, value = 0, value2 = 0;
|
||||
int i, j, k, pos, start;
|
||||
int i, start;
|
||||
int j, k, pos;
|
||||
int ret;
|
||||
uint32_t *pal;
|
||||
double *dp;
|
||||
@ -702,35 +715,25 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
|
||||
break;
|
||||
case TIFF_STRIP_OFFS:
|
||||
if (count == 1) {
|
||||
s->strippos = 0;
|
||||
s->stripoff = value;
|
||||
s->strippos = 0;
|
||||
s->stripoff = value;
|
||||
} else
|
||||
s->strippos = off;
|
||||
s->strips = count;
|
||||
if (s->strips == 1)
|
||||
s->rps = s->height;
|
||||
s->sot = type;
|
||||
if (s->strippos > bytestream2_size(&s->gb)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR,
|
||||
"Tag referencing position outside the image\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
break;
|
||||
case TIFF_STRIP_SIZE:
|
||||
if (count == 1) {
|
||||
s->stripsizesoff = 0;
|
||||
s->stripsize = value;
|
||||
s->strips = 1;
|
||||
s->stripsize = value;
|
||||
s->strips = 1;
|
||||
} else {
|
||||
s->stripsizesoff = off;
|
||||
}
|
||||
s->strips = count;
|
||||
s->sstype = type;
|
||||
if (s->stripsizesoff > bytestream2_size(&s->gb)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR,
|
||||
"Tag referencing position outside the image\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
break;
|
||||
case TIFF_XRES:
|
||||
case TIFF_YRES:
|
||||
@ -771,11 +774,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
|
||||
}
|
||||
s->fill_order = value - 1;
|
||||
break;
|
||||
case TIFF_PAL:
|
||||
case TIFF_PAL: {
|
||||
pal = (uint32_t *) s->palette;
|
||||
off = type_sizes[type];
|
||||
if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
|
||||
if (count / 3 > 256 ||
|
||||
bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
off = (type_sizes[type] - 1) << 3;
|
||||
for (k = 2; k >= 0; k--) {
|
||||
for (i = 0; i < count / 3; i++) {
|
||||
@ -787,6 +792,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
|
||||
}
|
||||
s->palette_is_set = 1;
|
||||
break;
|
||||
}
|
||||
case TIFF_PLANAR:
|
||||
s->planar = value == 2;
|
||||
break;
|
||||
@ -1019,12 +1025,14 @@ static int decode_frame(AVCodecContext *avctx,
|
||||
if (s->stripsizesoff) {
|
||||
if (s->stripsizesoff >= (unsigned)avpkt->size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, avpkt->size - s->stripsizesoff);
|
||||
bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
|
||||
avpkt->size - s->stripsizesoff);
|
||||
}
|
||||
if (s->strippos) {
|
||||
if (s->strippos >= (unsigned)avpkt->size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
bytestream2_init(&stripdata, avpkt->data + s->strippos, avpkt->size - s->strippos);
|
||||
bytestream2_init(&stripdata, avpkt->data + s->strippos,
|
||||
avpkt->size - s->strippos);
|
||||
}
|
||||
|
||||
if (s->rps <= 0) {
|
||||
@ -1038,12 +1046,12 @@ static int decode_frame(AVCodecContext *avctx,
|
||||
dst = p->data[plane];
|
||||
for (i = 0; i < s->height; i += s->rps) {
|
||||
if (s->stripsizesoff)
|
||||
ssize = ff_tget(&stripsizes, s->sstype, s->le);
|
||||
ssize = ff_tget(&stripsizes, s->sstype, le);
|
||||
else
|
||||
ssize = s->stripsize;
|
||||
|
||||
if (s->strippos)
|
||||
soff = ff_tget(&stripdata, s->sot, s->le);
|
||||
soff = ff_tget(&stripdata, s->sot, le);
|
||||
else
|
||||
soff = s->stripoff;
|
||||
|
||||
|
@ -42,15 +42,13 @@ int ff_tis_ifd(unsigned tag)
|
||||
|
||||
unsigned ff_tget_short(GetByteContext *gb, int le)
|
||||
{
|
||||
unsigned v = le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
|
||||
return v;
|
||||
return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb);
|
||||
}
|
||||
|
||||
|
||||
unsigned ff_tget_long(GetByteContext *gb, int le)
|
||||
{
|
||||
unsigned v = le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
|
||||
return v;
|
||||
return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb);
|
||||
}
|
||||
|
||||
|
||||
@ -64,14 +62,10 @@ double ff_tget_double(GetByteContext *gb, int le)
|
||||
unsigned ff_tget(GetByteContext *gb, int type, int le)
|
||||
{
|
||||
switch (type) {
|
||||
case TIFF_BYTE:
|
||||
return bytestream2_get_byte(gb);
|
||||
case TIFF_SHORT:
|
||||
return ff_tget_short(gb, le);
|
||||
case TIFF_LONG:
|
||||
return ff_tget_long(gb, le);
|
||||
default:
|
||||
return UINT_MAX;
|
||||
case TIFF_BYTE: return bytestream2_get_byte(gb);
|
||||
case TIFF_SHORT: return ff_tget_short(gb, le);
|
||||
case TIFF_LONG: return ff_tget_long(gb, le);
|
||||
default: return UINT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user