aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <8965202+gpanders@users.noreply.github.com>2024-04-15 11:06:54 -0500
committerGitHub <noreply@github.com>2024-04-15 11:06:54 -0500
commit533e01a75b71e93686e7bc9c79fe0172ca876d91 (patch)
tree9a48a36c05a8e4b301d00a011262cdef0eb48404
parent57adf8c6e01d9395eb52fe03571c535571efdc4b (diff)
downloadrneovim-533e01a75b71e93686e7bc9c79fe0172ca876d91.tar.gz
rneovim-533e01a75b71e93686e7bc9c79fe0172ca876d91.tar.bz2
rneovim-533e01a75b71e93686e7bc9c79fe0172ca876d91.zip
fix(base64): properly handle embedded NULLs when decoding (#28349)
-rw-r--r--src/nvim/base64.c14
-rw-r--r--src/nvim/lua/base64.c5
-rw-r--r--test/functional/lua/base64_spec.lua1
3 files changed, 15 insertions, 5 deletions
diff --git a/src/nvim/base64.c b/src/nvim/base64.c
index d461b7e3ff..a645c64fe3 100644
--- a/src/nvim/base64.c
+++ b/src/nvim/base64.c
@@ -132,12 +132,18 @@ char *base64_encode(const char *src, size_t src_len)
/// Decode a Base64 encoded string.
///
+/// The returned string is NOT null-terminated, because the decoded string may
+/// contain embedded NULLs. Use the output parameter out_lenp to determine the
+/// length of the returned string.
+///
/// @param src Base64 encoded string
/// @param src_len Length of {src}
+/// @param [out] out_lenp Returns the length of the decoded string
/// @return Decoded string
-char *base64_decode(const char *src, size_t src_len)
+char *base64_decode(const char *src, size_t src_len, size_t *out_lenp)
{
assert(src != NULL);
+ assert(out_lenp != NULL);
char *dest = NULL;
@@ -155,7 +161,7 @@ char *base64_decode(const char *src, size_t src_len)
const uint8_t *s = (const uint8_t *)src;
- dest = xmalloc(out_len + 1);
+ dest = xmalloc(out_len);
int acc = 0;
int acc_len = 0;
@@ -203,7 +209,7 @@ char *base64_decode(const char *src, size_t src_len)
}
}
- dest[out_len] = '\0';
+ *out_lenp = out_len;
return dest;
@@ -212,5 +218,7 @@ invalid:
xfree((void *)dest);
}
+ *out_lenp = 0;
+
return NULL;
}
diff --git a/src/nvim/lua/base64.c b/src/nvim/lua/base64.c
index c1f43a37d7..8fe918493a 100644
--- a/src/nvim/lua/base64.c
+++ b/src/nvim/lua/base64.c
@@ -45,12 +45,13 @@ static int nlua_base64_decode(lua_State *L)
size_t src_len = 0;
const char *src = lua_tolstring(L, 1, &src_len);
- const char *ret = base64_decode(src, src_len);
+ size_t out_len = 0;
+ const char *ret = base64_decode(src, src_len, &out_len);
if (ret == NULL) {
return luaL_error(L, "Invalid input");
}
- lua_pushstring(L, ret);
+ lua_pushlstring(L, ret, out_len);
xfree((void *)ret);
return 1;
diff --git a/test/functional/lua/base64_spec.lua b/test/functional/lua/base64_spec.lua
index bb986c3220..c7fbe2ad23 100644
--- a/test/functional/lua/base64_spec.lua
+++ b/test/functional/lua/base64_spec.lua
@@ -42,6 +42,7 @@ describe('vim.base64', function()
̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕
Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮
]],
+ 'Hello\0world',
}
for _, v in ipairs(values) do