[llvm] r358176 - YAMLIO: Fix serialization of strings with embedded nuls

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 11 07:57:34 PDT 2019


Author: labath
Date: Thu Apr 11 07:57:34 2019
New Revision: 358176

URL: http://llvm.org/viewvc/llvm-project?rev=358176&view=rev
Log:
YAMLIO: Fix serialization of strings with embedded nuls

Summary:
A bug/typo in Output::scalarString caused us to round-trip a StringRef
through a const char *. This meant that any strings with embedded nuls
were unintentionally cut short at the first such character. (It also
could have caused accidental buffer overruns, but it seems that all
StringRefs coming into this functions were formed from null-terminated
strings.)

This patch fixes the bug and adds an appropriate test.

Reviewers: sammccall, jhenderson

Subscribers: kristina, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60505

Modified:
    llvm/trunk/lib/Support/YAMLTraits.cpp
    llvm/trunk/unittests/Support/YAMLIOTest.cpp

Modified: llvm/trunk/lib/Support/YAMLTraits.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=358176&r1=358175&r2=358176&view=diff
==============================================================================
--- llvm/trunk/lib/Support/YAMLTraits.cpp (original)
+++ llvm/trunk/lib/Support/YAMLTraits.cpp Thu Apr 11 07:57:34 2019
@@ -660,11 +660,6 @@ void Output::scalarString(StringRef &S,
     return;
   }
 
-  unsigned i = 0;
-  unsigned j = 0;
-  unsigned End = S.size();
-  const char *Base = S.data();
-
   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
   output(Quote); // Starting quote.
 
@@ -672,11 +667,16 @@ void Output::scalarString(StringRef &S,
   // present, and will be escaped using a variety of unicode-scalar and special short-form
   // escapes. This is handled in yaml::escape.
   if (MustQuote == QuotingType::Double) {
-    output(yaml::escape(Base, /* EscapePrintable= */ false));
+    output(yaml::escape(S, /* EscapePrintable= */ false));
     outputUpToEndOfLine(Quote);
     return;
   }
 
+  unsigned i = 0;
+  unsigned j = 0;
+  unsigned End = S.size();
+  const char *Base = S.data();
+
   // When using single-quoted strings, any single quote ' must be doubled to be escaped.
   while (j < End) {
     if (S[j] == '\'') {                    // Escape quotes.

Modified: llvm/trunk/unittests/Support/YAMLIOTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=358176&r1=358175&r2=358176&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/YAMLIOTest.cpp (original)
+++ llvm/trunk/unittests/Support/YAMLIOTest.cpp Thu Apr 11 07:57:34 2019
@@ -688,6 +688,7 @@ struct StringTypes {
   std::string stdstr10;
   std::string stdstr11;
   std::string stdstr12;
+  std::string stdstr13;
 };
 
 namespace llvm {
@@ -718,6 +719,7 @@ namespace yaml {
       io.mapRequired("stdstr10",  st.stdstr10);
       io.mapRequired("stdstr11",  st.stdstr11);
       io.mapRequired("stdstr12",  st.stdstr12);
+      io.mapRequired("stdstr13",  st.stdstr13);
     }
   };
 }
@@ -750,6 +752,7 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
     map.stdstr10 = "0.2e20";
     map.stdstr11 = "0x30";
     map.stdstr12 = "- match";
+    map.stdstr13.assign("\0a\0b\0", 5);
 
     llvm::raw_string_ostream ostr(intermediate);
     Output yout(ostr);
@@ -775,6 +778,7 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
   EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
   EXPECT_NE(std::string::npos, flowOut.find("''\n"));
   EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
+  EXPECT_NE(std::string::npos, flowOut.find("\"\\0a\\0b\\0\""));
 
   {
     Input yin(intermediate);
@@ -794,6 +798,7 @@ TEST(YAMLIO, TestReadWriteStringTypes) {
     EXPECT_TRUE(map.stdstr4 == "@hhh");
     EXPECT_TRUE(map.stdstr5 == "");
     EXPECT_TRUE(map.stdstr6 == "0000000004000000");
+    EXPECT_EQ(std::string("\0a\0b\0", 5), map.stdstr13);
   }
 }
 




More information about the llvm-commits mailing list