Skip to content

Commit 80e52ec

Browse files
authored
Merge pull request #1248 from Some1fromthedark/avast_false_positives
Change Suspicious Code in Various Projects to Prevent False Flagging by Avast Anti-Virus
2 parents 825113e + 806e751 commit 80e52ec

9 files changed

Lines changed: 182 additions & 58 deletions

File tree

OpenKh.Command.Arc/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private static void Unpack(string inputFile, string outputDirectory)
8585
? StringComparison.OrdinalIgnoreCase
8686
: StringComparison.Ordinal;
8787

88-
if (!outputPath.StartsWith(outputDirectory + Path.DirectorySeparatorChar, comparison))
88+
if (!outputPath.StartsWith(Path.GetFullPath(outputRoot + Path.DirectorySeparatorChar), comparison))
8989
{
9090
throw new Exception($"The file {entry.Name} is outside the output directory");
9191
}

OpenKh.Command.Bar/Program.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.ComponentModel.DataAnnotations;
44
using System.IO;
55
using System.Reflection;
6+
using System.Runtime.InteropServices;
67

78
namespace OpenKh.Command.Bar
89
{
@@ -89,16 +90,29 @@ private class PackCommand
8990
protected int OnExecute(CommandLineApplication app)
9091
{
9192
var baseDirectory = Path.GetDirectoryName(InputProject);
93+
if (String.IsNullOrEmpty(baseDirectory))
94+
{
95+
baseDirectory = Environment.CurrentDirectory;
96+
}
9297
var binarc = Core.ImportProject(InputProject, out var originalFileName);
9398

99+
var OutputBaseDirectory = baseDirectory;
100+
var OutputFileName = originalFileName;
101+
94102
if (string.IsNullOrEmpty(OutputFile))
95-
OutputFile = Path.Combine(baseDirectory, originalFileName);
103+
{
104+
OutputFile = Path.Combine(OutputBaseDirectory, OutputFileName);
105+
}
106+
107+
if (!File.Exists(OutputFile) && Directory.Exists(OutputFile))
108+
{
109+
OutputBaseDirectory = OutputFile;
110+
OutputFile = Path.Combine(OutputBaseDirectory, originalFileName);
111+
}
96112

97-
if (!File.Exists(OutputFile) && Directory.Exists(OutputFile) &&
98-
File.GetAttributes(OutputFile).HasFlag(FileAttributes.Directory))
99-
OutputFile = Path.Combine(OutputFile, originalFileName);
113+
var fullPath = Path.GetFullPath(OutputFile);
100114

101-
using var outputStream = File.Create(OutputFile);
115+
using var outputStream = File.Create(fullPath);
102116
Kh2.Bar.Write(outputStream, binarc);
103117

104118
foreach (var entry in binarc)

OpenKh.Command.Bbsa/Program.cs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
using System.Collections.Generic;
44
using System.ComponentModel.DataAnnotations;
55
using System.IO;
6-
using System.Text;
76
using System.Linq;
87
using System.Reflection;
8+
using System.Runtime.InteropServices;
9+
using System.Text;
10+
using System.Threading;
911

1012
namespace OpenKh.Command.Bbsa
1113
{
@@ -140,10 +142,9 @@ private static void ExtractArchives(IEnumerable<string> bbsaFileNames, string ou
140142
if (bbsaFileStream == null)
141143
continue;
142144

143-
var destinationFileName = Path.Combine(Path.Combine(outputDir, $"{prefix}{file.ArchiveIndex}"), name);
144-
var destinationFolder = Path.GetDirectoryName(destinationFileName);
145-
if (!Directory.Exists(destinationFolder))
146-
Directory.CreateDirectory(destinationFolder);
145+
var baseDir = Path.Combine(outputDir, $"{prefix}{file.ArchiveIndex}");
146+
var destinationFileName = MakeSafeDestination(baseDir, name);
147+
Directory.CreateDirectory(Path.GetDirectoryName(destinationFileName)!);
147148
streams[0].Position = file.Location + 4;
148149

149150
Bbs.Bbsa.CalculateArchiveOffset(bbsa.GetHeader(), file.offset, out var nuind, out var coffs);
@@ -178,8 +179,8 @@ private static void ExtractArchives(IEnumerable<string> bbsaFileNames, string ou
178179
}
179180

180181

181-
using (var outStream = File.Create(destinationFileName))
182-
bbsaFileStream.CopyTo(outStream);
182+
using var outStream = File.Create(destinationFileName);
183+
bbsaFileStream.CopyTo(outStream);
183184
}
184185

185186
if (log)
@@ -280,5 +281,27 @@ protected int OnExecute(CommandLineApplication app)
280281

281282
private static bool DoesContainBbsa(string path, string prefix) =>
282283
File.Exists(Path.Combine(path, $"{prefix}{0}.DAT"));
284+
285+
private static string MakeSafeDestination(string baseDir, string entryName)
286+
{
287+
// Prevent absolute paths
288+
entryName = entryName.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
289+
290+
// Replace invalid filename chars (optional; you can be stricter)
291+
foreach (var c in Path.GetInvalidPathChars())
292+
entryName = entryName.Replace(c, '_');
293+
294+
var dest = Path.GetFullPath(Path.Combine(baseDir, entryName));
295+
var fullBase = Path.GetFullPath(baseDir + Path.DirectorySeparatorChar);
296+
297+
var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
298+
? StringComparison.OrdinalIgnoreCase
299+
: StringComparison.Ordinal;
300+
301+
if (!dest.StartsWith(fullBase, comparison))
302+
throw new InvalidOperationException($"Unsafe archive path: {entryName}");
303+
304+
return dest;
305+
}
283306
}
284307
}

OpenKh.Command.DoctChanger/Program.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
using McMaster.Extensions.CommandLineUtils;
2-
using OpenKh.Kh2;
2+
using OpenKh.Command.DoctChanger.Utils;
33
using OpenKh.Common;
4+
using OpenKh.Kh2;
5+
using OpenKh.Kh2.Utils;
46
using System;
57
using System.ComponentModel.DataAnnotations;
68
using System.IO;
7-
using System.Reflection;
89
using System.Linq;
9-
using OpenKh.Kh2.Utils;
10-
using OpenKh.Command.DoctChanger.Utils;
10+
using System.Reflection;
11+
using System.Runtime.InteropServices;
1112

1213
namespace OpenKh.Command.DoctChanger
1314
{
@@ -76,7 +77,16 @@ protected int OnExecute(CommandLineApplication app)
7677
{
7778
Console.WriteLine(mapIn);
7879

79-
var mapOut = Path.Combine(Output, Path.GetFileName(mapIn));
80+
var fileName = Path.GetFileName(mapIn);
81+
var mapOut = Path.GetFullPath(Path.Combine(Output, fileName));
82+
var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
83+
? StringComparison.OrdinalIgnoreCase
84+
: StringComparison.Ordinal;
85+
86+
if (!mapOut.StartsWith(Path.GetFullPath(Output + Path.DirectorySeparatorChar), comparison))
87+
{
88+
throw new Exception($"The file {fileName} is outside the output directory");
89+
}
8090

8191
var entries = File.OpenRead(mapIn).Using(s => Bar.Read(s))
8292
.Select(

OpenKh.Command.PAMtoFBXConverter/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,13 @@ private static void Convert(string PMO_Path, string PAM_Path)
6767
pmoStream.Close();
6868
pamStream.Close();
6969

70+
71+
var OutputName = "Test.fbx";
72+
var OutputPath = ".";
73+
var FullPath = Path.GetFullPath(Path.Combine(OutputPath, OutputName));
74+
7075
using var ctx = new AssimpContext();
71-
ctx.ExportFile(nScene, "Test.fbx", "fbx");
76+
ctx.ExportFile(nScene, FullPath, "fbx");
7277

7378
}
7479

OpenKh.Command.PmpConverter/Program.cs

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1+
using Assimp;
2+
using McMaster.Extensions.CommandLineUtils;
3+
using OpenKh.Bbs;
4+
using OpenKh.Common.Utils;
15
using OpenKh.Engine.MonoGame;
26
using OpenKh.Engine.Parsers;
37
using OpenKh.Imaging;
4-
58
using System;
6-
using McMaster.Extensions.CommandLineUtils;
7-
using System.IO;
8-
using System.Reflection;
9-
using System.ComponentModel.DataAnnotations;
10-
using OpenKh.Bbs;
119
using System.Collections.Generic;
10+
using System.ComponentModel.DataAnnotations;
11+
using System.IO;
1212
using System.Numerics;
13-
using OpenKh.Common.Utils;
14-
using Assimp;
13+
using System.Reflection;
14+
using System.Runtime.InteropServices;
1515

1616
namespace OpenKh.Command.PmpConverter
1717
{
@@ -67,7 +67,6 @@ private static void Convert(string fileIn, string fileOut)
6767
Pmp pmp = MeshGroupList2PMP(p);
6868
using Stream stream = File.Create(fileOut);
6969
Pmp.Write(stream, pmp);
70-
stream.Close();
7170
}
7271

7372
private static Pmp MeshGroupList2PMP(List<MeshGroup> meshGroup)
@@ -118,10 +117,10 @@ private static Pmp MeshGroupList2PMP(List<MeshGroup> meshGroup)
118117
// Set extra flags.
119118
if (UsesUniformColor)
120119
{
121-
var UniformColor = (uint)(desc.Vertices[0].A / 255f);
122-
UniformColor += (uint)(desc.Vertices[0].B / 255f) << 8;
123-
UniformColor += (uint)(desc.Vertices[0].G / 255f) << 16;
124-
UniformColor += (uint)(desc.Vertices[0].R / 255f) << 24;
120+
var UniformColor = (uint)(desc.Vertices[0].A * 255f);
121+
UniformColor |= (uint)(desc.Vertices[0].B * 255f) << 8;
122+
UniformColor |= (uint)(desc.Vertices[0].G * 255f) << 16;
123+
UniformColor |= (uint)(desc.Vertices[0].R * 255f) << 24;
125124
chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
126125
chunk.SectionInfo_opt2 = new Pmo.MeshSectionOptional2();
127126
chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
@@ -331,17 +330,40 @@ public static List<MeshGroup> FromFbx(string filePath)
331330
var assimp = new Assimp.AssimpContext();
332331
var scene = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
333332
var baseFilePath = Path.GetDirectoryName(filePath);
333+
if (String.IsNullOrEmpty(baseFilePath))
334+
{
335+
baseFilePath = ".";
336+
}
334337
TexList = new List<string>();
335338
TextureData = new List<Tm2>();
336339

337340
foreach (Assimp.Material mat in scene.Materials)
338341
{
339-
TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
340-
Stream str = File.OpenRead(TexList[TexList.Count - 1]);
342+
if (String.IsNullOrEmpty(mat.TextureDiffuse.FilePath))
343+
{
344+
throw new Exception($"Material '{mat.Name}' has no diffuse texture specified");
345+
}
346+
347+
var texPath = Path.IsPathRooted(mat.TextureDiffuse.FilePath)
348+
? Path.GetFullPath(mat.TextureDiffuse.FilePath)
349+
: Path.GetFullPath(Path.Combine(baseFilePath, mat.TextureDiffuse.FilePath));
341350

342-
PngImage png = new PngImage(str);
343-
Tm2 tmImage = Tm2.Create(png);
344-
TextureData.Add(tmImage);
351+
var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
352+
? StringComparison.OrdinalIgnoreCase
353+
: StringComparison.Ordinal;
354+
355+
if (!texPath.StartsWith(Path.GetFullPath(baseFilePath + Path.DirectorySeparatorChar), comparison))
356+
{
357+
throw new Exception($"The file {texPath} is outside the output directory");
358+
}
359+
360+
TexList.Add(Path.GetFileName(texPath));
361+
using (Stream str = new FileStream(texPath, FileMode.Open, FileAccess.Read, FileShare.Read))
362+
{
363+
PngImage png = new PngImage(str);
364+
Tm2 tmImage = Tm2.Create(png);
365+
TextureData.Add(tmImage);
366+
}
345367
}
346368

347369
for(int i = 0; i < scene.RootNode.ChildCount; i++)
@@ -364,10 +386,10 @@ public static List<MeshGroup> FromFbx(string filePath)
364386
vertices[k].Z = x.Vertices[k].Z * Scale;
365387
vertices[k].Tu = x.TextureCoordinateChannels[0][k].X;
366388
vertices[k].Tv = 1.0f - x.TextureCoordinateChannels[0][k].Y;
367-
vertices[k].R = x.VertexColorChannels[0][i].R;
368-
vertices[k].G = x.VertexColorChannels[0][i].G;
369-
vertices[k].B = x.VertexColorChannels[0][i].B;
370-
vertices[k].A = x.VertexColorChannels[0][i].A;
389+
vertices[k].R = x.VertexColorChannels[0][k].R;
390+
vertices[k].G = x.VertexColorChannels[0][k].G;
391+
vertices[k].B = x.VertexColorChannels[0][k].B;
392+
vertices[k].A = x.VertexColorChannels[0][k].A;
371393
}
372394

373395
meshDescriptor.Vertices = vertices;

OpenKh.Command.Rbin/Program.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using OpenKh.Common;
21
using McMaster.Extensions.CommandLineUtils;
2+
using OpenKh.Common;
3+
using OpenKh.Common.Exceptions;
34
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel.DataAnnotations;
47
using System.IO;
58
using System.Linq;
69
using System.Reflection;
7-
using System.ComponentModel.DataAnnotations;
8-
using OpenKh.Common.Exceptions;
9-
using System.Collections.Generic;
10+
using System.Runtime.InteropServices;
1011

1112
namespace OpenKh.Command.Rbin
1213
{
@@ -203,7 +204,15 @@ private static bool ExtractFile(FileStream stream, Ddd.Rbin.TocEntry tocEntry, s
203204
{
204205
try
205206
{
206-
var outPath = Path.Combine(outputFolder, tocEntry.Name);
207+
var outPath = Path.GetFullPath(Path.Combine(outputFolder, tocEntry.Name));
208+
var comparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
209+
? StringComparison.OrdinalIgnoreCase
210+
: StringComparison.Ordinal;
211+
212+
if (!outPath.StartsWith(Path.GetFullPath(outputFolder + Path.DirectorySeparatorChar), comparison))
213+
{
214+
throw new Exception($"The file {tocEntry.Name} is outside the output directory");
215+
}
207216

208217
stream.Seek(tocEntry.Offset, SeekOrigin.Begin);
209218
if (tocEntry.IsCompressed)
@@ -212,9 +221,8 @@ private static bool ExtractFile(FileStream stream, Ddd.Rbin.TocEntry tocEntry, s
212221
}
213222
else
214223
{
215-
var writeStream = File.OpenWrite(outPath);
224+
using var writeStream = new FileStream(outPath, FileMode.Create, FileAccess.Write, FileShare.None);
216225
writeStream.Write(stream.ReadBytes((int)tocEntry.Size));
217-
writeStream.Close();
218226
}
219227

220228
return true;

OpenKh.Command.SpawnScript/Program.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,21 @@ private class DecompileCommand
5757

5858
protected int OnExecute(CommandLineApplication app)
5959
{
60-
OutputPath ??= Path.Combine(Path.GetDirectoryName(InputPath), $"{Path.GetFileNameWithoutExtension(InputPath)}.txt");
61-
var spawnScript = File.OpenRead(InputPath).Using(AreaDataScript.Read);
62-
File.WriteAllText(OutputPath, AreaDataScript.Decompile(spawnScript));
60+
var OutputName = $"{Path.GetFileNameWithoutExtension(InputPath)}.txt";
61+
var InputBaseDir = Path.GetDirectoryName(InputPath);
62+
if (String.IsNullOrEmpty(InputBaseDir))
63+
{
64+
InputBaseDir = Environment.CurrentDirectory;
65+
}
66+
OutputPath ??= Path.Combine(InputBaseDir, OutputName);
67+
if (!String.IsNullOrEmpty(OutputPath))
68+
{
69+
var spawnScript = File.OpenRead(InputPath).Using(AreaDataScript.Read);
70+
71+
var fullPath = Path.GetFullPath(OutputPath);
72+
73+
File.WriteAllText(fullPath, AreaDataScript.Decompile(spawnScript));
74+
}
6375
return 0;
6476
}
6577
}
@@ -76,9 +88,22 @@ private class CompileCommand
7688

7789
protected int OnExecute(CommandLineApplication app)
7890
{
79-
OutputPath ??= Path.Combine(Path.GetDirectoryName(InputPath), $"{Path.GetFileNameWithoutExtension(InputPath)}.spawnscript");
80-
var spawnScript = AreaDataScript.Compile(File.ReadAllText(InputPath));
81-
File.Create(OutputPath).Using(stream => AreaDataScript.Write(stream, spawnScript));
91+
var OutputName = $"{Path.GetFileNameWithoutExtension(InputPath)}.spawnscript";
92+
var InputBaseDir = Path.GetDirectoryName(InputPath);
93+
if (String.IsNullOrEmpty(InputBaseDir))
94+
{
95+
InputBaseDir = Environment.CurrentDirectory;
96+
}
97+
OutputPath ??= Path.Combine(InputBaseDir, OutputName);
98+
if (!String.IsNullOrEmpty(OutputPath))
99+
{
100+
var spawnScript = AreaDataScript.Compile(File.ReadAllText(InputPath));
101+
102+
var fullPath = Path.GetFullPath(OutputPath);
103+
104+
using var stream = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None);
105+
AreaDataScript.Write(stream, spawnScript);
106+
}
82107
return 0;
83108
}
84109
}

0 commit comments

Comments
 (0)