diff options
author | Miguel Paris <mparisparis@gmail.com> | 2016-11-25 10:48:06 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-11-25 13:15:24 +0200 |
commit | 036bdf5d2d44facdcf4116ac90d3df29cbd96b8d (patch) | |
tree | ab10590935a41932d5baccaa828264279d2b223a | |
parent | 47fdb15074fb4bebf20bf63f857b82d784b96919 (diff) |
rtpbuffer: Fix ensure_buffers() if whole packet is in one GstMemory
When gst_rtp_buffer_add_extension_onebyte_header() is used over a
GstRtpBuffer that only contains a memory for the whole packet,
ensure_buffers function crashes at the next point:
mem = gst_memory_copy (rtp->map[i].memory, offset, rtp->size[i]);
when i==2 because the payload is not mapped.
In addition the offset is calculated subtracting in the wrong direction.
https://bugzilla.gnome.org/show_bug.cgi?id=774959
-rw-r--r-- | gst-libs/gst/rtp/gstrtpbuffer.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c index 16e740c25..9cb3e8ba7 100644 --- a/gst-libs/gst/rtp/gstrtpbuffer.c +++ b/gst-libs/gst/rtp/gstrtpbuffer.c @@ -757,20 +757,45 @@ gst_rtp_buffer_get_extension_bytes (GstRTPBuffer * rtp, guint16 * bits) return g_bytes_new (buf_data, 4 * buf_len); } +static gboolean +gst_rtp_buffer_map_payload (GstRTPBuffer * rtp) +{ + guint hlen, plen; + guint idx, length; + gsize skip; + + if (rtp->map[2].memory != NULL) + return TRUE; + + hlen = gst_rtp_buffer_get_header_len (rtp); + plen = gst_buffer_get_size (rtp->buffer) - hlen - rtp->size[3]; + + if (!gst_buffer_find_memory (rtp->buffer, hlen, plen, &idx, &length, &skip)) + return FALSE; + + if (!gst_buffer_map_range (rtp->buffer, idx, length, &rtp->map[2], + rtp->map[0].flags)) + return FALSE; + + rtp->data[2] = rtp->map[2].data + skip; + rtp->size[2] = plen; + + return TRUE; +} + /* ensure header, payload and padding are in separate buffers */ static void ensure_buffers (GstRTPBuffer * rtp) { guint i, pos; - gsize offset; gboolean changed = FALSE; /* make sure payload is mapped */ - gst_rtp_buffer_get_payload (rtp); + gst_rtp_buffer_map_payload (rtp); for (i = 0, pos = 0; i < 4; i++) { if (rtp->size[i]) { - offset = rtp->map[i].data - (guint8 *) rtp->data[i]; + gsize offset = (guint8 *) rtp->data[i] - rtp->map[i].data; if (offset != 0 || rtp->map[i].size != rtp->size[i]) { GstMemory *mem; @@ -1140,26 +1165,12 @@ gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp) gpointer gst_rtp_buffer_get_payload (GstRTPBuffer * rtp) { - guint hlen, plen; - guint idx, length; - gsize skip; - if (rtp->data[2]) return rtp->data[2]; - hlen = gst_rtp_buffer_get_header_len (rtp); - plen = gst_buffer_get_size (rtp->buffer) - hlen - rtp->size[3]; - - if (!gst_buffer_find_memory (rtp->buffer, hlen, plen, &idx, &length, &skip)) + if (!gst_rtp_buffer_map_payload (rtp)) return NULL; - if (!gst_buffer_map_range (rtp->buffer, idx, length, &rtp->map[2], - rtp->map[0].flags)) - return NULL; - - rtp->data[2] = rtp->map[2].data + skip; - rtp->size[2] = plen; - return rtp->data[2]; } |