From 14b14fdf7a8067a13347ba7da954e504e37c3d7c Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 7 May 2010 15:31:03 +0200 Subject: [PATCH] rtptheoradepay: fix in-band configuration parsing Also make configuration header parsing a bit more relaxed with respect to length field interpretation. --- gst/rtp/gstrtptheoradepay.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/gst/rtp/gstrtptheoradepay.c b/gst/rtp/gstrtptheoradepay.c index e86487091d..860a1137e1 100644 --- a/gst/rtp/gstrtptheoradepay.c +++ b/gst/rtp/gstrtptheoradepay.c @@ -191,6 +191,7 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay, guint8 n_headers, b; GstRtpTheoraConfig *conf; guint *h_sizes; + guint extra = 1; if (size < 6) goto too_small; @@ -206,7 +207,8 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay, /* FIXME check if we already got this ident */ - if (size < length) + /* length might also include count of following size fields */ + if (size < length && size + 1 != length) goto too_small; /* read header sizes we read 2 sizes, the third size (for which we allocate @@ -221,6 +223,7 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay, goto too_small; b = *data++; size--; + extra++; h_size = (h_size << 7) | (b & 0x7f); } while (b & 0x80); GST_DEBUG_OBJECT (rtptheoradepay, "headers %d: size: %u", j, h_size); @@ -239,8 +242,15 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay, guint h_size; h_size = h_sizes[j]; - if (size < h_size) - goto too_small; + if (size < h_size) { + if (j != n_headers || size + extra != h_size) { + goto too_small; + } else { + /* otherwise means that overall length field contained total length, + * including extra fields */ + h_size -= extra; + } + } GST_DEBUG_OBJECT (rtptheoradepay, "reading header %d, size %u", j, h_size); @@ -265,7 +275,8 @@ too_small: static gboolean gst_rtp_theora_depay_parse_inband_configuration (GstRtpTheoraDepay * - rtptheoradepay, guint ident, guint8 * configuration, guint size) + rtptheoradepay, guint ident, guint8 * configuration, guint size, + guint length) { GstBuffer *confbuf; guint8 *conf; @@ -274,14 +285,16 @@ gst_rtp_theora_depay_parse_inband_configuration (GstRtpTheoraDepay * return FALSE; /* transform inline to out-of-band and parse that one */ - confbuf = gst_buffer_new_and_alloc (size + 3); + confbuf = gst_buffer_new_and_alloc (size + 9); conf = GST_BUFFER_DATA (confbuf); /* 1 header */ GST_WRITE_UINT32_BE (conf, 1); /* write Ident */ GST_WRITE_UINT24_BE (conf + 4, ident); + /* write sort-of-length */ + GST_WRITE_UINT16_BE (conf + 7, length); /* copy remainder */ - memcpy (conf + 7, configuration + 4, size - 4); + memcpy (conf + 9, configuration, size); return gst_rtp_theora_depay_parse_configuration (rtptheoradepay, confbuf); } @@ -550,7 +563,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) if (G_UNLIKELY (TDT == 1)) { GST_DEBUG_OBJECT (rtptheoradepay, "in-band configuration"); if (!gst_rtp_theora_depay_parse_inband_configuration (rtptheoradepay, - ident, payload, payload_len)) + ident, payload, payload_len, length)) goto invalid_configuration; goto no_output; }