]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/Formatter: fix string_view usage for {json,xml}_stream_escaper 21317/head
authorSage Weil <sage@redhat.com>
Tue, 10 Apr 2018 03:25:17 +0000 (22:25 -0500)
committerSage Weil <sage@redhat.com>
Tue, 10 Apr 2018 03:40:58 +0000 (22:40 -0500)
These are passing a simple const char* without a length, which breaks for
binary strings with \0 in them.

Broken by b40f76a7a0cf460f2a851b001885a4831a6f6503.

This code is still a mess because there is a mix of boost::string_view
and std::string_view throughout the code.  A cleanup is in order!

Signed-off-by: Sage Weil <sage@redhat.com>
src/common/Formatter.cc
src/common/HTMLFormatter.cc
src/common/escape.h
src/test/escape.cc

index d0cc2d2aeda8c2972ae7249160cde0e84d6920cb..6b57027e3a7b0692381579907257d43947b436e7 100644 (file)
@@ -163,7 +163,7 @@ void JSONFormatter::print_comma(json_formatter_stack_entry_d& entry)
 
 void JSONFormatter::print_quoted_string(std::string_view s)
 {
-  m_ss << '\"' << json_stream_escaper(s.data()) << '\"';
+  m_ss << '\"' << json_stream_escaper(s) << '\"';
 }
 
 void JSONFormatter::print_name(const char *name)
@@ -447,7 +447,7 @@ void XMLFormatter::dump_string(const char *name, std::string_view s)
       [this](char c) { return this->to_lower_underscore(c); });
 
   print_spaces();
-  m_ss << "<" << e << ">" << xml_stream_escaper(s.data()) << "</" << e << ">";
+  m_ss << "<" << e << ">" << xml_stream_escaper(s) << "</" << e << ">";
   if (m_pretty)
     m_ss << "\n";
 }
@@ -461,7 +461,7 @@ void XMLFormatter::dump_string_with_attrs(const char *name, std::string_view s,
   std::string attrs_str;
   get_attrs_str(&attrs, attrs_str);
   print_spaces();
-  m_ss << "<" << e << attrs_str << ">" << xml_stream_escaper(s.data()) << "</" << e << ">";
+  m_ss << "<" << e << attrs_str << ">" << xml_stream_escaper(s) << "</" << e << ">";
   if (m_pretty)
     m_ss << "\n";
 }
@@ -477,7 +477,7 @@ std::ostream& XMLFormatter::dump_stream(const char *name)
 void XMLFormatter::dump_format_va(const char* name, const char *ns, bool quoted, const char *fmt, va_list ap)
 {
   char buf[LARGE_SIZE];
-  vsnprintf(buf, LARGE_SIZE, fmt, ap);
+  size_t len = vsnprintf(buf, LARGE_SIZE, fmt, ap);
   std::string e(name);
   std::transform(e.begin(), e.end(), e.begin(),
       [this](char c) { return this->to_lower_underscore(c); });
@@ -486,7 +486,7 @@ void XMLFormatter::dump_format_va(const char* name, const char *ns, bool quoted,
   if (ns) {
     m_ss << "<" << e << " xmlns=\"" << ns << "\">" << buf << "</" << e << ">";
   } else {
-    m_ss << "<" << e << ">" << xml_stream_escaper(buf) << "</" << e << ">";
+    m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf, len)) << "</" << e << ">";
   }
 
   if (m_pretty)
index 1ad6a6d88e567dbe0f9d49fe2baf93e24430f262..725bc39ff70d401fbdeb31026ca1a03291db4c3e 100644 (file)
@@ -114,7 +114,7 @@ void HTMLFormatter::dump_float(const char *name, double d)
 
 void HTMLFormatter::dump_string(const char *name, std::string_view s)
 {
-  dump_template(name, xml_stream_escaper(s.data()));
+  dump_template(name, xml_stream_escaper(s));
 }
 
 void HTMLFormatter::dump_string_with_attrs(const char *name, std::string_view s, const FormatterAttrs& attrs)
@@ -123,7 +123,7 @@ void HTMLFormatter::dump_string_with_attrs(const char *name, std::string_view s,
   std::string attrs_str;
   get_attrs_str(&attrs, attrs_str);
   print_spaces();
-  m_ss << "<li>" << e << ": " << xml_stream_escaper(s.data()) << attrs_str << "</li>";
+  m_ss << "<li>" << e << ": " << xml_stream_escaper(s) << attrs_str << "</li>";
   if (m_pretty)
     m_ss << "\n";
 }
@@ -139,14 +139,16 @@ std::ostream& HTMLFormatter::dump_stream(const char *name)
 void HTMLFormatter::dump_format_va(const char* name, const char *ns, bool quoted, const char *fmt, va_list ap)
 {
   char buf[LARGE_SIZE];
-  vsnprintf(buf, LARGE_SIZE, fmt, ap);
+  size_t len = vsnprintf(buf, LARGE_SIZE, fmt, ap);
 
   std::string e(name);
   print_spaces();
   if (ns) {
-    m_ss << "<li xmlns=\"" << ns << "\">" << e << ": " << xml_stream_escaper(buf) << "</li>";
+    m_ss << "<li xmlns=\"" << ns << "\">" << e << ": "
+        << xml_stream_escaper(std::string_view(buf, len)) << "</li>";
   } else {
-    m_ss << "<li>" << e << ": " << xml_stream_escaper(buf) << "</li>";
+    m_ss << "<li>" << e << ": "
+        << xml_stream_escaper(std::string_view(buf, len)) << "</li>";
   }
 
   if (m_pretty)
index 22da777212a58e1b03775542bf997e61ce046f1c..97178520b7eccd40ff71f0fa6aed3e459de1bae2 100644 (file)
@@ -51,13 +51,13 @@ void escape_json_attr(const char *buf, size_t src_len, char *out);
 
 struct xml_stream_escaper {
   boost::string_view str;
-  xml_stream_escaper(boost::string_view str) : str(str) {}
+  xml_stream_escaper(std::string_view str) : str(str.data(), str.size()) {}
 };
 std::ostream& operator<<(std::ostream& out, const xml_stream_escaper& e);
 
 struct json_stream_escaper {
   boost::string_view str;
-  json_stream_escaper(boost::string_view str) : str(str) {}
+  json_stream_escaper(std::string_view str) : str(str.data(), str.size()) {}
 };
 std::ostream& operator<<(std::ostream& out, const json_stream_escaper& e);
 
index 82591cba1e199402059bd1ee3c7d978881e84bf9..cab87043ffcc6ac122d5deffb214fb0e5c9b176b 100644 (file)
@@ -66,18 +66,21 @@ TEST(EscapeXml, Utf8) {
   ASSERT_EQ(escape_xml_stream("<\xe6\xb1\x89\xe5\xad\x97>\n"), "&lt;\xe6\xb1\x89\xe5\xad\x97&gt;\n");
 }
 
-static std::string escape_json_attrs(const char *str)
+static std::string escape_json_attrs(const char *str, size_t src_len = 0)
 {
-  int src_len = strlen(str);
+  if (!src_len)
+    src_len = strlen(str);
   int len = escape_json_attr_len(str, src_len);
   char out[len];
   escape_json_attr(str, src_len, out);
   return out;
 }
-static std::string escape_json_stream(const char *str)
+static std::string escape_json_stream(const char *str, size_t src_len = 0)
 {
+  if (!src_len)
+    src_len = strlen(str);
   std::stringstream ss;
-  ss << json_stream_escaper(str);
+  ss << json_stream_escaper(std::string_view(str, src_len));
   return ss.str();
 }
 
@@ -110,6 +113,10 @@ TEST(EscapeJson, Escapes1) {
 TEST(EscapeJson, ControlChars) {
   ASSERT_EQ(escape_json_attrs("\x01\x02\x03"), "\\u0001\\u0002\\u0003");
   ASSERT_EQ(escape_json_stream("\x01\x02\x03"), "\\u0001\\u0002\\u0003");
+  ASSERT_EQ(escape_json_stream("\x00\x02\x03", 3), "\\u0000\\u0002\\u0003");
+
+  // json can't print binary data!
+  ASSERT_EQ(escape_json_stream("\x00\x7f\xff", 3), "\\u0000\\u007f\xff");
 
   ASSERT_EQ(escape_json_attrs("abc\x7f"), "abc\\u007f");
   ASSERT_EQ(escape_json_stream("abc\x7f"), "abc\\u007f");