From 2ebebdbfbb7f5cfa7b438bb6b02fc723c9349d51 Mon Sep 17 00:00:00 2001 From: Alex Ashley Date: Wed, 19 Aug 2015 11:29:43 +0100 Subject: [PATCH] dashdemux: replace xmlNodeDump with xmlNodeDumpOutput When running on an STB, the function gst_mpdparser_get_xml_node_as_string causes a segmentation fault. This code works correctly on a Linux desktop. Looking at the libxml documentation, the xmlNodeDump is deprecated. Replacing the use of xmlNodeDump with xmlNodeDumpOutput fixes the segfault on the STB and removes the use of the deprecated function. --- ext/dash/gstmpdparser.c | 42 +++++++++++++++++++---- tests/check/elements/dash_mpd.c | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index 98ef978249..e800d6b1f5 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -971,17 +971,45 @@ static gboolean gst_mpdparser_get_xml_node_as_string (xmlNode * a_node, gchar ** content) { gboolean exists = FALSE; - xmlBufferPtr buffer = xmlBufferCreate (); - int size; + const char *txt_encoding; + xmlCharEncodingHandlerPtr conv_hdlr = NULL; + xmlOutputBufferPtr out_buf; - size = xmlNodeDump (buffer, a_node->doc, a_node, 0, /* indent */ - 0 /* format */ ); - if (size > 0) { - *content = (gchar *) xmlBufferDetach (buffer); + txt_encoding = (const char *) a_node->doc->encoding; + if (txt_encoding != NULL) { + conv_hdlr = xmlFindCharEncodingHandler (txt_encoding); + if (conv_hdlr == NULL) { + GST_ERROR ("Unable to find encoder for encoding: %s", txt_encoding); + return FALSE; + } + } + out_buf = xmlAllocOutputBuffer (conv_hdlr); + g_assert (out_buf != NULL); + xmlNodeDumpOutput (out_buf, a_node->doc, a_node, 0, 0, txt_encoding); + xmlOutputBufferFlush (out_buf); +#ifdef LIBXML2_NEW_BUFFER + if (xmlOutputBufferGetSize (out_buf) > 0) { + *content = + (gchar *) xmlStrndup (xmlOutputBufferGetContent (out_buf), + xmlOutputBufferGetSize (out_buf)); exists = TRUE; + } +#else + if (out_buf->conv && out_buf->conv->use > 0) { + *content = + (gchar *) xmlStrndup (out_buf->conv->content, out_buf->conv->use); + exists = TRUE; + } else if (out_buf->buffer && out_buf->buffer->use > 0) { + *content = + (gchar *) xmlStrndup (out_buf->buffer->content, out_buf->buffer->use); + exists = TRUE; + } +#endif // LIBXML2_NEW_BUFFER + (void) xmlOutputBufferClose (out_buf); + + if (exists) { GST_LOG (" - %s: %s", a_node->name, *content); } - xmlBufferFree (buffer); return exists; } diff --git a/tests/check/elements/dash_mpd.c b/tests/check/elements/dash_mpd.c index ee5b6cbbd2..bbf27aa983 100644 --- a/tests/check/elements/dash_mpd.c +++ b/tests/check/elements/dash_mpd.c @@ -1271,6 +1271,66 @@ GST_START_TEST GST_END_TEST; +/* + * Test parsing ContentProtection element that has no value attribute + */ +GST_START_TEST (dash_mpdparser_contentProtection_no_value) +{ + GstPeriodNode *periodNode; + GstAdaptationSetNode *adaptationSet; + GstRepresentationBaseType *representationBase; + GstDescriptorType *contentProtection; + const gchar *xml = + "" + "" + " " + " " + " " + " " + " " + " urn:marlin:kid:02020202020202020202020202020202" + " " + " " ""; + + gboolean ret; + GstMpdClient *mpdclient = gst_mpd_client_new (); + gchar *str; + + ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); + assert_equals_int (ret, TRUE); + + periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; + adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; + representationBase = adaptationSet->RepresentationBase; + assert_equals_int (g_list_length (representationBase->ContentProtection), 2); + contentProtection = + (GstDescriptorType *) g_list_nth (representationBase->ContentProtection, + 1)->data; + assert_equals_string (contentProtection->schemeIdUri, + "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4"); + fail_if (contentProtection->value == NULL); + g_print ("%s\n", contentProtection->value); + /* We can't do a simple compare of value (which should be an XML dump + of the ContentProtection element), because the whitespace + formatting from xmlDump might differ between versions of libxml */ + str = strstr (contentProtection->value, "value, ""); + fail_if (str == NULL); + str = strstr (contentProtection->value, ""); + fail_if (str == NULL); + str = + strstr (contentProtection->value, + "urn:marlin:kid:02020202020202020202020202020202"); + fail_if (str == NULL); + str = strstr (contentProtection->value, ""); + fail_if (str == NULL); + gst_mpd_client_free (mpdclient); +} + +GST_END_TEST; + /* * Test parsing Period AdaptationSet Accessibility attributes * @@ -4344,6 +4404,7 @@ dash_suite (void) dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_representationBase_contentProtection); + tcase_add_test (tc_simpleMPD, dash_mpdparser_contentProtection_no_value); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_accessibility); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role);