don't allow image formats to have 0 width/height/tiles

This commit is contained in:
haven1433 2022-11-14 07:25:59 -06:00
parent 614a619ead
commit e1da957c30
8 changed files with 42 additions and 9 deletions

View File

@ -1391,7 +1391,7 @@ namespace HavenSoft.HexManiac.Core.Models {
}
public override void ObserveAnchorWritten(ModelDelta changeToken, string anchorName, IFormattedRun run) {
Debug.Assert(run.Length > 0); // writing an anchor of length zero is stupid.
Debug.Assert(run.Length > 0, $"Trying to write a run of length zero! {run.FormatString} at {run.Start:X6}"); // writing an anchor of length zero is stupid.
lock (threadlock) {
int location = run.Start;
var index = BinarySearch(location);

View File

@ -44,7 +44,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = SpriteRunContentStrategy.IsValid(spriteFormat.BitsPerPixel);
var error = SpriteRunContentStrategy.IsValid(spriteFormat);
if (error.HasError) return error;
run = new LzSpriteRun(spriteFormat, model, dataIndex, run.PointerSources);
if (run.Length == LZRun.DecompressedTooLong) return new ErrorInfo("Decompressed more bytes than expected. Add a ! to override this.");

View File

@ -22,7 +22,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = SpriteRunContentStrategy.IsValid(TilemapFormat.BitsPerPixel);
var error = SpriteRunContentStrategy.IsValid(TilemapFormat);
if (error.HasError) return error;
var lzRun = new LZRun(model, dataIndex);
var rowRemainder = lzRun.DecompressedLength % TilemapFormat.TileWidth;

View File

@ -23,7 +23,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = SpriteRunContentStrategy.IsValid(TilesetFormat.BitsPerPixel);
var error = SpriteRunContentStrategy.IsValid(TilesetFormat);
if (error.HasError) return error;
var lzRun = new LzTilesetRun(TilesetFormat, model, dataIndex);
if (lzRun.Length == LZRun.DecompressedTooLong) return new ErrorInfo("Decompressed more bytes than expected. Add a ! to override this.");

View File

@ -36,17 +36,37 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = IsValid(spriteFormat.BitsPerPixel);
var error = IsValid(spriteFormat);
if (error.HasError) return error;
run = new SpriteRun(model, dataIndex, spriteFormat, run.PointerSources);
return ErrorInfo.NoError;
}
public static ErrorInfo IsValid(int bitsPerPixel) {
if (!new[] { 1, 2, 4, 8 }.Contains(bitsPerPixel)) {
public static ErrorInfo IsValid(TilemapFormat format) {
if (!format.BitsPerPixel.IsAny(1, 2, 4, 8)) {
return new ErrorInfo("Sprite bpp must be 1, 2, 4, or 8.");
}
return ErrorInfo.NoError;
}
public static ErrorInfo IsValid(TilesetFormat format) {
if (!format.BitsPerPixel.IsAny(1, 2, 4, 8)) {
return new ErrorInfo("Sprite bpp must be 1, 2, 4, or 8.");
}
if (format.MaxTiles == 0 || format.Tiles == 0) {
return new ErrorInfo("Tilesets must have at least 1 tile.");
}
return ErrorInfo.NoError;
}
public static ErrorInfo IsValid(SpriteFormat format) {
if (!format.BitsPerPixel.IsAny(1, 2, 4, 8)) {
return new ErrorInfo("Sprite bpp must be 1, 2, 4, or 8.");
}
if (format.ExpectedByteLength <= 0) {
return new ErrorInfo("Sprite width/height must positive.");
}
return ErrorInfo.NoError;
}
}
}

View File

@ -28,7 +28,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = SpriteRunContentStrategy.IsValid(format.BitsPerPixel);
var error = SpriteRunContentStrategy.IsValid(format);
if (error.HasError) return error;
var newRun = new TilemapRun(model, dataIndex, format);
run = newRun;

View File

@ -31,7 +31,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Factory {
}
public override ErrorInfo TryParseData(IDataModel model, string name, int dataIndex, ref IFormattedRun run) {
var error = SpriteRunContentStrategy.IsValid(TilesetFormat.BitsPerPixel);
var error = SpriteRunContentStrategy.IsValid(TilesetFormat);
if (error.HasError) return error;
var newRun = new TilesetRun(TilesetFormat, model, run.Start, run.PointerSources);
var nextRun = model.GetNextRun(run.Start + 1);

View File

@ -882,6 +882,19 @@ namespace HavenSoft.HexManiac.Tests {
Assert.Equal("Decompressed more bytes than expected. Add a ! to override this.", Errors[0]);
}
[Theory]
[InlineData("`ucs4x0x1`")]
[InlineData("`ucs4x1x0`")]
[InlineData("`uct4x0`")]
[InlineData("`lzs4x0x1`")]
[InlineData("`lzs4x1x0`")]
[InlineData("`lzt4x0`")]
public void ImageFormatWithZeroDimensionErrors(string format) {
WriteCompressedData(0, 0x20);
ViewPort.Edit($"^image{format} ");
Assert.Single(Errors);
}
private void WriteCompressedData(int start, int length) {
var compressedData = LZRun.Compress(new byte[length], 0, length);
for (int i = 0; i < compressedData.Count; i++) Model[start + i] = compressedData[i];