From 39a21d749d9ff6c69b173900ec76b14ddc09626a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 21 Sep 2025 06:16:20 +0800 Subject: [PATCH] vim-patch:9.1.1774: cannot calculate sha256 of a Blob Problem: cannot calculate sha256() of a Blob Solution: Change sha256() to accept a Blob or String argument (thinca). closes: vim/vim#18336 https://github.com/vim/vim/commit/4150283b837975152d36f87a2bb975e894bc965c Co-authored-by: thinca --- runtime/doc/vimfn.txt | 7 ++++--- runtime/lua/vim/_meta/vimfn.lua | 7 ++++--- src/nvim/eval.lua | 7 ++++--- src/nvim/eval/funcs.c | 21 +++++++++++++++------ test/old/testdir/test_sha256.vim | 12 ++++++++++++ 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt index 130a6a4832..ea191cb960 100644 --- a/runtime/doc/vimfn.txt +++ b/runtime/doc/vimfn.txt @@ -9468,12 +9468,13 @@ setwinvar({nr}, {varname}, {val}) *setwinvar()* Return: ~ (`any`) -sha256({string}) *sha256()* +sha256({expr}) *sha256()* Returns a String with 64 hex characters, which is the SHA256 - checksum of {string}. + checksum of {expr}. + {expr} is a String or a Blob. Parameters: ~ - • {string} (`string`) + • {expr} (`string`) Return: ~ (`string`) diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index c56026b707..028a23d053 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -8631,11 +8631,12 @@ function vim.fn.settagstack(nr, dict, action) end function vim.fn.setwinvar(nr, varname, val) end --- Returns a String with 64 hex characters, which is the SHA256 ---- checksum of {string}. +--- checksum of {expr}. +--- {expr} is a String or a Blob. --- ---- @param string string +--- @param expr string --- @return string -function vim.fn.sha256(string) end +function vim.fn.sha256(expr) end --- Escape {string} for use as a shell command argument. --- diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index f921ac9d84..4b58eabed8 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -10419,13 +10419,14 @@ M.funcs = { base = 1, desc = [=[ Returns a String with 64 hex characters, which is the SHA256 - checksum of {string}. + checksum of {expr}. + {expr} is a String or a Blob. ]=], name = 'sha256', - params = { { 'string', 'string' } }, + params = { { 'expr', 'string' } }, returns = 'string', - signature = 'sha256({string})', + signature = 'sha256({expr})', }, shellescape = { args = { 1, 2 }, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 1378fbc26b..54fd9d326a 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7189,15 +7189,24 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } -/// f_sha256 - sha256({string}) function +/// "sha256({expr})" function static void f_sha256(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - const char *p = tv_get_string(&argvars[0]); - const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0); - - // make a copy of the hash (sha256_bytes returns a static buffer) - rettv->vval.v_string = xstrdup(hash); rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + + if (argvars[0].v_type == VAR_BLOB) { + blob_T *blob = argvars[0].vval.v_blob; + if (blob != NULL) { + const uint8_t *p = (uint8_t *)blob->bv_ga.ga_data; + int len = blob->bv_ga.ga_len; + rettv->vval.v_string = xstrdup(sha256_bytes(p, (size_t)len, NULL, 0)); + } + } else { + const char *p = tv_get_string(&argvars[0]); + const char *hash = sha256_bytes((const uint8_t *)p, strlen(p), NULL, 0); + rettv->vval.v_string = xstrdup(hash); + } } /// "shellescape({string})" function diff --git a/test/old/testdir/test_sha256.vim b/test/old/testdir/test_sha256.vim index b0941c60e3..9f4599bd73 100644 --- a/test/old/testdir/test_sha256.vim +++ b/test/old/testdir/test_sha256.vim @@ -19,4 +19,16 @@ function Test_sha256() " test for contains non-ascii char: call assert_equal('5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953', sha256("\xde\xad\xbe\xef")) + + " test for blob: + " empty blob + call assert_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256(0z)) + " blob with single byte + call assert_equal('ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', sha256(0z61)) + " blob with "abc" + call assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256(0z616263)) + " blob with non-ascii bytes + call assert_equal('5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953', sha256(0zdeadbeef)) endfunction + +" vim: shiftwidth=2 sts=2 expandtab