acarteas / FileCache

FileCache is a concrete implementation of the .Net Framework 4's System.Runtime.Caching.ObjectCache that uses the local filesystem as the target location.
Apache License 2.0
77 stars 24 forks source link

BinaryFormatter should be replaced #49

Open njannink opened 3 years ago

njannink commented 3 years ago

I updated my project to Net5 and now I get an exception because the BinaryFormatter has been marked insecure and throws and exception

https://docs.microsoft.com/nl-nl/dotnet/standard/serialization/binaryformatter-security-guide

acarteas commented 3 years ago

Closed in PR #52

acarteas commented 3 years ago

Reopened because serialization is still used in some cases.

palenshus commented 1 year ago

I got bit by this in a way I couldn't workaround with EnableUnsafeBinaryFormatterSerialization, so I ended up making a quick replacement using https://github.com/Cysharp/MemoryPack, hope this helps someone else experiencing the same issue until this gets fixed:

public partial class FileCache<T>
{
    private readonly string path;
    private readonly Dictionary<string, (DateTimeOffset, T)> cache;

    public FileCache(string path)
    {
        this.path = path;
        if (File.Exists(path))
        {
            var bytes = File.ReadAllBytes(path);
            this.cache = MemoryPackSerializer.Deserialize<Dictionary<string, (DateTimeOffset, T)>>(bytes);
        }
        else
        {
            this.cache = new();
        }
    }

    public async Task<T> GetOrAddAsync(string key, Func<Task<T>> valueFactory, DateTimeOffset absoluteExpiration)
    {
        if (!this.cache.ContainsKey(key) || DateTime.Now > this.cache[key].Item1)
        {
            this.cache[key] = (absoluteExpiration, await valueFactory());
            var bytes = MemoryPackSerializer.Serialize(this.cache);
            await File.WriteAllBytesAsync(this.path, bytes);
        }

        return this.cache[key].Item2;
    }
}