hadashiA / VYaml

The extra fast, low memory footprint YAML library for C#, focued on .NET and Unity.
MIT License
309 stars 19 forks source link

特定の文字から始まるstringを持つyamlをデシリアライズすると無限ループに陥る #120

Open Rapilias opened 2 weeks ago

Rapilias commented 2 weeks ago

概要

VYamlで特定の文字から始まるstringを持つyamlをデシリアライズすると、無限ループに陥ります。 Serialize*()は問題なく動作します。

再現手順

  1. .NET コンソールアプリケーション(net8)を作成しVYaml 0.27.1をインストールします。
  2. 以下のコードを記述します。
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);
  1. プログラムを実行すると、Alice: Serialized以降のログが表示されず、処理が進行しなくなります。

期待される結果

Alice: Serialized Alice: Deserialized と表示され、プログラムが正常に終了する。

環境

.NET: 8.0 VYaml: 0.27.1

追加の検証コード ```csharp 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(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); ``` ```sh 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 ```