diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 487db826fa..74cb9666ff 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1,4 +1,4 @@ -*builtin.txt* For Vim version 9.1. Last change: 2025 Sep 15 +*builtin.txt* For Vim version 9.1. Last change: 2025 Sep 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -575,7 +575,7 @@ settabwinvar({tabnr}, {winnr}, {varname}, {val}) settagstack({nr}, {dict} [, {action}]) Number modify tag stack using {dict} setwinvar({nr}, {varname}, {val}) none set {varname} in window {nr} to {val} -sha256({string}) String SHA256 checksum of {string} +sha256({expr}) String SHA256 checksum of String or Blob shellescape({string} [, {special}]) String escape {string} for use as shell command argument @@ -10336,12 +10336,14 @@ setwinvar({winnr}, {varname}, {val}) *setwinvar()* Return type: |Number| -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. Can also be used as a |method|: > GetText()->sha256() + GetBlob()->sha256() < Return type: |String| diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index 1522296433..1433cfb45b 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.1. Last change: 2025 Sep 15 +*version9.txt* For Vim version 9.1. Last change: 2025 Sep 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41735,6 +41735,7 @@ Functions: ~ - |chdir()| allows to optionally specify a scope argument - |matchfuzzy()| and |matchfuzzypos()| use an improved fuzzy matching algorithm (same as fzy). +- |sha256()| also accepts a |Blob| as argument. Others: ~ - the regex engines match correctly case-insensitive multi-byte characters diff --git a/src/evalfunc.c b/src/evalfunc.c index 3a0e9a77af..a1076f07dc 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1257,6 +1257,7 @@ static argcheck_T arg1_string[] = {arg_string}; static argcheck_T arg1_string_or_list_any[] = {arg_string_or_list_any}; static argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string}; static argcheck_T arg1_string_or_nr[] = {arg_string_or_nr}; +static argcheck_T arg1_string_or_blob[] = {arg_string_or_blob}; static argcheck_T arg2_any_buffer[] = {arg_any, arg_buffer}; static argcheck_T arg2_buffer_any[] = {arg_buffer, arg_any}; static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool}; @@ -2842,7 +2843,7 @@ static const funcentry_T global_functions[] = ret_number_bool, f_settagstack}, {"setwinvar", 3, 3, FEARG_3, arg3_number_string_any, ret_void, f_setwinvar}, - {"sha256", 1, 1, FEARG_1, arg1_string, + {"sha256", 1, 1, FEARG_1, arg1_string_or_blob, ret_string, #ifdef FEAT_CRYPT f_sha256 @@ -11742,20 +11743,36 @@ f_settagstack(typval_T *argvars, typval_T *rettv) #ifdef FEAT_CRYPT /* - * "sha256({string})" function + * "sha256({expr})" function */ static void f_sha256(typval_T *argvars, typval_T *rettv) { char_u *p; + int len; - if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) + if (in_vim9script() && check_for_string_or_blob_arg(argvars, 0) == FAIL) return; - p = tv_get_string(&argvars[0]); - rettv->vval.v_string = vim_strsave( - sha256_bytes(p, (int)STRLEN(p), NULL, 0)); 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) + { + p = (char_u *)blob->bv_ga.ga_data; + len = blob->bv_ga.ga_len; + rettv->vval.v_string = vim_strsave(sha256_bytes(p, len, NULL, 0)); + } + } + else + { + p = tv_get_string(&argvars[0]); + rettv->vval.v_string = vim_strsave( + sha256_bytes(p, (int)STRLEN(p), NULL, 0)); + } } #endif // FEAT_CRYPT diff --git a/src/testdir/test_sha256.vim b/src/testdir/test_sha256.vim index 3db1b2a99c..4da4a6f94e 100644 --- a/src/testdir/test_sha256.vim +++ b/src/testdir/test_sha256.vim @@ -18,6 +18,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 diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 1cf4010cd8..339506bac9 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -4162,10 +4162,14 @@ def Test_setwinvar() enddef def Test_sha256() - v9.CheckSourceDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1']) - v9.CheckSourceDefAndScriptFailure(['sha256(0zABCD)'], ['E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1']) + v9.CheckSourceDefAndScriptFailure(['sha256(100)'], ['E1013: Argument 1: type mismatch, expected string but got number', 'E1221: String or Blob required for argument 1']) assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256('abc')) assert_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256('')) + + assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256(0z616263)) + assert_equal('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256(0z)) + assert_equal('ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', sha256(0z61)) + assert_equal('5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953', sha256(0zdeadbeef)) enddef def Test_shiftwidth() diff --git a/src/version.c b/src/version.c index 2e0c771771..a1e0521959 100644 --- a/src/version.c +++ b/src/version.c @@ -724,6 +724,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1774, /**/ 1773, /**/