diff --git a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp index f8b610dd7f73f..42ebfbfb3729a 100644 --- a/llvm/lib/Remarks/YAMLRemarkSerializer.cpp +++ b/llvm/lib/Remarks/YAMLRemarkSerializer.cpp @@ -114,11 +114,15 @@ template <> struct MappingTraits { static void mapping(IO &io, Argument &A) { assert(io.outputting() && "input not yet implemented"); + // A.Key.data() is not necessarily null-terminated, so we must make a copy, + // otherwise we potentially read out of bounds. + // FIXME: Add support for StringRef Keys in YAML IO. + std::string Key(A.Key); if (StringRef(A.Val).count('\n') > 1) { StringBlockVal S(A.Val); - io.mapRequired(A.Key.data(), S); + io.mapRequired(Key.c_str(), S); } else { - io.mapRequired(A.Key.data(), A.Val); + io.mapRequired(Key.c_str(), A.Val); } io.mapOptional("DebugLoc", A.Loc); } diff --git a/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp b/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp index 112cd92285685..974356d9cf30a 100644 --- a/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp +++ b/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp @@ -163,3 +163,33 @@ TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneNoStrTab) { "...\n"), std::move(PreFilledStrTab)); } + +TEST(YAMLRemarks, SerializerRemarkStringRefOOBRead) { + remarks::Remark R; + R.RemarkType = remarks::Type::Missed; + R.PassName = StringRef("passAAAA", 4); + R.RemarkName = StringRef("nameAAAA", 4); + R.FunctionName = StringRef("funcAAAA", 4); + R.Loc = remarks::RemarkLocation{StringRef("pathAAAA", 4), 3, 4}; + R.Hotness = 5; + R.Args.emplace_back(); + R.Args.back().Key = StringRef("keyAAAA", 3); + R.Args.back().Val = StringRef("valueAAAA", 5); + R.Args.emplace_back(); + R.Args.back().Key = StringRef("keydebugAAAA", 8); + R.Args.back().Val = StringRef("valuedebugAAAA", 10); + R.Args.back().Loc = + remarks::RemarkLocation{StringRef("argpathAAAA", 7), 6, 7}; + checkStandalone(remarks::Format::YAML, R, + "--- !Missed\n" + "Pass: pass\n" + "Name: name\n" + "DebugLoc: { File: path, Line: 3, Column: 4 }\n" + "Function: func\n" + "Hotness: 5\n" + "Args:\n" + " - key: value\n" + " - keydebug: valuedebug\n" + " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n" + "...\n"); +}