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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/utility/media_router/dial_device_description_parser.h"
6
7 #include <libxml/parser.h>
8 #include <libxml/tree.h>
9 #include <libxml/xpath.h>
10 #include <libxslt/transform.h>
11 #include <libxslt/xslt.h>
12 #include <libxslt/xsltutils.h>
13
14 #include "base/strings/string_util.h"
15 #include "third_party/libxml/chromium/libxml_utils.h"
16
17 namespace {
18
19 constexpr char xslt_text[] =
20 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
21 "<xsl:stylesheet version=\"1.0\" "
22 "xmlns:t=\"urn:schemas-upnp-org:device-1-0\" "
23 "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
24 "<xsl:template match=\"node()|@*\">"
25 "<xsl:copy>"
26 "<xsl:apply-templates select=\"node()|@*\"/>"
27 "</xsl:copy>"
28 "</xsl:template>"
29 "<xsl:template match=\"t:root/t:device/t:UDN/text()\">***</xsl:template>"
30 "<xsl:template "
31 "match=\"t:root/t:device/t:serialNumber/text()\">***</xsl:template>"
32 "</xsl:stylesheet>";
33
34 static std::string Validate(
35 const media_router::DialDeviceDescription& description) {
36 if (description.unique_id.empty()) {
37 return "Missing uniqueId";
38 }
39 if (description.friendly_name.empty()) {
40 return "Missing friendlyName";
41 }
42 return "";
43 }
44
45 } // namespace
46
47 namespace media_router {
48
49 DialDeviceDescriptionParser::DialDeviceDescriptionParser() = default;
50 DialDeviceDescriptionParser::~DialDeviceDescriptionParser() = default;
51
52 bool DialDeviceDescriptionParser::Parse(const std::string& xml) {
53 device_description_ = DialDeviceDescription();
54
55 XmlReader xml_reader;
56 if (!xml_reader.Load(xml))
57 return false;
58
59 while (xml_reader.Read()) {
60 xml_reader.SkipToElement();
61 std::string node_name(xml_reader.NodeName());
62
63 if (node_name == "UDN") {
64 if (!xml_reader.ReadElementContent(&device_description_.unique_id))
65 return false;
66 } else if (node_name == "friendlyName") {
67 if (!xml_reader.ReadElementContent(&device_description_.friendly_name))
68 return false;
69 } else if (node_name == "modelName") {
70 if (!xml_reader.ReadElementContent(&device_description_.model_name))
71 return false;
72 } else if (node_name == "deviceType") {
73 if (!xml_reader.ReadElementContent(&device_description_.device_type))
74 return false;
75 }
76 }
77
78 // If friendly name does not exist, fall back to use model name + last 4
79 // digits of UUID as friendly name.
80 if (device_description_.friendly_name.empty()) {
81 auto model_name = device_description_.model_name;
82 auto unique_id = device_description_.unique_id;
83
84 if (!model_name.empty() && unique_id.length() >= 4) {
85 device_description_.friendly_name =
86 model_name + "[" + unique_id.substr(unique_id.length() - 4) + "]";
87
88 DVLOG(2)
89 << "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.
90 }
91 }
92
93 std::string error = Validate(device_description_);
94 if (!error.empty()) {
95 DLOG(WARNING) << "Device description failed to validate: " << error;
96 return false;
97 }
98
99 return true;
100 }
101
102 std::string DialDeviceDescriptionParser::ScrubXmlForLogging(
103 const std::string& xml) {
104 xmlDocPtr doc = xmlParseMemory(xml.c_str(), xml.size());
105
106 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.
107 LOG(WARNING) << "Document not parsed successfully";
108 return "";
109 }
110
111 xmlDocPtr xslt_doc = xmlParseMemory(xslt_text, sizeof(xslt_text));
112 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.
113
114 xsltStylesheetPtr style_ptr = xsltParseStylesheetDoc(xslt_doc);
115 xmlDocPtr res = xsltApplyStylesheet(style_ptr, doc, NULL);
116
117 xmlChar* output;
118 int size;
119 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
120
121 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
122
123 xmlFreeDoc(xslt_doc);
124 xmlFreeDoc(doc);
125
126 xsltCleanupGlobals();
127 xmlCleanupParser();
mark a. foltz 2017/03/17 19:05:47 Who frees output?
zhaobin 2017/03/18 00:17:39 Done.
128
129 return logging_xml;
130 }
131
132 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698