summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxaizek <xaizek@posteo.net>2024-05-10 13:04:24 +0300
committerxaizek <xaizek@posteo.net>2024-05-10 13:04:24 +0300
commit68f8b900cfc505c3422e57993c94cd995838793e (patch)
tree019a0a2d644f60ff63aa6d7be16701c78d753075
parenta8a0ffb1b0f5b10b64918853e16198fda703adff (diff)
parentc1cc08111402542ee920c20f517e3438475daaf0 (diff)
Merge branch 'infer-sa-fixes'HEADmaster
Fix several potential issues discovered by Infer. Thanks to ZhipengXue97.
-rw-r--r--src/cmd_handlers.c5
-rw-r--r--src/lua/common.c14
-rw-r--r--src/lua/common.h5
-rw-r--r--src/lua/vifmentry.c4
-rw-r--r--src/lua/vifmjob.c9
-rw-r--r--src/lua/vifmview.c16
-rw-r--r--src/lua/vlua_state.c2
-rw-r--r--src/modes/cmdline.c13
-rw-r--r--src/utils/str.c29
9 files changed, 65 insertions, 32 deletions
diff --git a/src/cmd_handlers.c b/src/cmd_handlers.c
index 79df65ef0..ea32df303 100644
--- a/src/cmd_handlers.c
+++ b/src/cmd_handlers.c
@@ -3701,6 +3701,11 @@ mark_cmd(const cmd_info_t *cmd_info)
}
expanded_path = expand_tilde(cmd_info->argv[1]);
+ if(expanded_path == NULL)
+ {
+ return CMDS_ERR_NO_MEM;
+ }
+
if(!is_path_absolute(expanded_path))
{
free(expanded_path);
diff --git a/src/lua/common.c b/src/lua/common.c
index 51d169d6c..553aaea75 100644
--- a/src/lua/common.c
+++ b/src/lua/common.c
@@ -76,13 +76,25 @@ vlua_cmn_check_opt_field(lua_State *lua, int table_idx, const char name[],
if(type != lua_type)
{
- return luaL_error(lua, "`%s` value must be a %s",name,
+ return luaL_error(lua, "`%s` value must be a %s", name,
lua_typename(lua, lua_type));
}
return 1;
}
void *
+vlua_cmn_check_this(lua_State *lua, int idx)
+{
+ void *udata = lua_touserdata(lua, idx);
+ if(udata == NULL)
+ {
+ const char *type = lua_typename(lua, lua_type(lua, idx));
+ luaL_error(lua, "Value at %d must be user data, got %s", idx, type);
+ }
+ return udata;
+}
+
+void *
vlua_cmn_to_pointer(lua_State *lua)
{
void *ptr = (void *)lua_topointer(lua, -1);
diff --git a/src/lua/common.h b/src/lua/common.h
index bfd7e9f5a..acd6a2219 100644
--- a/src/lua/common.h
+++ b/src/lua/common.h
@@ -39,6 +39,11 @@ void vlua_cmn_check_field(struct lua_State *lua, int table_idx,
int vlua_cmn_check_opt_field(struct lua_State *lua, int table_idx,
const char name[], int lua_type);
+/* Retrieves user data from a specified stack index aborting (Lua does
+ * longjmp()) if it's missing or isn't user data. Returns user data pointer,
+ * never NULL. */
+void * vlua_cmn_check_this(struct lua_State *lua, int idx);
+
/* Converts Lua value at the top of the stack into a C pointer without popping
* it. Returns the pointer. */
void * vlua_cmn_to_pointer(struct lua_State *lua);
diff --git a/src/lua/vifmentry.c b/src/lua/vifmentry.c
index e50fe5bcb..1263c8e8f 100644
--- a/src/lua/vifmentry.c
+++ b/src/lua/vifmentry.c
@@ -137,7 +137,7 @@ VLUA_API(vifmentry_gc)(lua_State *lua)
static int
VLUA_API(vifmentry_gettarget)(lua_State *lua)
{
- vifm_entry_t *vifm_entry = lua_touserdata(lua, lua_upvalueindex(1));
+ vifm_entry_t *vifm_entry = vlua_cmn_check_this(lua, lua_upvalueindex(1));
if(vifm_entry->type != FT_LINK)
{
@@ -158,7 +158,7 @@ VLUA_API(vifmentry_gettarget)(lua_State *lua)
static int
VLUA_API(vifmentry_mimetype)(lua_State *lua)
{
- vifm_entry_t *vifm_entry = lua_touserdata(lua, lua_upvalueindex(1));
+ vifm_entry_t *vifm_entry = vlua_cmn_check_this(lua, lua_upvalueindex(1));
const char *mimetype = get_mimetype(vifm_entry->full_path,
/*resolve_symlinks=*/1);
diff --git a/src/lua/vifmjob.c b/src/lua/vifmjob.c
index aa3b7dedf..47a465e97 100644
--- a/src/lua/vifmjob.c
+++ b/src/lua/vifmjob.c
@@ -81,7 +81,12 @@ static const luaL_Reg vifmjob_methods[] = {
{ NULL, NULL }
};
-/* Address of this variable serves as a key in Lua table. */
+/*
+ * Address of this variable serves as a key in Lua table which maps VifmJob
+ * instances onto dictionary with such fields:
+ * - "obj" - vifm_job_t user data
+ * - "on_exit" - Lua callback to invoke when the job is done
+ */
static char jobs_key;
void
@@ -104,6 +109,7 @@ vifmjob_finish(lua_State *lua)
lua_pop(lua, 1);
bg_job_t *job = lua_touserdata(lua, -1);
+ assert(job != NULL && "List of Lua jobs includes a bad key!");
bg_job_set_exit_cb(job, NULL, NULL);
}
@@ -210,6 +216,7 @@ job_exit_cb(struct bg_job_t *job, void *arg)
lua_getfield(vlua->lua, -2, "obj");
vifm_job_t *vifm_job = lua_touserdata(vlua->lua, -1);
+ assert(vifm_job != NULL && "List of Lua jobs is includes bad element!");
/* Remove the table entry we've just used. */
lua_pushlightuserdata(vlua->lua, job);
diff --git a/src/lua/vifmview.c b/src/lua/vifmview.c
index 4ee77bd9e..8a174ff18 100644
--- a/src/lua/vifmview.c
+++ b/src/lua/vifmview.c
@@ -198,14 +198,14 @@ VLUA_API(cursor_index)(lua_State *lua)
const char *key = luaL_checkstring(lua, 2);
if(strcmp(key, "pos") == 0)
{
- const unsigned int *id = lua_touserdata(lua, 1);
+ const unsigned int *id = vlua_cmn_check_this(lua, 1);
view_t *view = find_view(lua, *id);
lua_pushinteger(lua, view->list_pos + 1);
return 1;
}
else if(strcmp(key, "entry") == 0)
{
- unsigned int *id = lua_touserdata(lua, 1);
+ unsigned int *id = vlua_cmn_check_this(lua, 1);
lua_pushlightuserdata(lua, id);
lua_pushcclosure(lua, VLUA_REF(cursor_entry), 1);
return 1;
@@ -225,7 +225,7 @@ VLUA_API(cursor_newindex)(lua_State *lua)
{
return 0;
}
- const unsigned int *id = lua_touserdata(lua, 1);
+ const unsigned int *id = vlua_cmn_check_this(lua, 1);
view_t *view = find_view(lua, *id);
const int pos = luaL_checkinteger(lua, 3) - 1;
fpos_set_pos(view, pos);
@@ -253,7 +253,7 @@ VLUA_API(cursor_newindex)(lua_State *lua)
static int
VLUA_API(cursor_entry)(lua_State *lua)
{
- const unsigned int *id = lua_touserdata(lua, lua_upvalueindex(1));
+ const unsigned int *id = vlua_cmn_check_this(lua, lua_upvalueindex(1));
view_t *view = find_view(lua, *id);
vifmentry_new(lua, &view->dir_entry[view->list_pos]);
return 1;
@@ -340,7 +340,7 @@ VLUA_API(locopts_newindex)(lua_State *lua)
static int
do_opt(lua_State *lua, opt_t *opt, int set)
{
- const unsigned int *id = lua_touserdata(lua, 1);
+ const unsigned int *id = vlua_cmn_check_this(lua, 1);
view_t *view = find_view(lua, *id);
if(view == curr_view)
@@ -379,7 +379,7 @@ do_opt(lua_State *lua, opt_t *opt, int set)
static int
VLUA_IMPL(restore_curr_view)(lua_State *lua)
{
- view_t *curr = lua_touserdata(lua, lua_upvalueindex(1));
+ view_t *curr = vlua_cmn_check_this(lua, lua_upvalueindex(1));
curr_view = curr;
load_view_options(curr_view);
return 1;
@@ -389,7 +389,7 @@ VLUA_IMPL(restore_curr_view)(lua_State *lua)
static int
VLUA_IMPL(get_opt_wrapper)(lua_State *lua)
{
- opt_t *opt = lua_touserdata(lua, 1);
+ opt_t *opt = vlua_cmn_check_this(lua, 1);
return vlua_cmn_get_opt(lua, opt);
}
@@ -397,7 +397,7 @@ VLUA_IMPL(get_opt_wrapper)(lua_State *lua)
static int
VLUA_IMPL(set_opt_wrapper)(lua_State *lua)
{
- opt_t *opt = lua_touserdata(lua, 1);
+ opt_t *opt = vlua_cmn_check_this(lua, 1);
return vlua_cmn_set_opt(lua, opt);
}
diff --git a/src/lua/vlua_state.c b/src/lua/vlua_state.c
index 07015c860..1f44f5ba8 100644
--- a/src/lua/vlua_state.c
+++ b/src/lua/vlua_state.c
@@ -126,6 +126,8 @@ vlua_state_get(lua_State *lua)
lua_gettable(lua, LUA_REGISTRYINDEX);
vlua_t *vlua = lua_touserdata(lua, -1);
lua_pop(lua, 1);
+
+ assert(vlua != NULL && "Failed to obtain vlua state!");
return vlua;
}
diff --git a/src/modes/cmdline.c b/src/modes/cmdline.c
index ca003a0d5..718222e75 100644
--- a/src/modes/cmdline.c
+++ b/src/modes/cmdline.c
@@ -2365,16 +2365,17 @@ static char *
escape_cmd_for_pasting(const char str[])
{
wchar_t *const wide_input = vifm_wcsdup(input_stat.line);
- char *mb_input;
- char *escaped;
+ if(wide_input == NULL)
+ {
+ return NULL;
+ }
wide_input[input_stat.index] = L'\0';
- mb_input = to_multibyte(wide_input);
-
- escaped = cmds_insertion_escape(mb_input, strlen(mb_input), str);
+ char *mb_input = to_multibyte(wide_input);
+ free(wide_input);
+ char *escaped = cmds_insertion_escape(mb_input, strlen(mb_input), str);
free(mb_input);
- free(wide_input);
return escaped;
}
diff --git a/src/utils/str.c b/src/utils/str.c
index 9f951ca75..d85e36df3 100644
--- a/src/utils/str.c
+++ b/src/utils/str.c
@@ -291,37 +291,38 @@ transform_ascii_str(const char str[], int (*f)(int), char buf[], size_t buf_len)
}
/* Transforms characters of the string to while they fit in the buffer by
- * calling specified function on them. Returns zero on success or non-zero if
- * output buffer is too small. */
+ * calling specified function on them. Returns zero on success or non-zero on
+ * error (output buffer is too small or out of memory) in which case buffer is
+ * filled with full UTF-8 characters from input. */
static int
transform_wide_str(const char str[], wint_t (*f)(wint_t), char buf[],
size_t buf_len)
{
- size_t copied;
- int error;
- wchar_t *wstring;
- wchar_t *p;
- char *narrow;
-
- wstring = to_wide(str);
+ wchar_t *wstring = to_wide(str);
if(wstring == NULL)
{
(void)utf8_strcpy(buf, str, buf_len);
return 1;
}
- p = wstring;
+ wchar_t *p = wstring;
while(*p != L'\0')
{
*p = f(*p);
++p;
}
- narrow = to_multibyte(wstring);
- copied = utf8_strcpy(buf, narrow, buf_len);
- error = copied == 0U || narrow[copied - 1U] != '\0';
-
+ char *narrow = to_multibyte(wstring);
free(wstring);
+
+ if(narrow == NULL)
+ {
+ (void)utf8_strcpy(buf, str, buf_len);
+ return 1;
+ }
+
+ size_t copied = utf8_strcpy(buf, narrow, buf_len);
+ int error = (copied == 0U || narrow[copied - 1U] != '\0');
free(narrow);
return error;