rtptheoradepay: fix in-band configuration parsing

Also make configuration header parsing a bit more relaxed with respect
to length field interpretation.
This commit is contained in:
Mark Nauwelaerts 2010-05-07 15:31:03 +02:00
parent b899afaeb6
commit 14b14fdf7a

View file

@ -191,6 +191,7 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
guint8 n_headers, b; guint8 n_headers, b;
GstRtpTheoraConfig *conf; GstRtpTheoraConfig *conf;
guint *h_sizes; guint *h_sizes;
guint extra = 1;
if (size < 6) if (size < 6)
goto too_small; goto too_small;
@ -206,7 +207,8 @@ gst_rtp_theora_depay_parse_configuration (GstRtpTheoraDepay * rtptheoradepay,
/* FIXME check if we already got this ident */ /* 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; goto too_small;
/* read header sizes we read 2 sizes, the third size (for which we allocate /* 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; goto too_small;
b = *data++; b = *data++;
size--; size--;
extra++;
h_size = (h_size << 7) | (b & 0x7f); h_size = (h_size << 7) | (b & 0x7f);
} while (b & 0x80); } while (b & 0x80);
GST_DEBUG_OBJECT (rtptheoradepay, "headers %d: size: %u", j, h_size); 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; guint h_size;
h_size = h_sizes[j]; h_size = h_sizes[j];
if (size < h_size) if (size < h_size) {
goto too_small; 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, GST_DEBUG_OBJECT (rtptheoradepay, "reading header %d, size %u", j,
h_size); h_size);
@ -265,7 +275,8 @@ too_small:
static gboolean static gboolean
gst_rtp_theora_depay_parse_inband_configuration (GstRtpTheoraDepay * 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; GstBuffer *confbuf;
guint8 *conf; guint8 *conf;
@ -274,14 +285,16 @@ gst_rtp_theora_depay_parse_inband_configuration (GstRtpTheoraDepay *
return FALSE; return FALSE;
/* transform inline to out-of-band and parse that one */ /* 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); conf = GST_BUFFER_DATA (confbuf);
/* 1 header */ /* 1 header */
GST_WRITE_UINT32_BE (conf, 1); GST_WRITE_UINT32_BE (conf, 1);
/* write Ident */ /* write Ident */
GST_WRITE_UINT24_BE (conf + 4, ident); GST_WRITE_UINT24_BE (conf + 4, ident);
/* write sort-of-length */
GST_WRITE_UINT16_BE (conf + 7, length);
/* copy remainder */ /* copy remainder */
memcpy (conf + 7, configuration + 4, size - 4); memcpy (conf + 9, configuration, size);
return gst_rtp_theora_depay_parse_configuration (rtptheoradepay, confbuf); 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)) { if (G_UNLIKELY (TDT == 1)) {
GST_DEBUG_OBJECT (rtptheoradepay, "in-band configuration"); GST_DEBUG_OBJECT (rtptheoradepay, "in-band configuration");
if (!gst_rtp_theora_depay_parse_inband_configuration (rtptheoradepay, if (!gst_rtp_theora_depay_parse_inband_configuration (rtptheoradepay,
ident, payload, payload_len)) ident, payload, payload_len, length))
goto invalid_configuration; goto invalid_configuration;
goto no_output; goto no_output;
} }