comparison h264_mp4toannexb_bsf.c @ 11698:9a4c9c165b3b libavcodec

Check NAL unit size to avoid reading past the buffer. This fixes issue1907 Patch by Thomas Devanneaux gmail(thomdev)
author benoit
date Mon, 10 May 2010 07:08:57 +0000
parents 31a033fae70e
children e1e986bb64d0
comparison
equal deleted inserted replaced
11697:79a98585aa2d 11698:9a4c9c165b3b
53 uint8_t **poutbuf, int *poutbuf_size, 53 uint8_t **poutbuf, int *poutbuf_size,
54 const uint8_t *buf, int buf_size, 54 const uint8_t *buf, int buf_size,
55 int keyframe) { 55 int keyframe) {
56 H264BSFContext *ctx = bsfc->priv_data; 56 H264BSFContext *ctx = bsfc->priv_data;
57 uint8_t unit_type; 57 uint8_t unit_type;
58 uint32_t nal_size, cumul_size = 0; 58 int32_t nal_size;
59 uint32_t cumul_size = 0;
60 const uint8_t *buf_end = buf + buf_size;
59 61
60 /* nothing to filter */ 62 /* nothing to filter */
61 if (!avctx->extradata || avctx->extradata_size < 6) { 63 if (!avctx->extradata || avctx->extradata_size < 6) {
62 *poutbuf = (uint8_t*) buf; 64 *poutbuf = (uint8_t*) buf;
63 *poutbuf_size = buf_size; 65 *poutbuf_size = buf_size;
107 } 109 }
108 110
109 *poutbuf_size = 0; 111 *poutbuf_size = 0;
110 *poutbuf = NULL; 112 *poutbuf = NULL;
111 do { 113 do {
114 if (buf + ctx->length_size > buf_end)
115 goto fail;
116
112 if (ctx->length_size == 1) 117 if (ctx->length_size == 1)
113 nal_size = buf[0]; 118 nal_size = buf[0];
114 else if (ctx->length_size == 2) 119 else if (ctx->length_size == 2)
115 nal_size = AV_RB16(buf); 120 nal_size = AV_RB16(buf);
116 else 121 else
117 nal_size = AV_RB32(buf); 122 nal_size = AV_RB32(buf);
118 123
119 buf += ctx->length_size; 124 buf += ctx->length_size;
120 unit_type = *buf & 0x1f; 125 unit_type = *buf & 0x1f;
126
127 if (buf + nal_size > buf_end || nal_size < 0)
128 goto fail;
121 129
122 /* prepend only to the first type 5 NAL unit of an IDR picture */ 130 /* prepend only to the first type 5 NAL unit of an IDR picture */
123 if (ctx->first_idr && unit_type == 5) { 131 if (ctx->first_idr && unit_type == 5) {
124 alloc_and_copy(poutbuf, poutbuf_size, 132 alloc_and_copy(poutbuf, poutbuf_size,
125 ctx->sps_pps_data, ctx->size, 133 ctx->sps_pps_data, ctx->size,
137 buf += nal_size; 145 buf += nal_size;
138 cumul_size += nal_size + ctx->length_size; 146 cumul_size += nal_size + ctx->length_size;
139 } while (cumul_size < buf_size); 147 } while (cumul_size < buf_size);
140 148
141 return 1; 149 return 1;
150
151 fail:
152 av_freep(poutbuf);
153 *poutbuf_size = 0;
154 return AVERROR(EINVAL);
142 } 155 }
143 156
144 static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc) 157 static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc)
145 { 158 {
146 H264BSFContext *ctx = bsfc->priv_data; 159 H264BSFContext *ctx = bsfc->priv_data;