Skip to content

Commit 6787f01

Browse files
committed
LuaTableTextReader should not allow more than 1 value expression in the root.
1 parent f671d24 commit 6787f01

File tree

2 files changed

+59
-41
lines changed

2 files changed

+59
-41
lines changed

Luaon.NET/LuaTableTextReader.cs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,26 @@ public class LuaTableTextReader : IDisposable
5353
private enum State
5454
{
5555
Unknown = 0, // Determined by context (e.g. When leaving the current scope)
56-
Start = 1, // outside of table
57-
FieldStart, // At the middle of the table, but immediately after a field separator
58-
KeyStart, // At the beginning of table key expression []
59-
Key, // In table key expression, after the key literal
60-
KeyEnd, // Immediately after a key expression
61-
ValueStart, // Immediately after key expression and an equal sign
62-
FieldEnd, // (Should) immediately before a field separator
56+
Start = 1, // outside of table
57+
FieldStart, // At the middle of the table, but immediately after a field separator
58+
KeyStart, // At the beginning of table key expression []
59+
Key, // In table key expression, after the key literal
60+
KeyEnd, // Immediately after a key expression
61+
ValueStart, // Immediately after key expression and an equal sign
62+
FieldEnd, // (Should) immediately before a field separator
63+
End, // (Should be) end of input
6364
Error
6465
}
6566

6667
private enum Token
6768
{
6869
TableStart, // {
69-
TableEnd, // }
70-
KeyStart, // [
71-
KeyEnd, // ]
72-
Equal, // =
73-
Comma, // ,
74-
Literal, // "abc"
70+
TableEnd, // }
71+
KeyStart, // [
72+
KeyEnd, // ]
73+
Equal, // =
74+
Comma, // ,
75+
Literal, // "abc"
7576
}
7677

7778
// NextState[State][Token]
@@ -80,30 +81,29 @@ private enum Token
8081
// @formatter:off
8182
/* TableStart TableEnd KeyStart KeyEnd Equal Comma Literal */
8283
/* Unknown */ new[] {State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error},
83-
/* Start */ new[] {State.FieldStart, State.Error, State.Error, State.Error, State.Error, State.Error, State.Start},
84+
/* Start */ new[] {State.FieldStart, State.Error, State.Error, State.Error, State.Error, State.Error, State.End},
8485
/* FieldStart */ new[] {State.FieldStart, State.Unknown, State.KeyStart, State.Error, State.Error, State.Error, State.FieldEnd},
8586
/* KeyStart */ new[] {State.FieldStart, State.Error, State.Error, State.Error, State.Error, State.Error, State.Key},
8687
/* Key */ new[] {State.Error, State.Error, State.Error, State.KeyEnd, State.Error, State.Error, State.Error},
8788
/* KeyEnd */ new[] {State.Error, State.Error, State.Error, State.Error, State.ValueStart, State.Error, State.FieldStart},
8889
/* ValueStart */ new[] {State.FieldStart, State.Error, State.Error, State.Error, State.Error, State.Error, State.FieldEnd},
8990
/* FieldEnd */ new[] {State.Error, State.Unknown, State.Error, State.Error, State.Error, State.FieldStart, State.Error},
91+
/* End */ new[] {State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error},
9092
/* Error */ new[] {State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error},
9193
// @formatter:on
9294
};
9395

9496
private State currentState = State.Start;
9597

96-
private void AssertNextStateValid(Token token)
97-
{
98-
if (NextStateTable[(int)currentState][(int)token] == State.Error)
99-
throw MakeReaderException($"Unexpected token: {token}.");
100-
}
101-
10298
private void GotoNextState(Token token)
10399
{
104100
var next = NextStateTable[(int)currentState][(int)token];
105101
if (next == State.Error)
102+
{
103+
if (currentState == State.End)
104+
throw MakeReaderException("Detected extra content after the end of LUA object.");
106105
throw MakeReaderException($"Unexpected token: {token}.");
106+
}
107107
currentState = next;
108108
}
109109

@@ -128,7 +128,7 @@ private LuaContainerType Pop()
128128
{
129129
case LuaContainerType.None:
130130
Debug.Assert(contextStack.Count == 0);
131-
currentState = State.Start;
131+
currentState = State.End;
132132
break;
133133
case LuaContainerType.Table:
134134
currentState = context.ContainerType == LuaContainerType.Key
@@ -142,7 +142,7 @@ private LuaContainerType Pop()
142142
Debug.Assert(false, "Invalid ContainerType.");
143143
break;
144144
}
145-
// Return the poped container type
145+
// Return the popped container type
146146
return context.ContainerType;
147147
}
148148

@@ -696,7 +696,6 @@ private object ReadNumberLiteral()
696696
var sb = new StringBuilder(32);
697697
if (Consume("0x", true))
698698
{
699-
sb.Append("0x");
700699
NEXT_HEX_DIGIT:
701700
var c = LookAhead();
702701
if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')
@@ -709,21 +708,20 @@ private object ReadNumberLiteral()
709708
try
710709
{
711710
// 0x00000000
712-
if (expr.Length < 2 + 8)
711+
if (expr.Length < 8)
713712
{
714-
var v = Convert.ToInt32(expr) * signFactor;
713+
var v = Convert.ToInt32(expr, 16) * signFactor;
715714
return v == 0 ? boxedZero : v;
716715
}
717716
else
718717
{
719-
var v = Convert.ToInt64(expr) * signFactor;
718+
var v = Convert.ToInt64(expr, 16) * signFactor;
720719
return v == 0 ? boxedZero : v;
721720
}
722721
}
723722
catch (Exception ex)
724723
{
725-
throw MakeReaderException($"Cannot represent numeric literal “{expr}” with a proper number type.",
726-
ex);
724+
throw MakeReaderException($"Cannot represent numeric literal “{expr}” with a proper number type.", ex);
727725
}
728726
}
729727
else

XUnitTestProject1/Tests/LuaTableTextReaderTests.cs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.ComponentModel;
34
using System.IO;
45
using System.Text;
56
using Luaon;
@@ -19,27 +20,46 @@ private void AssertNextToken(LuaTableTextReader reader, LuaTableReaderToken toke
1920

2021
private LuaTableTextReader CreateReader(string content)
2122
{
22-
return new LuaTableTextReader(new StringReader(content.Replace("\r\n", "\n"))) {CloseReader = true};
23+
return new LuaTableTextReader(new StringReader(content.Replace("\r\n", "\n"))) { CloseReader = true };
2324
}
2425

25-
[Fact]
26-
public void ReadLiteralTest()
26+
[Theory]
27+
[InlineData("true", true)]
28+
[InlineData("false", false)]
29+
[InlineData("true -- Comment", true)]
30+
[InlineData("-- Comment\nfalse-- Comment", false)]
31+
[InlineData("nil", null)]
32+
[InlineData("0/0", double.NaN)]
33+
[InlineData("123", 123)]
34+
[InlineData("-0x45f", -0x45f)]
35+
[InlineData("'abc'", "abc")]
36+
[InlineData("\"def\\t\"", "def\t")]
37+
[InlineData("[[ghi\\t\\]]", "ghi\\t\\")]
38+
public void ReadLiteralTest(string expr, object value)
2739
{
28-
using (var reader = CreateReader("true false nil 0/0 123 -0x45f 'abc' \"def\\t\" [[ghi\\]]"))
40+
using (var reader = CreateReader(expr))
2941
{
30-
AssertNextToken(reader, LuaTableReaderToken.Value, true);
31-
AssertNextToken(reader, LuaTableReaderToken.Value, false);
32-
AssertNextToken(reader, LuaTableReaderToken.Value, null);
33-
AssertNextToken(reader, LuaTableReaderToken.Value, double.NaN);
34-
AssertNextToken(reader, LuaTableReaderToken.Value, 123);
35-
AssertNextToken(reader, LuaTableReaderToken.Value, -0x45f);
36-
AssertNextToken(reader, LuaTableReaderToken.Value, "abc");
37-
AssertNextToken(reader, LuaTableReaderToken.Value, "def\t");
38-
AssertNextToken(reader, LuaTableReaderToken.Value, "ghi\\");
42+
Assert.Equal(LuaTableReaderToken.None, reader.CurrentToken);
43+
Assert.Null(reader.CurrentValue);
44+
AssertNextToken(reader, LuaTableReaderToken.Value, value);
45+
AssertNextToken(reader, LuaTableReaderToken.None);
3946
AssertNextToken(reader, LuaTableReaderToken.None);
4047
}
4148
}
4249

50+
[Theory]
51+
[InlineData("true false")]
52+
[InlineData("true -- Comment\n123")]
53+
[InlineData("true,")]
54+
public void ReadExtraContentTest(string expr)
55+
{
56+
using (var reader = CreateReader(expr))
57+
{
58+
reader.Read();
59+
Assert.Throws<LuaTableReaderException>(() => reader.Read());
60+
}
61+
}
62+
4363
[Fact]
4464
public void ReadTableTest()
4565
{

0 commit comments

Comments
 (0)