[vlc-commits] picture: check for overflow in picture_Setup()
Rémi Denis-Courmont
git at videolan.org
Sun Feb 11 09:17:09 CET 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 10 20:57:14 2018 +0200| [50251bfbaee96d061f950dfbfc39b63797e50917] | committer: Rémi Denis-Courmont
picture: check for overflow in picture_Setup()
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=50251bfbaee96d061f950dfbfc39b63797e50917
---
src/misc/picture.c | 48 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/src/misc/picture.c b/src/misc/picture.c
index a35ff0ff15..490b4a8300 100644
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -32,6 +32,7 @@
# include "config.h"
#endif
#include <assert.h>
+#include <limits.h>
#include <vlc_common.h>
#include "picture.h"
@@ -161,9 +162,10 @@ int picture_Setup( picture_t *p_picture, const video_format_t *restrict fmt )
Which is respected if you have
V % lcm( p_dsc->p[0..planes].w.i_den * 16) == 0
*/
- int i_modulo_w = 1;
- int i_modulo_h = 1;
- unsigned int i_ratio_h = 1;
+ unsigned i_modulo_w = 1;
+ unsigned i_modulo_h = 1;
+ unsigned i_ratio_h = 1;
+
for( unsigned i = 0; i < p_dsc->plane_count; i++ )
{
i_modulo_w = LCM( i_modulo_w, 16 * p_dsc->p[i].w.den );
@@ -173,22 +175,44 @@ int picture_Setup( picture_t *p_picture, const video_format_t *restrict fmt )
}
i_modulo_h = LCM( i_modulo_h, 32 );
- const int i_width_aligned = ( fmt->i_width + i_modulo_w - 1 ) / i_modulo_w * i_modulo_w;
- const int i_height_aligned = ( fmt->i_height + i_modulo_h - 1 ) / i_modulo_h * i_modulo_h;
- const int i_height_extra = 2 * i_ratio_h; /* This one is a hack for some ASM functions */
+ unsigned width, height;
+
+ if (unlikely(add_overflow(fmt->i_width, i_modulo_w - 1, &width))
+ || unlikely(add_overflow(fmt->i_height, i_modulo_h - 1, &height)))
+ return VLC_EGENERIC;
+
+ width = width / i_modulo_w * i_modulo_w;
+ height = height / i_modulo_h * i_modulo_h;
+
+ /* Hack: append two scan lines for some SIMD assembler */
+ if (unlikely(add_overflow(height, 2 * i_ratio_h, &height)))
+ return VLC_EGENERIC;
+
+ /* plane_t uses 'int'. */
+ if (unlikely(width > INT_MAX) || unlikely(height > INT_MAX))
+ return VLC_EGENERIC;
+
for( unsigned i = 0; i < p_dsc->plane_count; i++ )
{
plane_t *p = &p_picture->p[i];
+ const vlc_rational_t *h = &p_dsc->p[i].h;
+ const vlc_rational_t *w = &p_dsc->p[i].w;
+
+ /* A plane cannot be over-sampled. This could lead to overflow. */
+ assert(h->den >= h->num);
+ assert(w->den >= w->num);
+
+ p->i_lines = height * h->num / h->den;
+ p->i_visible_lines = fmt->i_visible_height * h->num / h->den;
- p->i_lines = (i_height_aligned + i_height_extra ) * p_dsc->p[i].h.num / p_dsc->p[i].h.den;
- p->i_visible_lines = fmt->i_visible_height * p_dsc->p[i].h.num / p_dsc->p[i].h.den;
- p->i_pitch = i_width_aligned * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size;
- p->i_visible_pitch = fmt->i_visible_width * p_dsc->p[i].w.num / p_dsc->p[i].w.den * p_dsc->pixel_size;
- p->i_pixel_pitch = p_dsc->pixel_size;
+ p->i_pitch = width * w->num / w->den * p_dsc->pixel_size;
+ p->i_visible_pitch = fmt->i_visible_width * w->num / w->den
+ * p_dsc->pixel_size;
+ p->i_pixel_pitch = p_dsc->pixel_size;
assert( (p->i_pitch % 16) == 0 );
}
- p_picture->i_planes = p_dsc->plane_count;
+ p_picture->i_planes = p_dsc->plane_count;
return VLC_SUCCESS;
}
More information about the vlc-commits
mailing list