aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-08-15 16:30:32 +0300
committerZyX <kp-pav@yandex.ru>2017-08-15 16:34:25 +0300
commitef6641ba6952fd868d3efafb2a23234ac9bd0d3f (patch)
treee818eba4d5d227227e232ffb1764de2b03e3607f /src
parent44dc8bbb1330a07a7cd3c1b379d6e15dc8258010 (diff)
downloadrneovim-ef6641ba6952fd868d3efafb2a23234ac9bd0d3f.tar.gz
rneovim-ef6641ba6952fd868d3efafb2a23234ac9bd0d3f.tar.bz2
rneovim-ef6641ba6952fd868d3efafb2a23234ac9bd0d3f.zip
lua/executor: Make stricmp function work with strings with NULs
Diffstat (limited to 'src')
-rw-r--r--src/nvim/lua/executor.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index eb821f7831..4ed477ea36 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -124,9 +124,36 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
/// omitted.
static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
- const char *s1 = luaL_checklstring(lstate, 1, NULL);
- const char *s2 = luaL_checklstring(lstate, 2, NULL);
- const int ret = STRICMP(s1, s2);
+ size_t s1_len;
+ size_t s2_len;
+ const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
+ const char *s2 = luaL_checklstring(lstate, 2, &s2_len);
+ char *nul1;
+ char *nul2;
+ int ret = 0;
+ assert(s1[s1_len] == NUL);
+ assert(s2[s2_len] == NUL);
+ do {
+ nul1 = memchr(s1, NUL, s1_len);
+ nul2 = memchr(s2, NUL, s2_len);
+ ret = STRICMP(s1, s2);
+ // Compare "a\0" greater then "a".
+ if (ret == 0 && (nul1 == NULL) != (nul2 == NULL)) {
+ ret = ((nul1 != NULL) - (nul2 != NULL));
+ break;
+ }
+ if (nul1 != NULL) {
+ assert(nul2 != NULL);
+ // Due to lowercase letter having possibly different byte length then
+ // uppercase letter can’t shift both strings by the same amount of bytes.
+ s1_len -= (size_t)(nul1 - s1) + 1;
+ s2_len -= (size_t)(nul2 - s2) + 1;
+ s1 = nul1 + 1;
+ s2 = nul2 + 1;
+ } else {
+ break;
+ }
+ } while (ret == 0);
lua_pop(lstate, 2);
lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0)));
return 1;