Escape filenames in MI output
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 17 Jul 2017 02:45:50 +0000 (05:45 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/netcoredbg/breakpoints.cpp
src/debug/netcoredbg/frames.cpp
src/debug/netcoredbg/main.cpp

index 47fc04e..736e823 100644 (file)
@@ -7,6 +7,7 @@
 #include <vector>
 #include <map>
 
+std::string EscapeMIValue(const std::string &str);
 
 // Modules
 HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
@@ -78,7 +79,7 @@ HRESULT PrintBreakpoint(ULONG32 id, std::string &output)
     if (b.IsResolved())
     {
         ss << "bkpt={number=\"" << id << "\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\","
-            "func=\"\",fullname=\"" << b.fullname << "\",line=\"" << b.linenum << "\"}";
+            "func=\"\",fullname=\"" << EscapeMIValue(b.fullname) << "\",line=\"" << b.linenum << "\"}";
         Status = S_OK;
     }
     else
index 077f7b7..2e1d0c5 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "typeprinter.h"
 
+std::string EscapeMIValue(const std::string &str);
+
 HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
                          ULONG32 &ilOffset,
                          mdMethodDef &methodToken,
@@ -77,7 +79,7 @@ HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output)
     IfFailRet(GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum));
 
     std::stringstream ss;
-    ss << "line=\"" << linenum << "\",fullname=\"" << fullname << "\"";
+    ss << "line=\"" << linenum << "\",fullname=\"" << EscapeMIValue(fullname) << "\"";
     output = ss.str();
 
     return S_OK;
index 1a1ad0a..4e92b04 100644 (file)
@@ -136,6 +136,34 @@ void NotifyEvalComplete();
 // Frames
 HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output);
 
+// TODO: Merge with EscapeString
+std::string EscapeMIValue(const std::string &str)
+{
+    std::string s(str);
+
+    for (std::size_t i = 0; i < s.size(); ++i)
+    {
+        int count = 0;
+        char c = s.at(i);
+        switch (c)
+        {
+            case '\"': count = 1; s.insert(i, count, '\\'); s[i + count] = '\"'; break;
+            case '\\': count = 1; s.insert(i, count, '\\'); s[i + count] = '\\'; break;
+            case '\0': count = 1; s.insert(i, count, '\\'); s[i + count] = '0'; break;
+            case '\a': count = 1; s.insert(i, count, '\\'); s[i + count] = 'a'; break;
+            case '\b': count = 1; s.insert(i, count, '\\'); s[i + count] = 'b'; break;
+            case '\f': count = 1; s.insert(i, count, '\\'); s[i + count] = 'f'; break;
+            case '\n': count = 1; s.insert(i, count, '\\'); s[i + count] = 'n'; break;
+            case '\r': count = 1; s.insert(i, count, '\\'); s[i + count] = 'r'; break;
+            case '\t': count = 1; s.insert(i, count, '\\'); s[i + count] = 't'; break;
+            case '\v': count = 1; s.insert(i, count, '\\'); s[i + count] = 'v'; break;
+        }
+        i += count;
+    }
+
+    return s;
+}
+
 static HRESULT DisableAllBreakpointsAndSteppersInAppDomain(ICorDebugAppDomain *pAppDomain)
 {
     HRESULT Status;
@@ -445,8 +473,8 @@ public:
             {
                 std::stringstream ss;
                 ss << "id=\"{" << id << "}\","
-                   << "target-name=\"" << name << "\","
-                   << "host-name=\"" << name << "\","
+                   << "target-name=\"" << EscapeMIValue(name) << "\","
+                   << "host-name=\"" << EscapeMIValue(name) << "\","
                    << "symbols-loaded=\"" << symbolsLoaded << "\","
                    << "base-address=\"0x" << std::hex << baseAddress << "\","
                    << "size=\"" << std::dec << size << "\"";