// Copyright (c) 2025-2026 GeWuYou // SPDX-License-Identifier: Apache-2.0 using GFramework.Godot.Config; namespace GFramework.Godot.Tests.Config; /// /// 验证 Godot YAML 配置表来源描述会拒绝可能逃逸缓存根目录的不安全相对路径。 /// [TestFixture] public sealed class GodotYamlConfigTableSourceTests { /// /// 验证配置目录路径必须保持为无根、无遍历段的安全相对路径。 /// /// 待验证的配置目录路径。 [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(() => _ = new GodotYamlConfigTableSource("monster", configRelativePath)); Assert.That(exception!.ParamName, Is.EqualTo("configRelativePath")); } /// /// 验证 schema 路径在提供时也必须满足同样的安全相对路径约束。 /// /// 待验证的 schema 路径。 [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(() => _ = new GodotYamlConfigTableSource("monster", "monster", schemaRelativePath)); Assert.That(exception!.ParamName, Is.EqualTo("schemaRelativePath")); } /// /// 验证合法的相对目录和 schema 路径仍可正常构造元数据对象。 /// [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")); }); } }