Fix superpmi.exe handling of exclusion lists (#62349)
authorBruce Forstall <brucefo@microsoft.com>
Fri, 3 Dec 2021 23:44:37 +0000 (15:44 -0800)
committerGitHub <noreply@github.com>
Fri, 3 Dec 2021 23:44:37 +0000 (15:44 -0800)
superpmi.exe has the concept of an exclusion list file which is automatically read
and processed when reading a .mch file. (I'm not sure if anyone actually uses it.)
So, when opening a `t.mch` file, it looks for an adjacent `t.mch.exc` and then `t.exc`
file.

There was a bug where it would also look for a `t` file (the comments say it takes t.exc.mch
and looks for t.exc, but it didn't check for that). In my case when I was testing, I actually
had a `t` directory (not file), which it found, but then emitted an error trying to load.

So, two fixes:
1. For `t.mch`, don't look for `t`.
2. Check all cases for being a directory, and fail if any name is a directory.

src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp

index c5e63bf..4b59b72 100644 (file)
@@ -42,25 +42,25 @@ std::string MethodContextReader::CheckForPairedFile(const std::string& fileName,
 {
     std::string tmp = to_lower(origSuffix);
 
-    // First, check to see if foo.origSuffix exists
+    // First, check to see if foo.origSuffix exists and is not a directory name
     size_t suffix_offset = fileName.find_last_of('.');
-    if ((SSIZE_T)suffix_offset <= 0 || (tmp != to_lower(fileName.substr(suffix_offset))) ||
-        (GetFileAttributesA(fileName.c_str()) == INVALID_FILE_ATTRIBUTES))
+    if ((SSIZE_T)suffix_offset <= 0 || (tmp != to_lower(fileName.substr(suffix_offset))))
+        return std::string();
+
+    DWORD attribs = GetFileAttributesA(fileName.c_str());
+    if ((attribs == INVALID_FILE_ATTRIBUTES) || (attribs & FILE_ATTRIBUTE_DIRECTORY))
         return std::string();
 
     // next, check foo.orig.new from foo.orig
     tmp = fileName + newSuffix;
-    if (GetFileAttributesA(tmp.c_str()) != INVALID_FILE_ATTRIBUTES)
-        return tmp;
-
-    // Now let's check for foo.new from foo.new.orig
-    tmp = fileName.substr(0, suffix_offset);
-    if (GetFileAttributesA(tmp.c_str()) != INVALID_FILE_ATTRIBUTES)
+    attribs = GetFileAttributesA(tmp.c_str());
+    if ((attribs != INVALID_FILE_ATTRIBUTES) && !(attribs & FILE_ATTRIBUTE_DIRECTORY))
         return tmp;
 
-    // Finally, lets try foo.orig from foo.new
-    tmp += newSuffix;
-    if (GetFileAttributesA(tmp.c_str()) != INVALID_FILE_ATTRIBUTES)
+    // Finally, lets try foo.new from foo.orig
+    tmp = fileName.substr(0, suffix_offset) + newSuffix;
+    attribs = GetFileAttributesA(tmp.c_str());
+    if ((attribs != INVALID_FILE_ATTRIBUTES) && !(attribs & FILE_ATTRIBUTE_DIRECTORY))
         return tmp;
 
     return std::string();