This revision was automatically updated to reflect the committed changes.
Closed by commit rLLDB346988: Add a check whether or not a str is utf8 prior to 
emplacing (authored by lanza, committed by ).
Herald added subscribers: lldb-commits, abidh.

Changed prior to commit:
  https://reviews.llvm.org/D53008?vs=174134&id=174264#toc

Repository:
  rLLDB LLDB

https://reviews.llvm.org/D53008

Files:
  tools/lldb-vscode/JSONUtils.cpp
  tools/lldb-vscode/JSONUtils.h
  tools/lldb-vscode/VSCode.cpp
  tools/lldb-vscode/lldb-vscode.cpp

Index: tools/lldb-vscode/JSONUtils.h
===================================================================
--- tools/lldb-vscode/JSONUtils.h
+++ tools/lldb-vscode/JSONUtils.h
@@ -16,7 +16,24 @@
 #include "VSCodeForward.h"
 
 namespace lldb_vscode {
-  
+
+//------------------------------------------------------------------
+/// Emplace a StringRef in a json::Object after enusring that the
+/// string is valid UTF8. If not, first call llvm::json::fixUTF8
+/// before emplacing.
+///
+/// @param[in] obj
+///     A JSON object that we will attempt to emplace the value in
+///
+/// @param[in] key
+///     The key to use when emplacing the value
+///
+/// @param[in] str
+///     The string to emplace
+//------------------------------------------------------------------
+void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key,
+                       llvm::StringRef str);
+
 //------------------------------------------------------------------
 /// Extract simple values as a string.
 ///
Index: tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- tools/lldb-vscode/lldb-vscode.cpp
+++ tools/lldb-vscode/lldb-vscode.cpp
@@ -289,7 +289,7 @@
   exe_fspec.GetPath(exe_path, sizeof(exe_path));
   llvm::json::Object event(CreateEventObject("process"));
   llvm::json::Object body;
-  body.try_emplace("name", std::string(exe_path));
+  EmplaceSafeString(body, "name", std::string(exe_path));
   const auto pid = g_vsc.target.GetProcess().GetProcessID();
   body.try_emplace("systemProcessId", (int64_t)pid);
   body.try_emplace("isLocalProcess", true);
@@ -539,7 +539,7 @@
     g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
     if (error.Fail()) {
       response.try_emplace("success", false);
-      response.try_emplace("message", std::string(error.GetCString()));
+      EmplaceSafeString(response, "message", std::string(error.GetCString()));
       g_vsc.SendJSON(llvm::json::Value(std::move(response)));
       return;
     }
@@ -591,7 +591,7 @@
 
   if (error.Fail()) {
     response.try_emplace("success", false);
-    response.try_emplace("message", std::string(error.GetCString()));
+    EmplaceSafeString(response, "message", std::string(error.GetCString()));
   }
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
   if (error.Success()) {
@@ -813,8 +813,8 @@
     else if (stopReason == lldb::eStopReasonBreakpoint) {
       ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
       if (exc_bp) {
-        body.try_emplace("exceptionId", exc_bp->filter);
-        body.try_emplace("description", exc_bp->label);
+        EmplaceSafeString(body, "exceptionId", exc_bp->filter);
+        EmplaceSafeString(body, "description", exc_bp->label);
       } else {
         body.try_emplace("exceptionId", "exception");
       }
@@ -824,7 +824,7 @@
     if (!ObjectContainsKey(body, "description")) {
       char description[1024];
       if (thread.GetStopDescription(description, sizeof(description))) {
-        body.try_emplace("description", std::string(description));
+        EmplaceSafeString(body, "description", std::string(description));
       }
     }
     body.try_emplace("breakMode", "always");
@@ -951,9 +951,9 @@
   const auto expression = GetString(arguments, "expression");
 
   if (!expression.empty() && expression[0] == '`') {
-    body.try_emplace("result",
-                     RunLLDBCommands(llvm::StringRef(),
-                                     {expression.substr(1)}));
+    auto result = RunLLDBCommands(llvm::StringRef(),
+                                     {expression.substr(1)});
+    EmplaceSafeString(body, "result", result);
     body.try_emplace("variablesReference", (int64_t)0);
   } else {
     // Always try to get the answer from the local variables if possible. If
@@ -968,13 +968,13 @@
       response.try_emplace("success", false);
       const char *error_cstr = value.GetError().GetCString();
       if (error_cstr && error_cstr[0])
-        response.try_emplace("message", std::string(error_cstr));
+        EmplaceSafeString(response, "message", std::string(error_cstr));
       else
-        response.try_emplace("message", "evaluate failed");
+        EmplaceSafeString(response, "message", "evaluate failed");
     } else {
       SetValueForKey(value, body, "result");
       auto value_typename = value.GetType().GetDisplayTypeName();
-      body.try_emplace("type", value_typename ? value_typename : NO_TYPENAME);
+      EmplaceSafeString(body, "type", value_typename ? value_typename : NO_TYPENAME);
       if (value.MightHaveChildren()) {
         auto variablesReference = VARIDX_TO_VARREF(g_vsc.variables.GetSize());
         g_vsc.variables.Append(value);
@@ -1241,7 +1241,7 @@
     g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
     if (error.Fail()) {
       response.try_emplace("success", false);
-      response.try_emplace("message", std::string(error.GetCString()));
+      EmplaceSafeString(response, "message", std::string(error.GetCString()));
       g_vsc.SendJSON(llvm::json::Value(std::move(response)));
     }
   }
@@ -1279,7 +1279,7 @@
   g_vsc.target.Launch(g_vsc.launch_info, error);
   if (error.Fail()) {
     response.try_emplace("success", false);
-    response.try_emplace("message", std::string(error.GetCString()));
+    EmplaceSafeString(response, "message", std::string(error.GetCString()));
   }
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 
@@ -1945,7 +1945,7 @@
   auto sourceReference = GetSigned(source, "sourceReference", -1);
   auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
   if (pos != g_vsc.source_map.end()) {
-    body.try_emplace("content", pos->second.content);
+    EmplaceSafeString(body, "content", pos->second.content);
   } else {
     response.try_emplace("success", false);
   }
@@ -2406,10 +2406,10 @@
     bool success = variable.SetValueFromCString(value.data(), error);
     if (success) {
       SetValueForKey(variable, body, "value");
-      body.try_emplace("type", variable.GetType().GetDisplayTypeName());
+      EmplaceSafeString(body, "type", variable.GetType().GetDisplayTypeName());
       body.try_emplace("variablesReference", newVariablesReference);
     } else {
-      body.try_emplace("message", std::string(error.GetCString()));
+      EmplaceSafeString(body, "message", std::string(error.GetCString()));
     }
     response.try_emplace("success", success);
   }
Index: tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- tools/lldb-vscode/JSONUtils.cpp
+++ tools/lldb-vscode/JSONUtils.cpp
@@ -23,6 +23,14 @@
 
 namespace lldb_vscode {
 
+void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key,
+                       llvm::StringRef str) {
+  if (LLVM_LIKELY(llvm::json::isUTF8(str)))
+    obj.try_emplace(key, str.str());
+  else
+    obj.try_emplace(key, llvm::json::fixUTF8(str));
+}
+
 llvm::StringRef GetAsString(const llvm::json::Value &value) {
   if (auto s = value.getAsString())
     return *s;
@@ -124,11 +132,11 @@
 
 void SetValueForKey(lldb::SBValue &v, llvm::json::Object &object,
                     llvm::StringRef key) {
-  
+
   llvm::StringRef value = v.GetValue();
   llvm::StringRef summary = v.GetSummary();
   llvm::StringRef type_name = v.GetType().GetDisplayTypeName();
-  
+
   std::string result;
   llvm::raw_string_ostream strm(result);
   if (!value.empty()) {
@@ -144,16 +152,16 @@
       strm << " @ " << llvm::format_hex(address, 0);
   }
   strm.flush();
-  object.try_emplace(key, result);
+  EmplaceSafeString(object, key, result);
 }
 
 void FillResponse(const llvm::json::Object &request,
                   llvm::json::Object &response) {
   // Fill in all of the needed response fields to a "request" and set "success"
   // to true by default.
   response.try_emplace("type", "response");
   response.try_emplace("seq", (int64_t)0);
-  response.try_emplace("command", GetString(request, "command"));
+  EmplaceSafeString(response, "command", GetString(request, "command"));
   const int64_t seq = GetSigned(request, "seq", 0);
   response.try_emplace("request_seq", seq);
   response.try_emplace("success", true);
@@ -223,7 +231,7 @@
                               int64_t variablesReference,
                               int64_t namedVariables, bool expensive) {
   llvm::json::Object object;
-  object.try_emplace("name", name.str());
+  EmplaceSafeString(object, "name", name.str());
   object.try_emplace("variablesReference", variablesReference);
   object.try_emplace("expensive", expensive);
   object.try_emplace("namedVariables", namedVariables);
@@ -357,7 +365,7 @@
   llvm::json::Object event;
   event.try_emplace("seq", 0);
   event.try_emplace("type", "event");
-  event.try_emplace("event", event_name);
+  EmplaceSafeString(event, "event", event_name);
   return event;
 }
 
@@ -388,8 +396,8 @@
 llvm::json::Value
 CreateExceptionBreakpointFilter(const ExceptionBreakpoint &bp) {
   llvm::json::Object object;
-  object.try_emplace("filter", bp.filter);
-  object.try_emplace("label", bp.label);
+  EmplaceSafeString(object, "filter", bp.filter);
+  EmplaceSafeString(object, "label", bp.label);
   object.try_emplace("default", bp.default_value);
   return llvm::json::Value(std::move(object));
 }
@@ -467,11 +475,11 @@
   if (file.IsValid()) {
     const char *name = file.GetFilename();
     if (name)
-      object.try_emplace("name", name);
+      EmplaceSafeString(object, "name", name);
     char path[PATH_MAX] = "";
     file.GetPath(path, sizeof(path));
     if (path[0]) {
-      object.try_emplace("path", std::string(path));
+      EmplaceSafeString(object, "path", std::string(path));
     }
   }
   return llvm::json::Value(std::move(object));
@@ -517,7 +525,7 @@
   }
   const auto num_insts = insts.GetSize();
   if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) {
-    object.try_emplace("name", frame.GetFunctionName());
+    EmplaceSafeString(object, "name", frame.GetFunctionName());
     SourceReference source;
     llvm::raw_string_ostream src_strm(source.content);
     std::string line;
@@ -540,8 +548,8 @@
       line.clear();
       llvm::raw_string_ostream line_strm(line);
       line_strm << llvm::formatv("{0:X+}: <{1}> {2} {3,12} {4}", inst_addr,
-                                 inst_offset, llvm::fmt_repeat(' ', spaces),
-                                 m, o);
+                                 inst_offset, llvm::fmt_repeat(' ', spaces), m,
+                                 o);
 
       // If there is a comment append it starting at column 60 or after one
       // space past the last char
@@ -626,7 +634,7 @@
   llvm::json::Object object;
   int64_t frame_id = MakeVSCodeFrameID(frame);
   object.try_emplace("id", frame_id);
-  object.try_emplace("name", frame.GetFunctionName());
+  EmplaceSafeString(object, "name", frame.GetFunctionName());
   int64_t disasm_line = 0;
   object.try_emplace("source", CreateSource(frame, disasm_line));
 
@@ -670,9 +678,9 @@
     std::string thread_with_name(thread_str);
     thread_with_name += ' ';
     thread_with_name += name;
-    object.try_emplace("name", thread_with_name);
+    EmplaceSafeString(object, "name", thread_with_name);
   } else {
-    object.try_emplace("name", std::string(thread_str));
+    EmplaceSafeString(object, "name", std::string(thread_str));
   }
   return llvm::json::Value(std::move(object));
 }
@@ -749,7 +757,7 @@
     ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
     if (exc_bp) {
       body.try_emplace("reason", "exception");
-      body.try_emplace("description", exc_bp->label);
+      EmplaceSafeString(body, "description", exc_bp->label);
     } else {
       body.try_emplace("reason", "breakpoint");
     }
@@ -782,7 +790,7 @@
   if (ObjectContainsKey(body, "description")) {
     char description[1024];
     if (thread.GetStopDescription(description, sizeof(description))) {
-      body.try_emplace("description", std::string(description));
+      EmplaceSafeString(body, "description", std::string(description));
     }
   }
   if (tid == g_vsc.focus_tid) {
@@ -862,12 +870,12 @@
                                  int64_t varID, bool format_hex) {
   llvm::json::Object object;
   auto name = v.GetName();
-  object.try_emplace("name", name ? name : "<null>");
+  EmplaceSafeString(object, "name", name ? name : "<null>");
   if (format_hex)
     v.SetFormat(lldb::eFormatHex);
   SetValueForKey(v, object, "value");
   auto type_cstr = v.GetType().GetDisplayTypeName();
-  object.try_emplace("type", type_cstr ? type_cstr : NO_TYPENAME);
+  EmplaceSafeString(object, "type", type_cstr ? type_cstr : NO_TYPENAME);
   if (varID != INT64_MAX)
     object.try_emplace("id", varID);
   if (v.MightHaveChildren())
@@ -878,7 +886,7 @@
   v.GetExpressionPath(evaluateStream);
   const char *evaluateName = evaluateStream.GetData();
   if (evaluateName && evaluateName[0])
-    object.try_emplace("evaluateName", std::string(evaluateName));
+    EmplaceSafeString(object, "evaluateName", std::string(evaluateName));
   return llvm::json::Value(std::move(object));
 }
 
Index: tools/lldb-vscode/VSCode.cpp
===================================================================
--- tools/lldb-vscode/VSCode.cpp
+++ tools/lldb-vscode/VSCode.cpp
@@ -256,7 +256,7 @@
     break;
   }
   body.try_emplace("category", category);
-  body.try_emplace("output", output.str());
+  EmplaceSafeString(body, "output", output.str());
   event.try_emplace("body", std::move(body));
   SendJSON(llvm::json::Value(std::move(event)));
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to