diff options
author | xaizek <xaizek@posteo.net> | 2024-05-10 13:04:24 +0300 |
---|---|---|
committer | xaizek <xaizek@posteo.net> | 2024-05-10 13:04:24 +0300 |
commit | 68f8b900cfc505c3422e57993c94cd995838793e (patch) | |
tree | 019a0a2d644f60ff63aa6d7be16701c78d753075 | |
parent | a8a0ffb1b0f5b10b64918853e16198fda703adff (diff) | |
parent | c1cc08111402542ee920c20f517e3438475daaf0 (diff) |
Fix several potential issues discovered by Infer.
Thanks to ZhipengXue97.
-rw-r--r-- | src/cmd_handlers.c | 5 | ||||
-rw-r--r-- | src/lua/common.c | 14 | ||||
-rw-r--r-- | src/lua/common.h | 5 | ||||
-rw-r--r-- | src/lua/vifmentry.c | 4 | ||||
-rw-r--r-- | src/lua/vifmjob.c | 9 | ||||
-rw-r--r-- | src/lua/vifmview.c | 16 | ||||
-rw-r--r-- | src/lua/vlua_state.c | 2 | ||||
-rw-r--r-- | src/modes/cmdline.c | 13 | ||||
-rw-r--r-- | src/utils/str.c | 29 |
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; |