Please install Geralt via NuGet.
The format below is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Changed
- libsodium defined constants are now checked against their libsodium function in tests.
- Updated the test packages.
Fixed/Security
Important
Thank you to Alexey Avramov (@hakavlad) for providing AI code audits of Geralt v4.2.0 over email, which identified several Informational-Medium issues. Most were repeat findings that are invalid or risk accepted. However, a few were new from rerunning the models, and one was a mistake in the previous release related to thread safety.
Gemini 3.1 Pro Preview bullet 5; Claude 4.7 Opus bullets 10 and 12; GPT-5.5 Pro bullets 1, 4, 5, and 6; and Claude Fable 5 bullets 1, 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.
ConstantTime.IsAllZeros()now throwsArgumentOutOfRangeExceptionif the buffer is empty. I'm arguing that this isn't a breaking change because the method name and documentation implies that the buffer has a length. I don't think there's any legitimate use case for allowing an empty buffer, so I'm not sure why this was done before.Spans.Concat()methods now throwArgumentExceptionif the buffer overlaps with any of the inputs because this is a misuse of these methods that can cause corruption. Tests have been updated for this. Again, this feels more like a bug fix than a breaking change, with nobody using these methods properly being affected.Argon2id.VerifyHash()andNeedsRehash()now check that everything after the first0x00byte in the password hash string is also zero. Test vectors have been added to cover this. libsodium expects null-terminated strings, and Geralt internally does this if the user provides a non-terminated string.IncrementalBLAKE2bnow stores the hash size when caching to avoid someone reinitialising and restoring a cached state with a different hash size.InvalidOperationExceptionis thrown if someone tries to do this, which can already be thrown in this method.IncrementalandGuardedHeapAllocationclass finalizers can no longer throw an exception when multiple threads are being used. Finalizers aren't meant to throw.- The internal
Sodium.Initialize()function now useslockto ensure that initialisation always occurs only once regardless of multiple threads. This was the original patch in v4.2.0 before I switched toInterlockedfor consistency with theIDisposableclasses without thinking, which introduced an early return scenario.