mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-11-15 17:00:38 +00:00
Locate the PKZIP file data instead of reading it into the model (#102)
* Locate the PKZIP file data instead of reading it into the model Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep only the offset of the PKZIP file data The length is the compressed size from the local file header or the ZIP64 extended field, which the printer already shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the file data property as a comment for documentation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,13 @@ namespace SabreTools.Data.Models.PKZIP
|
||||
/// File data, appears after the encryption header
|
||||
/// if it exists or after the local file header otherwise
|
||||
/// </summary>
|
||||
public byte[] FileData { get; set; } = [];
|
||||
/// Not read into the model, see <see cref="FileDataOffset"/>
|
||||
// public byte[] FileData { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Offset of the file data in the stream
|
||||
/// </summary>
|
||||
public long FileDataOffset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data descriptors, appears after the file data
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
@@ -68,5 +69,48 @@ namespace SabreTools.Serialization.Readers.Test
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidStream_FileDataLocated()
|
||||
{
|
||||
Stream? data = CreateArchive();
|
||||
var deserializer = new PKZIP();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.NotNull(actual);
|
||||
|
||||
var localFile = Assert.Single(actual.LocalFiles!);
|
||||
var header = localFile.LocalFileHeader;
|
||||
Assert.Equal(30 + header.FileNameLength + header.ExtraFieldLength, localFile.FileDataOffset);
|
||||
Assert.Single(actual.CentralDirectoryHeaders!);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TruncatedFileData_Null()
|
||||
{
|
||||
byte[] archive = CreateArchive().ToArray();
|
||||
Stream? data = new MemoryStream(archive, 0, 512);
|
||||
var deserializer = new PKZIP();
|
||||
|
||||
var actual = deserializer.Deserialize(data);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an archive with one stored file of 1000 bytes
|
||||
/// </summary>
|
||||
private static MemoryStream CreateArchive()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
var entry = archive.CreateEntry("file.bin", CompressionLevel.NoCompression);
|
||||
using var entryStream = entry.Open();
|
||||
entryStream.Write([.. Enumerable.Range(0, 1000).Select(i => (byte)i)], 0, 1000);
|
||||
}
|
||||
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,13 +472,13 @@ namespace SabreTools.Serialization.Readers
|
||||
|
||||
#region File Data
|
||||
|
||||
// Try to read the file data
|
||||
var fileData = data.ReadBytes((int)compressedSize);
|
||||
if (fileData.Length < (long)compressedSize)
|
||||
// The file data is skipped, so a large archive is not read into memory
|
||||
if (compressedSize > (ulong)(data.Length - data.Position))
|
||||
return null;
|
||||
|
||||
// Set the file data
|
||||
obj.FileData = fileData;
|
||||
// Set the location of the file data
|
||||
obj.FileDataOffset = data.Position;
|
||||
data.SeekIfPossible((long)compressedSize, SeekOrigin.Current);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -89,16 +89,7 @@ namespace SabreTools.Wrappers
|
||||
|
||||
#region File Data
|
||||
|
||||
var fileData = localFile.FileData;
|
||||
if (fileData is null)
|
||||
{
|
||||
builder.AppendLine(" [File Data]: [NULL]");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(fileData.Length, " [File Data] Length");
|
||||
//builder.AppendLine(fileData, " [File Data] Data");
|
||||
}
|
||||
builder.AppendLine(localFile.FileDataOffset, " [File Data] Offset");
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user