Skip to content

Commit c2678d9

Browse files
authored
Merge pull request #12 from sgrottel/bugfix-code-analyzer
Fixes issue found by code analyzer
2 parents 132dcc0 + 59a4089 commit c2678d9

5 files changed

Lines changed: 126 additions & 83 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# This docker can be used to test the linux implementation of FindExecutable
33
#
44
# On a Windows dev PC run:
5-
# docker build -t sgr/findexecutabletest .
5+
# docker build -t sgr/findexecutabletest .
66
# docker run --rm -v ".\bin\Debug\net10.0:/myapp" -t sgr/findexecutabletest
77
#
88
# Adjust path of the volume mount if you are to test other build flavors.

FindExecutable/ComponentSource.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

FindExecutable/FindExecutable.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
//
2626
// Version history:
2727
//
28+
// v1.0.2 -- 2026-04-01
29+
// resolved further finding by code analyzer
2830
// v1.0.1 -- 2026-02-22
2931
// resolved findings by scanners
3032
// v1.0 -- 2025-05-19
@@ -164,6 +166,7 @@ public static class FindExecutable
164166
#region Test if File is Executable
165167

166168
#region Windows P/Invoke
169+
[SupportedOSPlatform("Windows")]
167170
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
168171
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, IntPtr psfi, uint cbSizeFileInfo, uint uFlags);
169172
private const uint SHGFI_EXETYPE = 0x000002000;
@@ -204,7 +207,8 @@ private static bool IsExecutableOnWindow(string path)
204207
}
205208

206209
#region Linux P/Invoke
207-
[DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true)]
210+
[UnsupportedOSPlatform("Windows")]
211+
[DllImport("libc", CharSet = CharSet.Unicode, SetLastError = true)]
208212
private static extern int access(string pathname, int mode);
209213
// https://codebrowser.dev/glibc/glibc/posix/unistd.h.html#283
210214
private const int X_OK = 1;

Program.cs

Lines changed: 119 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,122 @@
1-
//
2-
// Run Docker/Linux test with:
3-
//
4-
// docker build -t sgr/findexecutable .
5-
// docker run --rm sgr/findexecutable
6-
//
7-
8-
using System;
9-
using System.IO;
10-
11-
namespace FindExecutable
12-
{
13-
internal class Program
14-
{
15-
static int Main(string[] args)
16-
{
17-
int retval = 0;
18-
19-
string[] executables = new string[] {
20-
"git.exe",
21-
"git"
22-
};
23-
24-
foreach (string executable in executables)
25-
{
26-
try
27-
{
28-
Console.WriteLine($"Searching for: {executable}");
29-
30-
string? fullPath = FindExecutable.FullPath(executable);
31-
32-
if (fullPath != null)
33-
{
34-
if (Path.IsPathFullyQualified(fullPath))
35-
{
36-
Console.WriteLine($"FOUND: {fullPath}");
37-
}
38-
else
39-
{
40-
Console.WriteLine($"FOUND w/ WARNING: non-full path, {fullPath}");
41-
}
42-
}
43-
else
44-
{
45-
Console.Error.WriteLine("NOT FOUND");
46-
retval = 1;
47-
}
48-
}
49-
catch (Exception e)
50-
{
51-
Console.Error.WriteLine($"FAILED, Exception: {e}");
52-
retval = 2;
53-
}
54-
}
55-
56-
Console.WriteLine("done.");
1+
//
2+
// Run Docker/Linux test with:
3+
//
4+
// docker build -t sgr/findexecutable .
5+
// docker run --rm sgr/findexecutable
6+
//
7+
8+
using System;
9+
using System.IO;
10+
using System.Reflection;
11+
12+
namespace FindExecutable
13+
{
14+
internal class Program
15+
{
16+
static int Main(string[] args)
17+
{
18+
Console.OutputEncoding = System.Text.Encoding.UTF8;
19+
int retval = 0;
20+
21+
retval = Math.Max(retval, TestSearchGit());
22+
23+
retval = Math.Max(retval, TestUnicodeFile());
24+
25+
Console.WriteLine("done.");
5726
if (retval != 0)
5827
{
5928
Console.WriteLine($"exit code: {retval}");
60-
}
61-
return retval;
62-
}
63-
}
64-
}
29+
}
30+
return retval;
31+
}
32+
33+
static int TestSearchGit()
34+
{
35+
string[] executables = [
36+
"git.exe",
37+
"git"
38+
];
39+
40+
foreach (string executable in executables)
41+
{
42+
try
43+
{
44+
Console.WriteLine($"Searching for: {executable}");
45+
46+
string? fullPath = FindExecutable.FullPath(executable);
47+
48+
if (fullPath != null)
49+
{
50+
if (Path.IsPathFullyQualified(fullPath))
51+
{
52+
Console.WriteLine($"FOUND: {fullPath}");
53+
}
54+
else
55+
{
56+
Console.WriteLine($"FOUND w/ WARNING: non-full path, {fullPath}");
57+
}
58+
}
59+
else
60+
{
61+
Console.Error.WriteLine("NOT FOUND");
62+
return 1;
63+
}
64+
}
65+
catch (Exception e)
66+
{
67+
Console.Error.WriteLine($"FAILED, Exception: {e}");
68+
return 2;
69+
}
70+
}
71+
72+
return 0;
73+
}
74+
75+
static int TestUnicodeFile()
76+
{
77+
Console.WriteLine("Searching for an (artificial) executable with a unicode name:");
78+
79+
const string gitExec = "git";
80+
const string unicodeExec = "まじかよ。.exe";
81+
82+
if (File.Exists(unicodeExec))
83+
{
84+
File.Delete(unicodeExec);
85+
}
86+
87+
string unicodeExecPath = Path.Join(AppContext.BaseDirectory, unicodeExec);
88+
string? gitFullPath = FindExecutable.FullPath(gitExec);
89+
90+
if (gitFullPath == null)
91+
{
92+
Console.WriteLine("Failed to find git exec as test subject");
93+
return 5;
94+
}
95+
96+
File.Copy(gitFullPath, unicodeExecPath);
97+
98+
if (!OperatingSystem.IsWindows())
99+
{
100+
File.SetUnixFileMode(unicodeExecPath, File.GetUnixFileMode(gitFullPath));
101+
}
102+
103+
if (!FindExecutable.IsExecutable(unicodeExecPath))
104+
{
105+
Console.WriteLine($"Failed to setup the unicode executable file name: {unicodeExecPath}");
106+
return 3;
107+
}
108+
109+
string? findIt = FindExecutable.FullPath(unicodeExec, includeCurrentDirectory: true);
110+
if (string.IsNullOrEmpty(findIt))
111+
{
112+
Console.WriteLine($"Failed to find the unicode executable file name: {unicodeExec}");
113+
return 4;
114+
}
115+
116+
Console.WriteLine($"FOUND: {findIt}");
117+
118+
return 0;
119+
}
120+
121+
}
122+
}

SGrottel.FindExecutable.nuspec

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<!-- package metadata -->
77
<metadata minClientVersion="3.3" >
88
<id>SGrottel.FindExecutable</id>
9-
<version>1.0.1</version>
9+
<version>1.0.2</version>
1010
<title>SGrottel.FindExecutable</title>
1111
<authors>SGrottel</authors>
1212
<owners>SGrottel</owners>
@@ -20,15 +20,13 @@
2020

2121
<contentFiles>
2222
<files include="cs/any/FindExecutable/FindExecutable.cs" />
23-
<files include="cs/any/FindExecutable/ComponentSource.json" buildAction="None" />
2423
<files include="cs/any/FindExecutable/LICENSE" buildAction="None" />
2524
</contentFiles>
2625
</metadata>
2726

2827
<!-- content -->
2928
<files>
3029
<file src="FindExecutable\FindExecutable.cs" target="contentFiles/cs/any/FindExecutable" />
31-
<file src="FindExecutable\ComponentSource.json" target="contentFiles/cs/any/FindExecutable" />
3230
<file src="LICENSE" target="contentFiles/cs/any/FindExecutable/LICENSE" />
3331

3432
<file src="package_readme.md" target="docs/README.md" />

0 commit comments

Comments
 (0)