Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
470 changes: 470 additions & 0 deletions GFramework.Godot.Tests/Config/GodotYamlConfigLoaderTests.cs

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions GFramework.Godot.Tests/Config/GodotYamlConfigTableSourceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using GFramework.Godot.Config;
using NUnit.Framework;

namespace GFramework.Godot.Tests.Config;

/// <summary>
/// 验证 Godot YAML 配置表来源描述会拒绝可能逃逸缓存根目录的不安全相对路径。
/// </summary>
[TestFixture]
public sealed class GodotYamlConfigTableSourceTests
{
/// <summary>
/// 验证配置目录路径必须保持为无根、无遍历段的安全相对路径。
/// </summary>
/// <param name="configRelativePath">待验证的配置目录路径。</param>
[TestCase("../outside")]
[TestCase(@"..\outside")]
[TestCase("./monster")]
[TestCase(@".\monster")]
[TestCase("monster/../outside")]
[TestCase(@"monster\..\outside")]
[TestCase("monster/./child")]
[TestCase(@"monster\.\child")]
[TestCase("/monster")]
[TestCase("C:/monster")]
[TestCase(@"C:\monster")]
[TestCase("res://monster")]
[TestCase("user://monster")]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
public void Constructor_Should_Throw_When_Config_Relative_Path_Is_Not_Safe(string configRelativePath)
{
var exception = Assert.Throws<ArgumentException>(() =>
_ = new GodotYamlConfigTableSource("monster", configRelativePath));

Assert.That(exception!.ParamName, Is.EqualTo("configRelativePath"));
}

/// <summary>
/// 验证 schema 路径在提供时也必须满足同样的安全相对路径约束。
/// </summary>
/// <param name="schemaRelativePath">待验证的 schema 路径。</param>
[TestCase("../schemas/monster.schema.json")]
[TestCase(@"..\schemas\monster.schema.json")]
[TestCase("./schemas/monster.schema.json")]
[TestCase(@".\schemas\monster.schema.json")]
[TestCase("schemas/../monster.schema.json")]
[TestCase(@"schemas\..\monster.schema.json")]
[TestCase("schemas/./monster.schema.json")]
[TestCase(@"schemas\.\monster.schema.json")]
[TestCase("/schemas/monster.schema.json")]
[TestCase("C:/schemas/monster.schema.json")]
[TestCase(@"C:\schemas\monster.schema.json")]
[TestCase("res://schemas/monster.schema.json")]
[TestCase("user://schemas/monster.schema.json")]
public void Constructor_Should_Throw_When_Schema_Relative_Path_Is_Not_Safe(string schemaRelativePath)
{
var exception = Assert.Throws<ArgumentException>(() =>
_ = new GodotYamlConfigTableSource("monster", "monster", schemaRelativePath));

Assert.That(exception!.ParamName, Is.EqualTo("schemaRelativePath"));
}

/// <summary>
/// 验证合法的相对目录和 schema 路径仍可正常构造元数据对象。
/// </summary>
[Test]
public void Constructor_Should_Accept_Safe_Relative_Paths()
{
var source = new GodotYamlConfigTableSource(
"monster",
"monster/configs",
"schemas/monster.schema.json");

Assert.Multiple(() =>
{
Assert.That(source.TableName, Is.EqualTo("monster"));
Assert.That(source.ConfigRelativePath, Is.EqualTo("monster/configs"));
Assert.That(source.SchemaRelativePath, Is.EqualTo("schemas/monster.schema.json"));
});
}
}
2 changes: 2 additions & 0 deletions GFramework.Godot.Tests/GFramework.Godot.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

<ItemGroup>
<ProjectReference Include="..\GFramework.Godot\GFramework.Godot.csproj"/>
<ProjectReference Include="..\GFramework.Game.Abstractions\GFramework.Game.Abstractions.csproj"/>
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj"/>
</ItemGroup>

</Project>
Loading
Loading