fix: make the parser more robust and no longer accept invalid input silently.
This commit is contained in:
parent
1d472ed61f
commit
2624b83a79
3 changed files with 25 additions and 4 deletions
|
@ -3,7 +3,7 @@ using Jellyfin.Plugin.SmartPlaylist.Lisp;
|
|||
|
||||
namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
|
||||
public class Parser {
|
||||
private StringTokenStream _sts;
|
||||
internal StringTokenStream _sts;
|
||||
public Parser(StringTokenStream tokens) {
|
||||
_sts = tokens;
|
||||
}
|
||||
|
@ -29,13 +29,18 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
|
|||
Debug.Assert(start.value == end.value);
|
||||
Debug.Assert("\"".Contains(start.value));
|
||||
string r = "";
|
||||
bool exit_ok = false;
|
||||
while (_sts.Available() > 0) {
|
||||
Token<string> t = _sts.Get();
|
||||
if (t.value == end.value) {
|
||||
exit_ok = true;
|
||||
break;
|
||||
}
|
||||
r += t.value;
|
||||
}
|
||||
if (!exit_ok) {
|
||||
throw new ApplicationException($"Failed to parse string, are you missing the closing quotes? String is: {r}");
|
||||
}
|
||||
_sts.Commit();
|
||||
return new String(r);
|
||||
}
|
||||
|
@ -69,11 +74,16 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
|
|||
if (";".Contains(start.value)) {
|
||||
return parse_comment(start, end);
|
||||
}
|
||||
Debug.Assert(end != null);
|
||||
if (end == null) {
|
||||
throw new ApplicationException($"Don't know how to parse grouping starting with token '{start.value}'");
|
||||
}
|
||||
|
||||
IList<Expression> expressions = new List<Expression>();
|
||||
bool exit_ok = false;
|
||||
while (_sts.Available() > 0) {
|
||||
Token<string> t = _sts.Get();
|
||||
if (t.value == end.value) {
|
||||
exit_ok = true;
|
||||
_sts.Commit();
|
||||
break;
|
||||
}
|
||||
|
@ -87,7 +97,11 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
|
|||
_sts.Rewind(1);
|
||||
expressions.Add(parse());
|
||||
}
|
||||
return Cons.FromList(expressions);
|
||||
var r = Cons.FromList(expressions);
|
||||
if (!exit_ok) {
|
||||
throw new ApplicationException($"Failed to parse grouping, are you missing some closing braces? Parsed expressions: {r}");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
Expression parse_atom(AtomToken at) {
|
||||
|
|
|
@ -601,7 +601,11 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
|
|||
throw new ApplicationException($"Not handled case '{expression}'");
|
||||
}
|
||||
public Expression eval(Parser p) {
|
||||
return eval(p.parse());
|
||||
Expression r = eval(p.parse());
|
||||
if (p._sts.Available() > 0) {
|
||||
throw new ApplicationException($"Did not consume all tokens, remaining program is {string.Join(" ", p._sts.Remainder())}");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
public Expression eval(StringTokenStream sts) {
|
||||
return eval(new Parser(sts));
|
||||
|
|
|
@ -56,6 +56,9 @@ namespace Jellyfin.Plugin.SmartPlaylist.Util {
|
|||
public IStream<T> Copy() {
|
||||
return new Stream<T>(_items, _cursor, _ephemeralCursor);
|
||||
}
|
||||
public IList<T> Remainder() {
|
||||
return _items.Skip(_cursor).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue