videosignal: add bound checks
authorRené Stadler <mail@renestadler.de>
Sat, 5 Sep 2009 23:44:05 +0000 (02:44 +0300)
committerRené Stadler <mail@renestadler.de>
Sat, 26 Sep 2009 16:11:09 +0000 (19:11 +0300)
gst/videosignal/gstvideodetect.c
gst/videosignal/gstvideomark.c

index c17871a9730d276156f4821edac797ae744c1028..3cdf3c661592715ecee6bd9036f8dbd09fab9bfd 100644 (file)
@@ -231,6 +231,7 @@ gst_video_detect_420 (GstVideoDetect * videodetect, GstBuffer * buffer)
 {
   gdouble brightness;
   gint i, pw, ph, stride, width, height;
+  gint req_width, req_height;
   guint8 *d, *data;
   guint pattern_data;
 
@@ -243,6 +244,14 @@ gst_video_detect_420 (GstVideoDetect * videodetect, GstBuffer * buffer)
   ph = videodetect->pattern_height;
   stride = GST_VIDEO_I420_Y_ROWSTRIDE (width);
 
+  req_width =
+      (videodetect->pattern_count + videodetect->pattern_data_count) * pw +
+      videodetect->left_offset;
+  req_height = videodetect->bottom_offset + ph;
+  if (req_width > width || req_height > height) {
+    goto no_pattern;
+  }
+
   /* analyse the bottom left pixels */
   for (i = 0; i < videodetect->pattern_count; i++) {
     d = data;
index 7f73c39f1457945cb4e985d026d7262e81118f15..10e748efead53ef9bffc1b92d3b34e27937c71f9 100644 (file)
@@ -140,10 +140,11 @@ gst_video_mark_draw_box (GstVideoMark * videomark, guint8 * data,
   }
 }
 
-static void
+static GstFlowReturn
 gst_video_mark_420 (GstVideoMark * videomark, GstBuffer * buffer)
 {
   gint i, pw, ph, stride, width, height;
+  gint req_width, req_height;
   guint8 *d, *data;
   guint pattern_shift;
   guint8 color;
@@ -157,6 +158,17 @@ gst_video_mark_420 (GstVideoMark * videomark, GstBuffer * buffer)
   ph = videomark->pattern_height;
   stride = GST_VIDEO_I420_Y_ROWSTRIDE (width);
 
+  req_width =
+      (videomark->pattern_count + videomark->pattern_data_count) * pw +
+      videomark->left_offset;
+  req_height = videomark->bottom_offset + ph;
+  if (req_width > width || req_height > height) {
+    GST_ELEMENT_ERROR (videomark, STREAM, WRONG_TYPE, (NULL),
+        ("videomark pattern doesn't fit video, need at least %ix%i (stream has %ix%i)",
+            req_width, req_height, width, height));
+    return GST_FLOW_ERROR;
+  }
+
   /* draw the bottom left pixels */
   for (i = 0; i < videomark->pattern_count; i++) {
     d = data;
@@ -198,6 +210,8 @@ gst_video_mark_420 (GstVideoMark * videomark, GstBuffer * buffer)
 
     pattern_shift >>= 1;
   }
+
+  return GST_FLOW_OK;
 }
 
 static GstFlowReturn
@@ -209,7 +223,7 @@ gst_video_mark_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
   videomark = GST_VIDEO_MARK (trans);
 
   if (videomark->enabled)
-    gst_video_mark_420 (videomark, buf);
+    return gst_video_mark_420 (videomark, buf);
 
   return ret;
 }