Author: rinrab Date: Sun Jan 4 12:24:35 2026 New Revision: 1931093 Log: bcrypt: Eliminate heap allocations when computing checksum contextless of a single data block. Use forbidden alloca() function to create the buffer and pass it to the initialization function. According to the documentation [1]#pbHashObject, we should not call BCryptDestroyHash() if non-null buffer is supplied.
* subversion/libsvn_subr/checksum_bcrypt.c (bcrypt_checksum): Manually initialize the context and the algorithm. Remove BCryptDestroyHash() call. [1] https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptcreatehash Modified: subversion/trunk/subversion/libsvn_subr/checksum_bcrypt.c Modified: subversion/trunk/subversion/libsvn_subr/checksum_bcrypt.c ============================================================================== --- subversion/trunk/subversion/libsvn_subr/checksum_bcrypt.c Sun Jan 4 12:10:02 2026 (r1931092) +++ subversion/trunk/subversion/libsvn_subr/checksum_bcrypt.c Sun Jan 4 12:24:35 2026 (r1931093) @@ -177,22 +177,29 @@ bcrypt_checksum(algorithm_state_t *algor const void *data, apr_size_t len) { - bcrypt_ctx_t bcrypt_ctx; - svn_error_t *err = SVN_NO_ERROR; + bcrypt_ctx_t bcrypt_ctx = { 0 }; + void *object_buf; - SVN_ERR(bcrypt_ctx_init(algorithm, &bcrypt_ctx)); + SVN_ERR(svn_atomic__init_once(&algorithm->initialized, algorithm_init, + algorithm, NULL)); - err = bcrypt_ctx_update(algorithm, &bcrypt_ctx, data, len); - if (err) - { - bcrypt_ctx_cleanup(&bcrypt_ctx); - return err; - } + SVN_ERR_ASSERT(algorithm->object_length < 4096); + object_buf = alloca(algorithm->object_length); - SVN_ERR(bcrypt_ctx_final(algorithm, &bcrypt_ctx, digest)); + SVN_ERR(handle_error(BCryptCreateHash(algorithm->alg_handle, + &bcrypt_ctx.handle, + object_buf, algorithm->object_length, + /* pbSecret */ NULL, + /* cbSecret */ 0, + /* dwFlags */ 0))); - bcrypt_ctx_cleanup(&bcrypt_ctx); - return err; + SVN_ERR(bcrypt_ctx_update(algorithm, &bcrypt_ctx, + data, len)); + + SVN_ERR(bcrypt_ctx_final(algorithm, &bcrypt_ctx, + digest)); + + return SVN_NO_ERROR; }
