mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
video-info: Sanity check the frame size to prevent overflows
https://bugzilla.gnome.org/show_bug.cgi?id=774588
This commit is contained in:
parent
a4c1dfe4cd
commit
17cdd369e6
2 changed files with 35 additions and 12 deletions
|
@ -106,7 +106,7 @@ gst_video_info_new (void)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_planes (GstVideoInfo * info);
|
static gboolean fill_planes (GstVideoInfo * info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_video_info_init:
|
* gst_video_info_init:
|
||||||
|
@ -205,13 +205,16 @@ validate_colorimetry (GstVideoInfo * info)
|
||||||
* Note: This initializes @info first, no values are preserved. This function
|
* Note: This initializes @info first, no values are preserved. This function
|
||||||
* does not set the offsets correctly for interlaced vertically
|
* does not set the offsets correctly for interlaced vertically
|
||||||
* subsampled formats.
|
* subsampled formats.
|
||||||
|
*
|
||||||
|
* Returns: %FALSE if the returned video info is invalid, e.g. because the
|
||||||
|
* size of a frame can't be represented as a 32 bit integer (Since: 1.12)
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
|
gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
|
||||||
guint width, guint height)
|
guint width, guint height)
|
||||||
{
|
{
|
||||||
g_return_if_fail (info != NULL);
|
g_return_val_if_fail (info != NULL, FALSE);
|
||||||
g_return_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN);
|
g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
|
||||||
|
|
||||||
gst_video_info_init (info);
|
gst_video_info_init (info);
|
||||||
|
|
||||||
|
@ -222,7 +225,7 @@ gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
|
||||||
|
|
||||||
set_default_colorimetry (info);
|
set_default_colorimetry (info);
|
||||||
|
|
||||||
fill_planes (info);
|
return fill_planes (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar *interlace_mode[] = {
|
static const gchar *interlace_mode[] = {
|
||||||
|
@ -461,7 +464,8 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
|
||||||
set_default_colorimetry (info);
|
set_default_colorimetry (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_planes (info);
|
if (!fill_planes (info))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -667,14 +671,25 @@ gst_video_info_to_caps (GstVideoInfo * info)
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static gboolean
|
||||||
fill_planes (GstVideoInfo * info)
|
fill_planes (GstVideoInfo * info)
|
||||||
{
|
{
|
||||||
gsize width, height, cr_h;
|
gsize width, height, cr_h;
|
||||||
|
gint bpp = 0, i;
|
||||||
|
|
||||||
width = (gsize) info->width;
|
width = (gsize) info->width;
|
||||||
height = (gsize) info->height;
|
height = (gsize) info->height;
|
||||||
|
|
||||||
|
/* Sanity check the resulting frame size for overflows */
|
||||||
|
for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
|
||||||
|
bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
|
||||||
|
bpp = GST_ROUND_UP_8 (bpp) / 8;
|
||||||
|
if (GST_ROUND_UP_128 ((guint64) width) * ((guint64) height) * bpp >=
|
||||||
|
G_MAXUINT) {
|
||||||
|
GST_ERROR ("Frame size %ux%u would overflow", info->width, info->height);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (info->finfo->format) {
|
switch (info->finfo->format) {
|
||||||
case GST_VIDEO_FORMAT_YUY2:
|
case GST_VIDEO_FORMAT_YUY2:
|
||||||
case GST_VIDEO_FORMAT_YVYU:
|
case GST_VIDEO_FORMAT_YVYU:
|
||||||
|
@ -959,9 +974,10 @@ fill_planes (GstVideoInfo * info)
|
||||||
case GST_VIDEO_FORMAT_UNKNOWN:
|
case GST_VIDEO_FORMAT_UNKNOWN:
|
||||||
GST_ERROR ("invalid format");
|
GST_ERROR ("invalid format");
|
||||||
g_warning ("invalid format");
|
g_warning ("invalid format");
|
||||||
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1100,8 +1116,11 @@ done:
|
||||||
*
|
*
|
||||||
* Extra padding will be added to the right side when stride alignment padding
|
* Extra padding will be added to the right side when stride alignment padding
|
||||||
* is required and @align will be updated with the new padding values.
|
* is required and @align will be updated with the new padding values.
|
||||||
|
*
|
||||||
|
* Returns: %FALSE if alignment could not be applied, e.g. because the
|
||||||
|
* size of a frame can't be represented as a 32 bit integer (Since: 1.12)
|
||||||
*/
|
*/
|
||||||
void
|
gboolean
|
||||||
gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
|
gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
|
||||||
{
|
{
|
||||||
const GstVideoFormatInfo *vinfo = info->finfo;
|
const GstVideoFormatInfo *vinfo = info->finfo;
|
||||||
|
@ -1153,7 +1172,9 @@ gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
|
||||||
|
|
||||||
info->width = padded_width;
|
info->width = padded_width;
|
||||||
info->height = padded_height;
|
info->height = padded_height;
|
||||||
fill_planes (info);
|
|
||||||
|
if (!fill_planes (info))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* check alignment */
|
/* check alignment */
|
||||||
aligned = TRUE;
|
aligned = TRUE;
|
||||||
|
@ -1196,4 +1217,6 @@ gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
|
||||||
info->offset[i] += (vedge * info->stride[i]) +
|
info->offset[i] += (vedge * info->stride[i]) +
|
||||||
(hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));
|
(hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ void gst_video_info_init (GstVideoInfo *info);
|
||||||
GstVideoInfo * gst_video_info_copy (const GstVideoInfo *info);
|
GstVideoInfo * gst_video_info_copy (const GstVideoInfo *info);
|
||||||
void gst_video_info_free (GstVideoInfo *info);
|
void gst_video_info_free (GstVideoInfo *info);
|
||||||
|
|
||||||
void gst_video_info_set_format (GstVideoInfo *info, GstVideoFormat format,
|
gboolean gst_video_info_set_format (GstVideoInfo *info, GstVideoFormat format,
|
||||||
guint width, guint height);
|
guint width, guint height);
|
||||||
|
|
||||||
gboolean gst_video_info_from_caps (GstVideoInfo *info, const GstCaps * caps);
|
gboolean gst_video_info_from_caps (GstVideoInfo *info, const GstCaps * caps);
|
||||||
|
@ -385,7 +385,7 @@ gboolean gst_video_info_is_equal (const GstVideoInfo *info,
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
void gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align);
|
gboolean gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align);
|
||||||
|
|
||||||
|
|
||||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||||
|
|
Loading…
Reference in a new issue