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.
This commit is contained in:
Alex Ashley 2015-08-19 11:29:43 +01:00 committed by Sebastian Dröge
parent 626bd97c5a
commit 2ebebdbfbb
2 changed files with 96 additions and 7 deletions

View file

@ -971,17 +971,45 @@ static gboolean
gst_mpdparser_get_xml_node_as_string (xmlNode * a_node, gchar ** content) gst_mpdparser_get_xml_node_as_string (xmlNode * a_node, gchar ** content)
{ {
gboolean exists = FALSE; gboolean exists = FALSE;
xmlBufferPtr buffer = xmlBufferCreate (); const char *txt_encoding;
int size; xmlCharEncodingHandlerPtr conv_hdlr = NULL;
xmlOutputBufferPtr out_buf;
size = xmlNodeDump (buffer, a_node->doc, a_node, 0, /* indent */ txt_encoding = (const char *) a_node->doc->encoding;
0 /* format */ ); if (txt_encoding != NULL) {
if (size > 0) { conv_hdlr = xmlFindCharEncodingHandler (txt_encoding);
*content = (gchar *) xmlBufferDetach (buffer); 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; 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); GST_LOG (" - %s: %s", a_node->name, *content);
} }
xmlBufferFree (buffer);
return exists; return exists;
} }

View file

@ -1271,6 +1271,66 @@ GST_START_TEST
GST_END_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 =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
" profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
" <Period>"
" <AdaptationSet>"
" <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>"
" <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">"
" <mas:MarlinContentIds>"
" <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>"
" </mas:MarlinContentIds>"
" </ContentProtection>" "</AdaptationSet></Period></MPD>";
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, "<ContentProtection");
fail_if (str == NULL);
str = strstr (contentProtection->value, "<mas:MarlinContentIds>");
fail_if (str == NULL);
str = strstr (contentProtection->value, "<mas:MarlinContentId>");
fail_if (str == NULL);
str =
strstr (contentProtection->value,
"urn:marlin:kid:02020202020202020202020202020202");
fail_if (str == NULL);
str = strstr (contentProtection->value, "</ContentProtection>");
fail_if (str == NULL);
gst_mpd_client_free (mpdclient);
}
GST_END_TEST;
/* /*
* Test parsing Period AdaptationSet Accessibility attributes * Test parsing Period AdaptationSet Accessibility attributes
* *
@ -4344,6 +4404,7 @@ dash_suite (void)
dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration); dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration);
tcase_add_test (tc_simpleMPD, tcase_add_test (tc_simpleMPD,
dash_mpdparser_period_adaptationSet_representationBase_contentProtection); dash_mpdparser_period_adaptationSet_representationBase_contentProtection);
tcase_add_test (tc_simpleMPD, dash_mpdparser_contentProtection_no_value);
tcase_add_test (tc_simpleMPD, tcase_add_test (tc_simpleMPD,
dash_mpdparser_period_adaptationSet_accessibility); dash_mpdparser_period_adaptationSet_accessibility);
tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role);