v4.2.0
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.
IncrementalandGuardedHeapAllocationclass methods now useInterlockedcorrectly for thread safety and throwInvalidOperationExceptionwhen accessed from multiple threads simultaneously. Nobody should be trying to useIDisposableclasses from multiple threads (most .NETIDisposableclasses are not thread-safe), but this provides protection for people who do.lockstatements can be used in calling code to avoid these exceptions when using multiple threads.Interlockedis also now used properly in the internal functionSodium.Initialize(), although libsodium initialisation should be thread-safe anyway, so this is more of a precaution.Incrementalclass states are now allocated after validation instead of on creation. It was done this way before to match the previousstructapproach.- Enum parameters are now validated for
IncrementalXChaCha20Poly1305.EncryptChunk()andEncodings.GetToBase64BufferSize()/ToBase64()/GetFromBase64BufferSize()/FromBase64(), throwingArgumentOutOfRangeExceptionif 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-finallypattern 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 toEncodings.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 otherIDisposableclasses.