From b4330c730b66d280d5e7403b9be0d651db12f62d Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 31 Aug 2020 16:12:33 +0200 Subject: [PATCH] jpegdec: decode the correct number of lines for interlaced frames For interlaced jpeg, gst_jpeg_dec_decode_direct() is called twice, once for each field. In this case, stride[n] is plane_stride[n] * 2 to ensure that only every other line is written. So the loop must stop at height / num_fields. If the frame is really interlaced then continuing beyound this, is not harmful, because jpeg_read_raw_data() will do nothing and return 0, so am info message is printed. However, if the frame is not actually interlaced, just misdetected as interlaced then there is still data available from the second half of the frame. Now line[0][j] is set to the scratch buffer. If the scratch buffer is not allocated (because the height is a multiple of v_samp[0] * DCTSIZE) then the result is a segfault due to a null-pointer dereference. Part-of: --- subprojects/gst-plugins-good/ext/jpeg/gstjpegdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/jpeg/gstjpegdec.c b/subprojects/gst-plugins-good/ext/jpeg/gstjpegdec.c index dd1a039a92..c91844a078 100644 --- a/subprojects/gst-plugins-good/ext/jpeg/gstjpegdec.c +++ b/subprojects/gst-plugins-good/ext/jpeg/gstjpegdec.c @@ -880,7 +880,7 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame, gint lines, v_samp[3]; guchar *base[3], *last[3]; gint stride[3]; - guint height, field_height; + guint field_height; line[0] = y; line[1] = u; @@ -893,7 +893,7 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame, if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2)) goto format_not_supported; - height = field_height = GST_VIDEO_FRAME_HEIGHT (frame); + field_height = GST_VIDEO_FRAME_HEIGHT (frame); /* XXX: division by 2 here might not be a good idea yes. But we are doing this * already in gst_jpeg_dec_handle_frame() for interlaced jpeg */ @@ -943,7 +943,7 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame, } else #endif { - for (i = 0; i < height; i += v_samp[0] * DCTSIZE) { + for (i = 0; i < field_height; i += v_samp[0] * DCTSIZE) { for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) { /* Y */ line[0][j] = base[0] + (i + j) * stride[0];