From c4f4ae51efdfd4cf3cb415c30fd3a5def637f8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 4 Aug 2006 13:05:01 +0000 Subject: [PATCH] gst/realmedia/: Factor out some code into rmutils.[ch]; when reading strings, don't read beyond the available data; r... Original commit message from CVS: * gst/realmedia/Makefile.am: * gst/realmedia/rmdemux.c: (gst_rmdemux_parse_mdpr), (gst_rmdemux_parse_cont): * gst/realmedia/rmutils.c: (gst_rm_utils_read_string8), (gst_rm_utils_read_string16), (gst_rm_utils_read_tags): * gst/realmedia/rmutils.h: Factor out some code into rmutils.[ch]; when reading strings, don't read beyond the available data; read metadata strings correctly (string length is 16 bits here, not just 8). --- ChangeLog | 13 ++++ gst/realmedia/Makefile.am | 8 +-- gst/realmedia/rmdemux.c | 68 ++++----------------- gst/realmedia/rmutils.c | 122 ++++++++++++++++++++++++++++++++++++++ gst/realmedia/rmutils.h | 44 ++++++++++++++ 5 files changed, 193 insertions(+), 62 deletions(-) create mode 100644 gst/realmedia/rmutils.c create mode 100644 gst/realmedia/rmutils.h diff --git a/ChangeLog b/ChangeLog index b1aff055f0..11733594b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-08-04 Tim-Philipp Müller + + * gst/realmedia/Makefile.am: + * gst/realmedia/rmdemux.c: (gst_rmdemux_parse_mdpr), + (gst_rmdemux_parse_cont): + * gst/realmedia/rmutils.c: (gst_rm_utils_read_string8), + (gst_rm_utils_read_string16), (gst_rm_utils_read_tags): + * gst/realmedia/rmutils.h: + Factor out some code into rmutils.[ch]; when reading + strings, don't read beyond the available data; read + metadata strings correctly (string length is 16 bits + here, not just 8). + 2006-07-31 Jan Schmidt * Makefile.am: diff --git a/gst/realmedia/Makefile.am b/gst/realmedia/Makefile.am index 9769097bbb..71bdbbde29 100644 --- a/gst/realmedia/Makefile.am +++ b/gst/realmedia/Makefile.am @@ -1,9 +1,9 @@ plugin_LTLIBRARIES = libgstrmdemux.la -libgstrmdemux_la_SOURCES = rmdemux.c +libgstrmdemux_la_SOURCES = rmdemux.c rmutils.c -libgstrmdemux_la_CFLAGS = $(GST_CFLAGS) -libgstrmdemux_la_LIBADD = $(GST_BASE_LIBS) +libgstrmdemux_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) +libgstrmdemux_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) libgstrmdemux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = rmdemux.h +noinst_HEADERS = rmdemux.h rmutils.h diff --git a/gst/realmedia/rmdemux.c b/gst/realmedia/rmdemux.c index bb9c6beb84..5619ef4d35 100644 --- a/gst/realmedia/rmdemux.c +++ b/gst/realmedia/rmdemux.c @@ -27,6 +27,7 @@ # include "config.h" #endif #include "rmdemux.h" +#include "rmutils.h" #include #include #include @@ -1454,15 +1455,6 @@ re_hexdump_bytes (guint8 * ptr, int len, int offset) } } -static char * -re_get_pascal_string (const guint8 * ptr) -{ - int length; - - length = ptr[0]; - return g_strndup ((char *) ptr + 1, length); -} - static int re_skip_pascal_string (const guint8 * ptr) { @@ -1512,6 +1504,7 @@ gst_rmdemux_parse_mdpr (GstRMDemux * rmdemux, const void *data, int length) GstRMDemuxStream *stream; char *stream1_type_string; char *stream2_type_string; + guint str_len = 0; int stream_type; int offset; @@ -1527,10 +1520,12 @@ gst_rmdemux_parse_mdpr (GstRMDemux * rmdemux, const void *data, int length) offset = 30; stream_type = GST_RMDEMUX_STREAM_UNKNOWN; - stream1_type_string = re_get_pascal_string (data + offset); - offset += re_skip_pascal_string (data + offset); - stream2_type_string = re_get_pascal_string (data + offset); - offset += re_skip_pascal_string (data + offset); + stream1_type_string = gst_rm_utils_read_string8 (data + offset, + length - offset, &str_len); + offset += str_len; + stream2_type_string = gst_rm_utils_read_string8 (data + offset, + length - offset, &str_len); + offset += str_len; /* stream1_type_string for audio and video stream is a "put_whatever_you_want" field : * observed values : @@ -1737,54 +1732,11 @@ gst_rmdemux_parse_data (GstRMDemux * rmdemux, const void *data, int length) static void gst_rmdemux_parse_cont (GstRMDemux * rmdemux, const void *data, int length) { - const gchar *gst_tags[] = { GST_TAG_TITLE, GST_TAG_ARTIST, - GST_TAG_COPYRIGHT, GST_TAG_COMMENT - }; GstTagList *tags; - guint i; - GST_DEBUG_OBJECT (rmdemux, "File Content : (CONT) len = %d", length); - - tags = gst_tag_list_new (); - - for (i = 0; i < G_N_ELEMENTS (gst_tags); ++i) { - if (length > 2) { - gchar *str; - guint str_length; - - str = (gchar *) re_get_pascal_string (data); - str_length = (str != NULL) ? strlen (str) : 0; - data += 2 + str_length; - length -= 2 + str_length; - - if (str != NULL && !g_utf8_validate (str, -1, NULL)) { - const gchar *encoding; - gchar *tmp; - - encoding = g_getenv ("GST_TAG_ENCODING"); - if (encoding == NULL || *encoding == '\0') { - if (g_get_charset (&encoding)) - encoding = "ISO-8859-15"; - } - GST_DEBUG_OBJECT (rmdemux, "converting tag from %s to UTF-8", encoding); - tmp = g_convert_with_fallback (str, -1, "UTF-8", encoding, "*", - NULL, NULL, NULL); - g_free (str); - str = tmp; - } - - GST_DEBUG_OBJECT (rmdemux, "%s = %s", gst_tags[i], GST_STR_NULL (str)); - if (str != NULL && *str != '\0') { - gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, gst_tags[i], str, NULL); - } - g_free (str); - } - } - - if (gst_structure_n_fields ((GstStructure *) tags) > 0) { + tags = gst_rm_utils_read_tags (data, length, gst_rm_utils_read_string16); + if (tags) { gst_element_found_tags (GST_ELEMENT (rmdemux), tags); - } else { - gst_tag_list_free (tags); } } diff --git a/gst/realmedia/rmutils.c b/gst/realmedia/rmutils.c new file mode 100644 index 0000000000..a70e206135 --- /dev/null +++ b/gst/realmedia/rmutils.c @@ -0,0 +1,122 @@ +/* GStreamer RealMedia utility functions + * Copyright (C) 2006 Tim-Philipp Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rmutils.h" + +gchar * +gst_rm_utils_read_string8 (const guint8 * data, guint datalen, + guint * p_total_len) +{ + gint length; + + if (p_total_len) + *p_total_len = 0; + + if (datalen < 1) + return NULL; + + length = GST_READ_UINT8 (data); + if (datalen < (1 + length)) + return NULL; + + if (p_total_len) + *p_total_len = 1 + length; + + return g_strndup ((gchar *) data + 1, length); +} + +gchar * +gst_rm_utils_read_string16 (const guint8 * data, guint datalen, + guint * p_total_len) +{ + gint length; + + if (p_total_len) + *p_total_len = 0; + + if (datalen < 2) + return NULL; + + length = GST_READ_UINT16_BE (data); + if (datalen < (2 + length)) + return NULL; + + if (p_total_len) + *p_total_len = 2 + length; + + return g_strndup ((gchar *) data + 2, length); +} + +GstTagList * +gst_rm_utils_read_tags (const guint8 * data, guint datalen, + GstRmUtilsStringReadFunc read_string_func) +{ + const gchar *gst_tags[] = { GST_TAG_TITLE, GST_TAG_ARTIST, + GST_TAG_COPYRIGHT, GST_TAG_COMMENT + }; + GstTagList *tags; + guint i; + + g_assert (read_string_func != NULL); + + GST_DEBUG ("File Content : (CONT) len = %d", datalen); + + tags = gst_tag_list_new (); + + for (i = 0; i < G_N_ELEMENTS (gst_tags); ++i) { + gchar *str = NULL; + guint total_length = 0; + + str = read_string_func (data, datalen, &total_length); + data += total_length; + datalen -= total_length; + + if (str != NULL && !g_utf8_validate (str, -1, NULL)) { + const gchar *encoding; + gchar *tmp; + + encoding = g_getenv ("GST_TAG_ENCODING"); + if (encoding == NULL || *encoding == '\0') { + if (g_get_charset (&encoding)) + encoding = "ISO-8859-15"; + } + GST_DEBUG ("converting tag from %s to UTF-8", encoding); + tmp = g_convert_with_fallback (str, -1, "UTF-8", encoding, "*", + NULL, NULL, NULL); + g_free (str); + str = tmp; + } + + GST_DEBUG ("%s = %s", gst_tags[i], GST_STR_NULL (str)); + if (str != NULL && *str != '\0') { + gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, gst_tags[i], str, NULL); + } + g_free (str); + } + + if (gst_structure_n_fields ((GstStructure *) tags) > 0) + return tags; + + gst_tag_list_free (tags); + return NULL; +} diff --git a/gst/realmedia/rmutils.h b/gst/realmedia/rmutils.h new file mode 100644 index 0000000000..41b8aa8eda --- /dev/null +++ b/gst/realmedia/rmutils.h @@ -0,0 +1,44 @@ +/* GStreamer RealMedia utility functions + * Copyright (C) 2006 Tim-Philipp Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_RM_UTILS_H__ +#define __GST_RM_UTILS_H__ + +#include + +G_BEGIN_DECLS + +typedef gchar * (*GstRmUtilsStringReadFunc) (const guint8 * data, guint datalen, guint * p_strlen); + +gchar *gst_rm_utils_read_string8 (const guint8 * data, + guint datalen, + guint * p_totallen); + +gchar *gst_rm_utils_read_string16 (const guint8 * data, + guint datalen, + guint * p_totallen); + +GstTagList *gst_rm_utils_read_tags (const guint8 * data, + guint datalen, + GstRmUtilsStringReadFunc func); + +G_END_DECLS + +#endif /* __GST_RM_UTILS_H__ */ +