1919 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2020 */
2121
22+ #include "libavutil/avassert.h"
2223#include "libavutil/common.h"
2324#include "libavutil/intreadwrite.h"
2425#include "avcodec.h"
@@ -75,6 +76,12 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p,
7576 return AVERROR_PATCHWELCOME ;
7677 }
7778
79+ if (maplength > 768 ) {
80+ av_log (avctx , AV_LOG_WARNING , "invalid colormap length\n" );
81+ return AVERROR_INVALIDDATA ;
82+ }
83+
84+ // This also checks depth to be valid
7885 switch (depth ) {
7986 case 1 :
8087 avctx -> pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_MONOWHITE ;
@@ -96,15 +103,23 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p,
96103 return AVERROR_INVALIDDATA ;
97104 }
98105
106+ // This checks w and h to be valid in the sense that bytes of a padded bitmap are addressable with 32bit int
99107 ret = ff_set_dimensions (avctx , w , h );
100108 if (ret < 0 )
101109 return ret ;
102110
111+ // ensured by ff_set_dimensions()
112+ av_assert0 (w <= (INT32_MAX - 7 ) / depth );
113+
103114 /* scanlines are aligned on 16 bit boundaries */
104115 len = (depth * w + 7 ) >> 3 ;
105116 alen = len + (len & 1 );
106117
107- if (buf_end - buf < maplength + (len * h ) * 3 / 256 )
118+ // ensured by ff_set_dimensions()
119+ av_assert0 (h <= INT32_MAX / (3 * len ));
120+
121+ // maplength is limited to 768 and the right term is limited to INT32_MAX / 256 so the add needs no check
122+ if (buf_end - buf < (uint64_t )maplength + (len * h ) * 3 / 256 )
108123 return AVERROR_INVALIDDATA ;
109124
110125 if ((ret = ff_get_buffer (avctx , p , 0 )) < 0 )
@@ -118,7 +133,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, AVFrame *p,
118133 } else if (maplength ) {
119134 unsigned int len = maplength / 3 ;
120135
121- if (maplength % 3 || maplength > 768 ) {
136+ if (maplength % 3 ) {
122137 av_log (avctx , AV_LOG_WARNING , "invalid colormap length\n" );
123138 return AVERROR_INVALIDDATA ;
124139 }
0 commit comments