Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10763)

Unified Diff: chrome/utility/media_router/dial_device_description_parser.cc

Issue 2745653008: [Media Router] Parse device description xml in utility process (Closed)
Patch Set: use mojo instead of IPC Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/utility/media_router/dial_device_description_parser.cc
diff --git a/chrome/utility/media_router/dial_device_description_parser.cc b/chrome/utility/media_router/dial_device_description_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c443609a49111fa49d7c86bcdc7fdabacf933341
--- /dev/null
+++ b/chrome/utility/media_router/dial_device_description_parser.cc
@@ -0,0 +1,132 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/utility/media_router/dial_device_description_parser.h"
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxslt/transform.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltutils.h>
+
+#include "base/strings/string_util.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
+
+namespace {
+
+constexpr char xslt_text[] =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<xsl:stylesheet version=\"1.0\" "
+ "xmlns:t=\"urn:schemas-upnp-org:device-1-0\" "
+ "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
+ "<xsl:template match=\"node()|@*\">"
+ "<xsl:copy>"
+ "<xsl:apply-templates select=\"node()|@*\"/>"
+ "</xsl:copy>"
+ "</xsl:template>"
+ "<xsl:template match=\"t:root/t:device/t:UDN/text()\">***</xsl:template>"
+ "<xsl:template "
+ "match=\"t:root/t:device/t:serialNumber/text()\">***</xsl:template>"
+ "</xsl:stylesheet>";
+
+static std::string Validate(
+ const media_router::DialDeviceDescription& description) {
+ if (description.unique_id.empty()) {
+ return "Missing uniqueId";
+ }
+ if (description.friendly_name.empty()) {
+ return "Missing friendlyName";
+ }
+ return "";
+}
+
+} // namespace
+
+namespace media_router {
+
+DialDeviceDescriptionParser::DialDeviceDescriptionParser() = default;
+DialDeviceDescriptionParser::~DialDeviceDescriptionParser() = default;
+
+bool DialDeviceDescriptionParser::Parse(const std::string& xml) {
+ device_description_ = DialDeviceDescription();
+
+ XmlReader xml_reader;
+ if (!xml_reader.Load(xml))
+ return false;
+
+ while (xml_reader.Read()) {
+ xml_reader.SkipToElement();
+ std::string node_name(xml_reader.NodeName());
+
+ if (node_name == "UDN") {
+ if (!xml_reader.ReadElementContent(&device_description_.unique_id))
+ return false;
+ } else if (node_name == "friendlyName") {
+ if (!xml_reader.ReadElementContent(&device_description_.friendly_name))
+ return false;
+ } else if (node_name == "modelName") {
+ if (!xml_reader.ReadElementContent(&device_description_.model_name))
+ return false;
+ } else if (node_name == "deviceType") {
+ if (!xml_reader.ReadElementContent(&device_description_.device_type))
+ return false;
+ }
+ }
+
+ // If friendly name does not exist, fall back to use model name + last 4
+ // digits of UUID as friendly name.
+ if (device_description_.friendly_name.empty()) {
+ auto model_name = device_description_.model_name;
+ auto unique_id = device_description_.unique_id;
+
+ if (!model_name.empty() && unique_id.length() >= 4) {
+ device_description_.friendly_name =
+ model_name + "[" + unique_id.substr(unique_id.length() - 4) + "]";
+
+ DVLOG(2)
+ << "Fixed device description: created friendlyName from modelName.";
mark a. foltz 2017/03/17 19:05:47 In my opinion, it will be pretty clear from the fr
zhaobin 2017/03/18 00:17:39 Done.
+ }
+ }
+
+ std::string error = Validate(device_description_);
+ if (!error.empty()) {
+ DLOG(WARNING) << "Device description failed to validate: " << error;
+ return false;
+ }
+
+ return true;
+}
+
+std::string DialDeviceDescriptionParser::ScrubXmlForLogging(
+ const std::string& xml) {
+ xmlDocPtr doc = xmlParseMemory(xml.c_str(), xml.size());
+
+ if (doc == NULL) {
mark a. foltz 2017/03/17 19:05:47 s/NULL/nullptr/ assuming doc is a pointer type.
zhaobin 2017/03/18 00:17:39 Done.
+ LOG(WARNING) << "Document not parsed successfully";
+ return "";
+ }
+
+ xmlDocPtr xslt_doc = xmlParseMemory(xslt_text, sizeof(xslt_text));
+ DCHECK(xslt_doc);
mark a. foltz 2017/03/17 19:05:47 Assuming xmlDocPtr is a pointer type, it would be
zhaobin 2017/03/18 00:17:39 Done.
+
+ xsltStylesheetPtr style_ptr = xsltParseStylesheetDoc(xslt_doc);
+ xmlDocPtr res = xsltApplyStylesheet(style_ptr, doc, NULL);
+
+ xmlChar* output;
+ int size;
+ xsltSaveResultToString(&output, &size, res, style_ptr);
mark a. foltz 2017/03/17 19:05:47 I assume this allocates output to be sufficiently
zhaobin 2017/03/18 00:17:39 Seems so. output is allocated inside xsltSaveResul
+
+ std::string logging_xml = std::string(reinterpret_cast<char*>(output));
mark a. foltz 2017/03/17 19:05:47 I'm not an expert in XML APIs to know how safe thi
zhaobin 2017/03/18 00:17:39 xmlChar is unsigned char, and seems that output is
+
+ xmlFreeDoc(xslt_doc);
+ xmlFreeDoc(doc);
+
+ xsltCleanupGlobals();
+ xmlCleanupParser();
mark a. foltz 2017/03/17 19:05:47 Who frees output?
zhaobin 2017/03/18 00:17:39 Done.
+
+ return logging_xml;
+}
+
+} // namespace media_router

Powered by Google App Engine
This is Rietveld 408576698