VYaml
VYaml copied to clipboard
特定の文字から始まるstringを持つyamlをデシリアライズすると無限ループに陥る
概要
VYamlで特定の文字から始まるstringを持つyamlをデシリアライズすると、無限ループに陥ります。
Serialize*()
は問題なく動作します。
再現手順
- .NET コンソールアプリケーション(net8)を作成しVYaml 0.27.1をインストールします。
- 以下のコードを記述します。
using System;
using VYaml.Annotations;
using VYaml.Serialization;
var user = new User("Alice");
var v = YamlSerializer.Serialize(user);
Console.Write($"{user.Name}: Serialized");
YamlSerializer.Deserialize<User>(v); // Inf loop
Console.Write($"{user.Name}: Deserialized");
[YamlObject]
public partial record User(string Name);
- プログラムを実行すると、
Alice: Serialized
以降のログが表示されず、処理が進行しなくなります。
期待される結果
Alice: Serialized
Alice: Deserialized
と表示され、プログラムが正常に終了する。
環境
.NET: 8.0 VYaml: 0.27.1
追加の検証コード
using System;
using System.Threading.Tasks;
using VYaml.Annotations;
using VYaml.Serialization;
var cases = new[]
{
// inf loop
new User("Alice"),
new User("AA"),
new User("0"),
new User("ア"),
new User("*"),
// success
new User("Alice"),
new User("ALICE"),
new User("あ"),
new User("ぁ"),
new User("ア"),
new User("'Alice'"),
new User("\"Alice\""),
};
foreach (var record in cases)
{
try
{
bool isFinished = false;
Task.Run(() =>
{
var v = YamlSerializer.Serialize(record);
Console.Write($"{record.Name}: Serialized");
YamlSerializer.Deserialize<User>(v);
Console.WriteLine($" -> Deserialized");
isFinished = true;
});
await Task.Delay(TimeSpan.FromSeconds(0.1));
if (!isFinished)
Console.WriteLine($" -> Inf loop");
}
catch (Exception ex)
{
Console.WriteLine($" -> Deserialize Failed");
}
}
[YamlObject]
public partial record User(string Name);
Alice: Serialized -> Inf loop
AA: Serialized -> Inf loop
0: Serialized -> Inf loop
ア: Serialized -> Inf loop
*: Serialized -> Inf loop
Alice: Serialized -> Deserialized
ALICE: Serialized -> Deserialized
あ: Serialized -> Deserialized
ぁ: Serialized -> Deserialized
ア: Serialized -> Deserialized
'Alice': Serialized -> Deserialized
"Alice": Serialized -> Deserialized