Skip to content

v4.2.0

Choose a tag to compare

@samuel-lucas6 samuel-lucas6 released this 24 May 17:34
· 14 commits to main since this release

Please install Geralt via NuGet.

The format below is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Changed

  • Updated the test packages.

Fixed/Security

Important

Thank you to Alexey Avramov (@hakavlad) for providing AI code audits of Geralt v4.1.0 over email, which identified several Informational-Medium issues. Some were new from rerunning the models, and others were repeats or due to failed patching because I rushed parts of the last release.

Claude 4.7 Opus bullets 1, 4, and 6; GPT-5.5 Pro bullets 2, 3, 5, 6, 9, and 11; and Gemini 3.1 Pro bullets 2 and 6 have been addressed in this release, with the rest being either invalid or intentionally left. Note that some of these bullets overlap.

  • Incremental and GuardedHeapAllocation class methods now use Interlocked correctly for thread safety and throw InvalidOperationException when accessed from multiple threads simultaneously. Nobody should be trying to use IDisposable classes from multiple threads (most .NET IDisposable classes are not thread-safe), but this provides protection for people who do. lock statements can be used in calling code to avoid these exceptions when using multiple threads.
  • Interlocked is also now used properly in the internal function Sodium.Initialize(), although libsodium initialisation should be thread-safe anyway, so this is more of a precaution.
  • Incremental class states are now allocated after validation instead of on creation. It was done this way before to match the previous struct approach.
  • Enum parameters are now validated for IncrementalXChaCha20Poly1305.EncryptChunk() and Encodings.GetToBase64BufferSize()/ToBase64()/GetFromBase64BufferSize()/FromBase64(), throwing ArgumentOutOfRangeException if the user passes a value that's not defined within the enum. No other classes use enums. Tests were added to cover these scenarios. This was overlooked.
  • A try-finally pattern is now used for all internal zeroing. X25519.DeriveSharedKey() could theoretically have thrown without internal buffers being cleared, but internal uses of functions shouldn't throw due to validation/correct usage.
  • Sodium.Initialize() was added to Encodings.GetToBase64BufferSize(), although it probably isn't required here. Every other function was correctly initialising libsodium before calling a libsodium function.
  • GuardedHeapAllocation.Dispose() now has a guard clause before freeing the pointer for consistency with the other IDisposable classes.