Prevents infinite propagation on input proxy and judge.

This commit is contained in:
2023-02-28 13:47:38 +08:00
parent a755cc13bd
commit 1a30149942
2 changed files with 26 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ using Cryville.Common.Unity.Input;
using Cryville.Crtr.Config; using Cryville.Crtr.Config;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine; using UnityEngine;
namespace Cryville.Crtr { namespace Cryville.Crtr {
@@ -209,14 +210,15 @@ namespace Cryville.Crtr {
} }
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv"); static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv"); static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag) { unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag, int depth = 0) {
if (depth >= 16) throw new InputProxyException("Input propagation limit reached\nThe ruleset has invalid input definitions");
var def = _ruleset.inputs[target]; var def = _ruleset.inputs[target];
if (def.pass != null) { if (def.pass != null) {
foreach (var p in def.pass) { foreach (var p in def.pass) {
_etor.ContextCascadeInsert(); _etor.ContextCascadeInsert();
_arbop.Name = _var_value; _arbop.Name = _var_value;
if (!nullflag) _etor.Evaluate(_arbop, p.Value); if (!nullflag) _etor.Evaluate(_arbop, p.Value);
OnInput(id, p.Key, ft, tt, nullflag); OnInput(id, p.Key, ft, tt, nullflag, depth + 1);
_etor.ContextCascadeDiscard(); _etor.ContextCascadeDiscard();
} }
} }
@@ -306,4 +308,12 @@ namespace Cryville.Crtr {
return !lhs.Equals(rhs); return !lhs.Equals(rhs);
} }
} }
[Serializable]
public class InputProxyException : Exception {
public InputProxyException() { }
public InputProxyException(string message) : base(message) { }
public InputProxyException(string message, Exception inner) : base(message, inner) { }
protected InputProxyException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
} }

View File

@@ -4,6 +4,7 @@ using Cryville.Common.Pdt;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Runtime.Serialization;
using System.Text.Formatting; using System.Text.Formatting;
namespace Cryville.Crtr { namespace Cryville.Crtr {
@@ -134,7 +135,7 @@ namespace Cryville.Crtr {
if (actlist.Count > 0) { if (actlist.Count > 0) {
_numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3); _numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3);
_numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4); _numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4);
var index = 0; int index = 0, iter = 0;
while (index >= 0 && index < actlist.Count) { while (index >= 0 && index < actlist.Count) {
var ev = actlist[index]; var ev = actlist[index];
_numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1); _numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
@@ -154,19 +155,21 @@ namespace Cryville.Crtr {
if (index < 0) index = ~index; if (index < 0) index = ~index;
} }
else index++; else index++;
if (iter++ >= 16) throw new JudgePropagationException();
} }
else index++; else index++;
} }
} }
} }
bool Pass(JudgeEvent ev, float time, Identifier[] ids) { bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth = 0) {
if (depth >= 16) throw new JudgePropagationException();
foreach (var i in ids) { foreach (var i in ids) {
var def = _rs.judges[i]; var def = _rs.judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit); if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
else _flag = true; else _flag = true;
if (_flag) { if (_flag) {
if (def.scores != null) UpdateScore(def.scores); if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(ev, time, def.pass); if (def.pass != null) Pass(ev, time, def.pass, depth + 1);
ev.Handler.ReportJudge(ev, time, i); ev.Handler.ReportJudge(ev, time, i);
return true; return true;
} }
@@ -323,4 +326,12 @@ namespace Cryville.Crtr {
public string format = ""; public string format = "";
} }
#endregion #endregion
[Serializable]
public class JudgePropagationException : Exception {
public JudgePropagationException() : base("Judge propagation limit reached\nThe ruleset has invalid judge definitions") { }
public JudgePropagationException(string message) : base(message) { }
public JudgePropagationException(string message, Exception inner) : base(message, inner) { }
protected JudgePropagationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
} }