mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 05:38:58 +00:00
vorbisdepay: fix some leaks
And leak the codebooks. Use glib base64 decoders. Use subbuffers to avoid a memcpy of the headers.
This commit is contained in:
parent
8f8e035cd5
commit
06efeff5d9
1 changed files with 52 additions and 57 deletions
|
@ -119,6 +119,33 @@ gst_rtp_vorbis_depay_init (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
{
|
{
|
||||||
rtpvorbisdepay->adapter = gst_adapter_new ();
|
rtpvorbisdepay->adapter = gst_adapter_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_config (GstRtpVorbisConfig * conf)
|
||||||
|
{
|
||||||
|
GList *headers;
|
||||||
|
|
||||||
|
for (headers = conf->headers; headers; headers = g_list_next (headers)) {
|
||||||
|
GstBuffer *header = GST_BUFFER_CAST (headers->data);
|
||||||
|
|
||||||
|
gst_buffer_unref (header);
|
||||||
|
}
|
||||||
|
g_list_free (conf->headers);
|
||||||
|
g_free (conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_indents (GstRtpVorbisDepay * rtpvorbisdepay)
|
||||||
|
{
|
||||||
|
GList *walk;
|
||||||
|
|
||||||
|
for (walk = rtpvorbisdepay->configs; walk; walk = g_list_next (walk)) {
|
||||||
|
free_config ((GstRtpVorbisConfig *) walk->data);
|
||||||
|
}
|
||||||
|
g_list_free (rtpvorbisdepay->configs);
|
||||||
|
rtpvorbisdepay->configs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_vorbis_depay_finalize (GObject * object)
|
gst_rtp_vorbis_depay_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -129,54 +156,6 @@ gst_rtp_vorbis_depay_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const guint8 a2bin[256] = {
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
|
|
||||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
||||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
|
|
||||||
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
|
||||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint
|
|
||||||
decode_base64 (const gchar * in, guint8 * out)
|
|
||||||
{
|
|
||||||
guint8 v1, v2;
|
|
||||||
guint len = 0;
|
|
||||||
|
|
||||||
v1 = a2bin[(gint) * in];
|
|
||||||
while (v1 <= 63) {
|
|
||||||
/* read 4 bytes, write 3 bytes, invalid base64 are zeroes */
|
|
||||||
v2 = a2bin[(gint) * ++in];
|
|
||||||
*out++ = (v1 << 2) | ((v2 & 0x3f) >> 4);
|
|
||||||
v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
|
|
||||||
*out++ = (v2 << 4) | ((v1 & 0x3f) >> 2);
|
|
||||||
v2 = (v1 > 63 ? 64 : a2bin[(gint) * ++in]);
|
|
||||||
*out++ = (v1 << 6) | (v2 & 0x3f);
|
|
||||||
v1 = (v2 > 63 ? 64 : a2bin[(gint) * ++in]);
|
|
||||||
len += 3;
|
|
||||||
}
|
|
||||||
/* move to '\0' */
|
|
||||||
while (*in != '\0')
|
|
||||||
in++;
|
|
||||||
|
|
||||||
/* subtract padding */
|
|
||||||
while (len > 0 && *--in == '=')
|
|
||||||
len--;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
const gchar * configuration)
|
const gchar * configuration)
|
||||||
|
@ -184,15 +163,18 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
guint32 num_headers;
|
guint32 num_headers;
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
guint size;
|
GstBuffer *confbuf;
|
||||||
|
gsize size;
|
||||||
|
guint offset;
|
||||||
gint i, j;
|
gint i, j;
|
||||||
|
|
||||||
/* deserialize base64 to buffer */
|
/* deserialize base64 to buffer */
|
||||||
size = strlen (configuration);
|
data = g_base64_decode (configuration, &size);
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "base64 config size %u", size);
|
|
||||||
|
|
||||||
data = g_malloc (size);
|
confbuf = gst_buffer_new ();
|
||||||
size = decode_base64 (configuration, data);
|
GST_BUFFER_DATA (confbuf) = data;
|
||||||
|
GST_BUFFER_MALLOCDATA (confbuf) = data;
|
||||||
|
GST_BUFFER_SIZE (confbuf) = size;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %u", size);
|
GST_DEBUG_OBJECT (rtpvorbisdepay, "config size %u", size);
|
||||||
|
|
||||||
|
@ -215,6 +197,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
num_headers = GST_READ_UINT32_BE (data);
|
num_headers = GST_READ_UINT32_BE (data);
|
||||||
size -= 4;
|
size -= 4;
|
||||||
data += 4;
|
data += 4;
|
||||||
|
offset = 4;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "have %u headers", num_headers);
|
GST_DEBUG_OBJECT (rtpvorbisdepay, "have %u headers", num_headers);
|
||||||
|
|
||||||
|
@ -257,6 +240,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
n_headers = data[5];
|
n_headers = data[5];
|
||||||
size -= 6;
|
size -= 6;
|
||||||
data += 6;
|
data += 6;
|
||||||
|
offset += 6;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay,
|
GST_DEBUG_OBJECT (rtpvorbisdepay,
|
||||||
"header %d, ident 0x%08x, length %u, left %u", i, ident, length, size);
|
"header %d, ident 0x%08x, length %u, left %u", i, ident, length, size);
|
||||||
|
@ -275,10 +259,15 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
goto too_small;
|
goto too_small;
|
||||||
b = *data++;
|
b = *data++;
|
||||||
|
offset++;
|
||||||
size--;
|
size--;
|
||||||
h_size = (h_size << 7) | (b & 0x7f);
|
h_size = (h_size << 7) | (b & 0x7f);
|
||||||
} while (b & 0x80);
|
} while (b & 0x80);
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "headers %d: size: %u", j, h_size);
|
GST_DEBUG_OBJECT (rtpvorbisdepay, "headers %d: size: %u", j, h_size);
|
||||||
|
|
||||||
|
if (length < h_size)
|
||||||
|
goto too_small;
|
||||||
|
|
||||||
h_sizes[j] = h_size;
|
h_sizes[j] = h_size;
|
||||||
length -= h_size;
|
length -= h_size;
|
||||||
}
|
}
|
||||||
|
@ -294,20 +283,22 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
guint h_size;
|
guint h_size;
|
||||||
|
|
||||||
h_size = h_sizes[j];
|
h_size = h_sizes[j];
|
||||||
if (size < h_size)
|
if (size < h_size) {
|
||||||
|
free_config (conf);
|
||||||
goto too_small;
|
goto too_small;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "reading header %d, size %u", j,
|
GST_DEBUG_OBJECT (rtpvorbisdepay, "reading header %d, size %u", j,
|
||||||
h_size);
|
h_size);
|
||||||
|
|
||||||
buf = gst_buffer_new_and_alloc (h_size);
|
buf = gst_buffer_create_sub (confbuf, offset, h_size);
|
||||||
memcpy (GST_BUFFER_DATA (buf), data, h_size);
|
|
||||||
conf->headers = g_list_append (conf->headers, buf);
|
conf->headers = g_list_append (conf->headers, buf);
|
||||||
data += h_size;
|
offset += h_size;
|
||||||
size -= h_size;
|
size -= h_size;
|
||||||
}
|
}
|
||||||
rtpvorbisdepay->configs = g_list_append (rtpvorbisdepay->configs, conf);
|
rtpvorbisdepay->configs = g_list_append (rtpvorbisdepay->configs, conf);
|
||||||
}
|
}
|
||||||
|
gst_buffer_unref (confbuf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -315,6 +306,7 @@ gst_rtp_vorbis_depay_parse_configuration (GstRtpVorbisDepay * rtpvorbisdepay,
|
||||||
too_small:
|
too_small:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (rtpvorbisdepay, "configuration too small");
|
GST_DEBUG_OBJECT (rtpvorbisdepay, "configuration too small");
|
||||||
|
gst_buffer_unref (confbuf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -637,6 +629,9 @@ gst_rtp_vorbis_depay_change_state (GstElement * element,
|
||||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
free_indents (rtpvorbisdepay);
|
||||||
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue