diff --git a/ext/dash/gstxmlhelper.c b/ext/dash/gstxmlhelper.c index ee7aa661cc..d4db559c8e 100644 --- a/ext/dash/gstxmlhelper.c +++ b/ext/dash/gstxmlhelper.c @@ -975,11 +975,24 @@ gst_xml_helper_get_node_as_string (xmlNode * a_node, gchar ** content) gboolean exists = FALSE; const char *txt_encoding; xmlOutputBufferPtr out_buf; + xmlNode *ncopy = NULL; txt_encoding = (const char *) a_node->doc->encoding; out_buf = xmlAllocOutputBuffer (NULL); g_assert (out_buf != NULL); - xmlNodeDumpOutput (out_buf, a_node->doc, a_node, 0, 0, txt_encoding); + + /* Need to make a copy of XML element so that it includes namespaces + in the output, so that the resulting string can be parsed by an XML parser + that is namespace aware. + Use extended=1 for recursive copy (properties, namespaces and children) */ + ncopy = xmlDocCopyNode (a_node, a_node->doc, 1); + + if (!ncopy) { + GST_WARNING ("Failed to clone XML node"); + goto done; + } + xmlNodeDumpOutput (out_buf, ncopy->doc, ncopy, 0, 0, txt_encoding); + (void) xmlOutputBufferFlush (out_buf); #ifdef LIBXML2_NEW_BUFFER if (xmlOutputBufferGetSize (out_buf) > 0) { @@ -999,6 +1012,8 @@ gst_xml_helper_get_node_as_string (xmlNode * a_node, gchar ** content) exists = TRUE; } #endif // LIBXML2_NEW_BUFFER + xmlFreeNode (ncopy); +done: (void) xmlOutputBufferClose (out_buf); if (exists) { diff --git a/tests/check/elements/dash_mpd.c b/tests/check/elements/dash_mpd.c index 51448e69aa..c7adab8f34 100644 --- a/tests/check/elements/dash_mpd.c +++ b/tests/check/elements/dash_mpd.c @@ -51,6 +51,9 @@ #include +#include +#include + GST_DEBUG_CATEGORY (gst_dash_demux_debug); /* @@ -1434,7 +1437,7 @@ GST_START_TEST "" "" - " customns=\"foo\"" + " xmlns:customns=\"foo\"" " " " " " " @@ -1578,6 +1581,93 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding) GST_END_TEST; +/* + * Test parsing Period AdaptationSet RepresentationBase ContentProtection + * attributes + */ +GST_START_TEST + (dash_mpdparser_period_adaptationSet_representationBase_contentProtection_xml_namespaces) +{ + const gchar *xml = + "" + "" + " " " " + " " + " " + " " + " https://drm.test.example/AcquireLicense" + " "; + GstMPDPeriodNode *periodNode; + GstMPDAdaptationSetNode *adaptationSet; + GstMPDRepresentationBaseNode *representationBase; + GstMPDDescriptorTypeNode *contentProtection; + gboolean ret; + GstMPDClient *mpdclient = gst_mpd_client_new (); + xmlDocPtr doc; + xmlNode *root_element = NULL, *node; + xmlChar *property = NULL; + + ret = gst_mpd_client_parse (mpdclient, xml, (gint) strlen (xml)); + assert_equals_int (ret, TRUE); + + periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data; + adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data; + representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet); + assert_equals_int (g_list_length (representationBase->ContentProtection), 2); + contentProtection = (GstMPDDescriptorTypeNode *) + g_list_nth_data (representationBase->ContentProtection, 0); + assert_equals_string (contentProtection->schemeIdUri, + "urn:mpeg:dash:mp4protection:2011"); + + contentProtection = (GstMPDDescriptorTypeNode *) + g_list_nth_data (representationBase->ContentProtection, 1); + assert_equals_string (contentProtection->schemeIdUri, + "urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e"); + + /* We can't do a simple string compare of value, because the whitespace + formatting from xmlDump might differ between versions of libxml */ + LIBXML_TEST_VERSION; + doc = + xmlReadMemory (contentProtection->value, + strlen (contentProtection->value), "ContentProtection.xml", NULL, + XML_PARSE_NONET); + fail_if (!doc); + root_element = xmlDocGetRootElement (doc); + fail_if (root_element->type != XML_ELEMENT_NODE); + fail_if (xmlStrcmp (root_element->name, + (xmlChar *) "ContentProtection") != 0); + fail_if ((property = + xmlGetNoNsProp (root_element, (const xmlChar *) "value")) == NULL); + fail_if (xmlStrcmp (property, (xmlChar *) "ClearKey1.0") != 0); + xmlFree (property); + fail_if ((property = + xmlGetNoNsProp (root_element, + (const xmlChar *) "schemeIdUri")) == NULL); + assert_equals_string ((const gchar *) property, + "urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e"); + xmlFree (property); + + for (node = root_element->children; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) + break; + } + assert_equals_string ((const gchar *) node->name, "Laurl"); + assert_equals_string ((const gchar *) node->children->content, + "https://drm.test.example/AcquireLicense"); + + xmlFreeDoc (doc); + + gst_mpd_client_free (mpdclient); +} + +GST_END_TEST; + /* * Test parsing Period AdaptationSet Accessibility attributes * @@ -6454,6 +6544,8 @@ dash_suite (void) dash_mpdparser_contentProtection_no_value_no_encoding); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_representationBase_contentProtection_with_content); + tcase_add_test (tc_simpleMPD, + dash_mpdparser_period_adaptationSet_representationBase_contentProtection_xml_namespaces); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_accessibility); tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role);