From 7f5fc6f91a65c9c9fd881323243ad647309f9d3a Mon Sep 17 00:00:00 2001 From: MCJack123 Date: Tue, 24 Aug 2021 18:06:10 -0400 Subject: [PATCH] Fixed comparison of substrings --- src/ltm.c | 2 +- src/lvm.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/ltm.c b/src/ltm.c index 0e367a3..6dea114 100644 --- a/src/ltm.c +++ b/src/ltm.c @@ -23,7 +23,7 @@ const char *const luaT_typenames[] = { "nil", "boolean", "userdata", "number", "string", "table", "function", "userdata", "thread", - "proto", "upval" + "proto", "upval", "dead key", "rope", "substring" }; diff --git a/src/lvm.c b/src/lvm.c index 65bcd90..c794d27 100644 --- a/src/lvm.c +++ b/src/lvm.c @@ -241,6 +241,28 @@ static int l_strcmp (const TString *ls, const TString *rs) { } +static int l_substrcmp (const TSubString *ls, const TSubString *rs) { + const char *l = getstr(ls->tss.str) + ls->tss.offset; + size_t ll = ls->tss.len; + const char *r = getstr(rs->tss.str) + rs->tss.offset; + size_t lr = rs->tss.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; resolverope(L, l); @@ -251,6 +273,8 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { return luai_numlt(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if (ttissubstr(l)) + return l_substrcmp(rawssvalue(l), rawssvalue(r)) < 0; else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; return luaG_ordererror(L, l, r); @@ -260,15 +284,15 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; resolverope(L, l); - resolvesubstr(L, l); resolverope(L, r); - resolvesubstr(L, r); if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return luai_numle(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if (ttissubstr(l)) + return l_substrcmp(rawssvalue(l), rawssvalue(r)) <= 0; else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */