Commit d88c6c45 authored by Jesse McGrew's avatar Jesse McGrew
Browse files

Issue warning MDL0430 for tables defined with a length prefix that's too

narrow to hold the number of elements. [ZILF-220]
parent 53d2d888ab88
......@@ -269,6 +269,8 @@ namespace Zilf.Diagnostics
public const int _0_LEXV_Table_Initializer_Is_Not_A_Multiple_Of_3_Elements = 428;
[Warning("{0}'{1} is parsed as two separate words, {0} and {1}; did you mean {0}\\'{1}?")]
public const int _0_1_Is_Parsed_As_Two_Separate_Words_0_And_1_Did_You_Mean_0_1 = 429;
[Warning("{0}: length prefix overflow: table element count ({1}) cannot be stored in a {2}")]
public const int _0_Length_Prefix_Overflow_Table_Element_Count_1_Cannot_Be_Stored_In_A_2 = 430;
// Modularity (package system, definitions sections) - 0500
......
......@@ -571,17 +571,17 @@ namespace Zilf.Interpreter
}
}
if ((flags & TableFlags.Lexv) != 0)
var elementCount = count * Math.Max(initializer.Length, 1);
if ((flags & TableFlags.Lexv) != 0 && (elementCount % 3) != 0)
{
var elementCount = count * Math.Max(initializer.Length, 1);
if ((elementCount % 3) != 0)
{
ctx.HandleError(new InterpreterError(
InterpreterMessages._0_LEXV_Table_Initializer_Is_Not_A_Multiple_Of_3_Elements,
"ITABLE"));
}
ctx.HandleError(new InterpreterError(
InterpreterMessages._0_LEXV_Table_Initializer_Is_Not_A_Multiple_Of_3_Elements,
"ITABLE"));
}
CheckForTableLengthPrefixOverflow(ctx, "ITABLE", flags, elementCount);
var tab = ZilTable.Create(count, initializer.Length == 0 ? null : initializer, flags, null);
tab.SourceLine = ctx.TopFrame.SourceLine;
if ((flags & TableFlags.TempTable) == 0)
......@@ -589,6 +589,34 @@ namespace Zilf.Interpreter
return tab;
}
static void CheckForTableLengthPrefixOverflow(Context ctx, string name, TableFlags flags, int elementCount)
{
int maxPrefixValue;
string prefixType;
if ((flags & TableFlags.ByteLength) != 0)
{
(maxPrefixValue, prefixType) = (byte.MaxValue, "byte");
}
else if ((flags & TableFlags.WordLength) != 0)
{
(maxPrefixValue, prefixType) = (ushort.MaxValue, "word");
}
else
{
return;
}
if (elementCount > maxPrefixValue)
{
ctx.HandleError(new InterpreterError(
InterpreterMessages._0_Length_Prefix_Overflow_Table_Element_Count_1_Cannot_Be_Stored_In_A_2,
name,
elementCount,
prefixType));
}
}
static ZilTable PerformTable(Context ctx, ZilListoidBase? flagList, ZilObject[] values,
bool pure, bool wantLength)
{
......@@ -700,6 +728,8 @@ namespace Zilf.Interpreter
newValues.Add(val);
}
CheckForTableLengthPrefixOverflow(ctx, name, flags, newValues.Count);
var tab = ZilTable.Create(1, newValues.ToArray(), flags, pattern?.ToArray());
tab.SourceLine = ctx.TopFrame.SourceLine;
if (!tempTable)
......
......@@ -239,5 +239,32 @@ namespace Zilf.Tests.Integration
.ImpliesAsync(
"<=? <GET <ZREST ,TBL 4> 0> 300>");
}
[TestMethod]
public async Task Table_With_Length_Prefix_Should_Warn_If_Overflowing()
{
await AssertGlobals(
"<CONSTANT FIELD <ITABLE BYTE 2500>>")
.WithWarnings("MDL0430")
.CompilesAsync();
await AssertGlobals(
"<CONSTANT FIELD <ITABLE WORD 70000>>")
.WithWarnings("MDL0430")
.CompilesAsync();
const string SOver256 =
"This string is longer than two hundred and fifty-six characters. " +
"This string is longer than two hundred and fifty-six characters. " +
"This string is longer than two hundred and fifty-six characters. " +
"This string is longer than two hundred and fifty-six characters. " +
"This string is longer than two hundred and fifty-six characters. " +
"This string is longer than two hundred and fifty-six characters. ";
await AssertGlobals(
@$"<CONSTANT FIELD <TABLE (STRING LENGTH) ""{SOver256}"">>")
.WithWarnings("MDL0430")
.CompilesAsync();
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment