GFramework/GFramework.Godot.Tests/Config/GodotYamlConfigTableSourceTests.cs
GeWuYou c29c9fe8f4 feat(config): 添加配置表来源安全性验证功能
- 在 GodotYamlConfigLoader 中增加对路径中冒号字符的验证,防止 Windows 无效名称和 ADS 类似语法
- 新增 GodotYamlConfigTableSource 类用于描述配置表来源信息,并实现安全路径验证
- 添加对配置路径和 schema 路径的严格安全检查,拒绝包含根路径、遍历标记或冒号字符的路径
- 扩展测试用例覆盖多种不安全路径场景,包括路径遍历、绝对路径前缀和冒号字符
- 为新功能添加完整的单元测试验证安全路径验证逻辑
2026-04-11 07:37:22 +08:00

85 lines
3.2 KiB
C#

using System;
using GFramework.Godot.Config;
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")]
[TestCase("schemas:bad/monster")]
[TestCase(@"schemas:bad\monster")]
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")]
[TestCase("schemas:bad/monster.schema.json")]
[TestCase(@"schemas:bad\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"));
});
}
}