Skip to content

Commit

Permalink
Deserialize compressed documents correctly
Browse files Browse the repository at this point in the history
Fix #16414

Related Work Items: #16
  • Loading branch information
MikeAlhayek committed Jul 9, 2024
1 parent d51f74a commit 4f5a751
Showing 1 changed file with 21 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using OrchardCore.Data.Documents;
Expand All @@ -14,13 +15,10 @@ public class DefaultDocumentSerializer : IDocumentSerializer
{
public static readonly DefaultDocumentSerializer Instance = new();

public DefaultDocumentSerializer()
public Task<byte[]> SerializeAsync<TDocument>(TDocument document, int compressThreshold = int.MaxValue)
where TDocument : class, IDocument, new()
{
}

public Task<byte[]> SerializeAsync<TDocument>(TDocument document, int compressThreshold = int.MaxValue) where TDocument : class, IDocument, new()
{
var data = Encoding.UTF8.GetBytes(JConvert.SerializeObject(document));
var data = JsonSerializer.SerializeToUtf8Bytes(document, JOptions.Default);
if (data.Length >= compressThreshold)
{
data = Compress(data);
Expand All @@ -29,22 +27,34 @@ public DefaultDocumentSerializer()
return Task.FromResult(data);
}

public Task<TDocument> DeserializeAsync<TDocument>(byte[] data) where TDocument : class, IDocument, new()
public Task<TDocument> DeserializeAsync<TDocument>(byte[] data)
where TDocument : class, IDocument, new()
{
if (IsCompressed(data))
{
data = Decompress(data);
}

var document = JConvert.DeserializeObject<TDocument>(Encoding.UTF8.GetString(data));
using var ms = new MemoryStream(data);

var document = JsonSerializer.Deserialize<TDocument>(ms, JOptions.Default);

return Task.FromResult(document);
}

private static readonly byte[] _gZipHeaderBytes = [0x1f, 0x8b];

internal static bool IsCompressed(byte[] data) =>
data.Length < _gZipHeaderBytes.Length && data[0..1] == _gZipHeaderBytes;
internal static bool IsCompressed(byte[] data)
{
// Ensure data is at least as long as the GZip header
if (data.Length >= _gZipHeaderBytes.Length)
{
// Compare the header bytes.
return data.Take(_gZipHeaderBytes.Length).SequenceEqual(_gZipHeaderBytes);
}

return false;
}

internal static byte[] Compress(byte[] data)
{
Expand Down

0 comments on commit 4f5a751

Please sign in to comment.