чување e5eccfd2bdd28eddc4f8895e530fe7c284ebcfa3
родитељ 7fd3f47cad89c7dbc872fbae5b53ea385cb1e897
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Fri, 17 May 2024 00:13:11 +0200
Fix a few potential bugs thanks to LLVM's scan-build
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | draw.c | | | 3 | ++- |
| M | po.c | | | 125 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
| M | poe.c | | | 59 | ++++++++++++++++++++++++++++++++++++++++------------------- |
измењених датотека: 3, додавања: 135(+), брисања: 52(-)
diff --git a/draw.c b/draw.c
@@ -90,7 +90,7 @@ init_drawstate(struct DrawState* state, char* error, char* filename,
{
state->error = error;
state->filename = filename;
- state->real_filename = filename;
+ state->real_filename = NULL;
state->backup_filename = NULL;
state->rfn_len = 0;
state->search = NULL;
@@ -208,6 +208,7 @@ set_nplurals(struct DrawState* state, struct PoEntry* entry)
else if (read_number && *ppf >= '0' && *ppf <= '9')
{
*ptoken++ = *ppf++;
+ *ptoken = 0;
}
else if (read_number && *ppf == ';')
{
diff --git a/po.c b/po.c
@@ -280,7 +280,12 @@ u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr, int msgstr_index,
entry->msgstr_count * sizeof(size_t));
}
if (!newmsgstr || !newmsgstr_size || !newmsgstr_len)
+ {
+ free(newmsgstr);
+ free(newmsgstr_len);
+ free(newmsgstr_size);
return NULL;
+ }
*(newmsgstr + msgstr_index) = NULL;
entry->msgstr = newmsgstr;
entry->msgstr_size = newmsgstr_size;
@@ -478,12 +483,15 @@ load_file(struct DrawState* dstate, long* lineno, long* col)
/* when the .po file is not a standard text file (no LF at end) */
if (dstate->msgid_count > 1)
{
- if (entry->msgid)
- /* regular entry */
- dstate->msgid_count++;
- else if (entry->comment_lines > 0)
- /* obsolete entry */
- entry->obsolete = 1;
+ if (entry)
+ {
+ if (entry->msgid)
+ /* regular entry */
+ dstate->msgid_count++;
+ else if (entry->comment_lines > 0)
+ /* obsolete entry */
+ entry->obsolete = 1;
+ }
#ifndef PLURAL_STRING
if (has_plural_msgid && !dstate->entries->plural_forms)
STRLCPY(errors[ERR_NO_PLURAL_FORMS], dstate->error,
@@ -527,6 +535,7 @@ save_file(const struct PoEntry* entries, const size_t real_msgid_count,
char* backup_filename = NULL;
#endif
struct stat st;
+ int result = SAVE_ERR_NONE;
char* real_filename = NULL;
size_t rfn_len = 0;
Flags flags;
@@ -535,7 +544,10 @@ save_file(const struct PoEntry* entries, const size_t real_msgid_count,
return SAVE_ERR_CANT_ALLOC;
#ifdef CREATE_BACKUPS
if (!(backup_filename = calloc(MAXPATH, 1)))
+ {
+ free(real_filename);
return SAVE_ERR_CANT_ALLOC;
+ }
#endif
#ifdef CREATE_BACKUPS
@@ -545,31 +557,52 @@ save_file(const struct PoEntry* entries, const size_t real_msgid_count,
{
rfn_len = readlink(filename, real_filename, MAXPATH);
if (rfn_len == -1)
- return SAVE_ERR_CANT_READLINK;
+ {
+ result = SAVE_ERR_CANT_READLINK;
+ goto save_loop_entries_done;
+ }
real_filename[rfn_len] = 0;
if (stat(real_filename, &st) == -1)
- return SAVE_ERR_CANT_STAT_FILE;
+ {
+ result = SAVE_ERR_CANT_STAT_FILE;
+ goto save_loop_entries_done;
+ }
}
STRLCPY(filename, backup_filename, MAXPATH);
STRLCAT(backup_suffix, backup_filename, MAXPATH);
if (rename(rfn_len > 0 ? real_filename : filename,
backup_filename)
== -1)
- return SAVE_ERR_CANT_MOVE_FILE;
+ {
+ result = SAVE_ERR_CANT_MOVE_FILE;
+ goto save_loop_entries_done;
+ }
}
else
- return SAVE_ERR_CANT_STAT_FILE;
+ {
+ result = SAVE_ERR_CANT_STAT_FILE;
+ goto save_loop_entries_done;
+ }
#endif
if (!(output = fopen(rfn_len > 0 ? real_filename : filename, "wt")))
- return SAVE_ERR_CANT_OPEN_FILE;
+ {
+ result = SAVE_ERR_CANT_OPEN_FILE;
+ goto save_loop_entries_done;
+ }
#ifdef CREATE_BACKUPS
if (rfn_len > 0)
{
if (unlink(filename) == -1)
- return SAVE_ERR_CANT_UNLINK;
+ {
+ result = SAVE_ERR_CANT_UNLINK;
+ goto save_loop_entries_done;
+ }
if (symlink(real_filename, filename) == -1)
- return SAVE_ERR_CANT_SYMLINK;
+ {
+ result = SAVE_ERR_CANT_SYMLINK;
+ goto save_loop_entries_done;
+ }
}
chmod(rfn_len > 0 ? real_filename : filename, st.st_mode);
#endif
@@ -597,7 +630,10 @@ save_comments:
else
u8_comment = realloc(u8_comment, size);
if (!u8_comment)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
unicode_string_to_u8(u8_comment, size,
*(current->comments + c), len);
fprintf(output, "#%s%s\n", current->obsolete ? "~" : "",
@@ -623,7 +659,10 @@ save_comments:
u8_trans_comment
= realloc(u8_trans_comment, size);
if (!u8_trans_comment)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
unicode_string_to_u8(u8_trans_comment, size,
*(current->trans_comments + tc), len);
fprintf(output, "#.%s%s\n",
@@ -711,7 +750,10 @@ save_obsolete_check:
u8_msgid = malloc(size);
if (!u8_msgid)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgid, 0, size);
@@ -729,7 +771,10 @@ save_obsolete_check:
size = current->msgid_size * UTF8REPMAX + 1;
u8_msgid = malloc(size);
if (!u8_msgid)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgid, 0, size);
@@ -770,7 +815,10 @@ save_obsolete_check:
size = len * UTF8REPMAX + 1;
u8_msgid = malloc(size);
if (!u8_msgid)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgid, 0, size);
@@ -789,7 +837,10 @@ save_obsolete_check:
size = current->msgid_plural_size * UTF8REPMAX + 1;
u8_msgid = malloc(size);
if (!u8_msgid)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgid, 9, size);
@@ -844,7 +895,10 @@ save_obsolete_check:
size = len * UTF8REPMAX + 1;
u8_msgstr = malloc(size);
if (!u8_msgstr)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgstr, 0, size);
@@ -937,7 +991,10 @@ save_obsolete_check:
size = len * UTF8REPMAX + 1;
u8_msgstr = malloc(size);
if (!u8_msgstr)
- return SAVE_ERR_CANT_ALLOC;
+ {
+ result = SAVE_ERR_CANT_ALLOC;
+ goto save_loop_entries_done;
+ }
memset(u8_msgstr, 0, size);
@@ -980,7 +1037,7 @@ save_loop_entries_done:
#endif
free(real_filename);
- return SAVE_ERR_NONE;
+ return result;
}
int
@@ -1171,6 +1228,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
(*col)++;
}
}
+ *ptoken = 0;
if (*pstate == PS_NONE)
{
struct PoEntry* newchunk = NULL;
@@ -1195,8 +1253,6 @@ parse_po_line(const char* line, struct DrawState* dstate,
}
if (*token)
{
- *ptoken = 0;
-
if (*pstate & PS_MSGID)
set_msgid(*current_entry, token, 1);
else if (*pstate & PS_MSGID_PLURAL)
@@ -1204,8 +1260,9 @@ parse_po_line(const char* line, struct DrawState* dstate,
set_msgid_plural(*current_entry, token, 1);
if (*current_entry != dstate->entries)
for (int i = 0; i < dstate->nplurals; i++)
- set_msgstr(*current_entry, NULL, i, 0,
- dstate);
+ if (!set_msgstr(*current_entry, NULL, i,
+ 0, dstate))
+ return PARSE_ERR_ALLOC;
}
else if (*pstate & PS_MSGSTR)
{
@@ -1221,11 +1278,15 @@ parse_po_line(const char* line, struct DrawState* dstate,
}
}
- set_msgstr(*current_entry, token, 0, 1, dstate);
+ if (!set_msgstr(*current_entry, token, 0, 1, dstate))
+ return PARSE_ERR_ALLOC;
}
else if (*pstate & PS_MSGSTR_ARRAY)
- set_msgstr(*current_entry, token, *msgstr_index, 1,
- dstate);
+ {
+ if (!set_msgstr(*current_entry, token, *msgstr_index, 1,
+ dstate))
+ return PARSE_ERR_ALLOC;
+ }
else if (*pstate & PS_COMMENT_TRAN)
{
uint32_t* u32_token = NULL;
@@ -1277,7 +1338,7 @@ parse_po_line(const char* line, struct DrawState* dstate,
dstate->fuzzy_count++;
ptoken += strlen(flag_strings[FL_FUZZY]);
}
- else if (starts_with(ptoken, ", "))
+ else if (*ptoken == ',' && *(ptoken + 1) == ' ')
ptoken += 2;
else
{
@@ -1302,8 +1363,8 @@ parse_po_line(const char* line, struct DrawState* dstate,
if (!u32_token)
return PARSE_ERR_ALLOC;
u8_string_to_unicode(u32_token, token, len);
- u32_add_comment(*current_entry, u32_token);
- (*current_entry)->obsolete = 1;
+ if (u32_add_comment(*current_entry, u32_token))
+ (*current_entry)->obsolete = 1;
free(u32_token);
}
*token = 0;
diff --git a/poe.c b/poe.c
@@ -2204,16 +2204,16 @@ main(int argc, char** argv)
print_error(EINVAL, "No filename given");
}
+ init_drawstate(&state, error, filename, prompt);
+
if (stat(filename, &st) == -1 || access(filename, R_OK | W_OK) == -1)
- {
- perror(PROGRAMNAME);
- return errno;
- }
+ goto file_error;
if (!S_ISREG(st.st_mode))
- return print_error(EINVAL, "Is not a regular file");
-
- init_drawstate(&state, error, filename, prompt);
+ {
+ result = print_error(EINVAL, "Is not a regular file");
+ goto general_error;
+ }
#ifdef __OpenBSD__
if (unveil(state.filename, "rwc") < 0)
@@ -2243,7 +2243,7 @@ main(int argc, char** argv)
state.rfn_len = readlink(state.filename,
state.real_filename, MAXPATH);
if (state.rfn_len == -1)
- return print_error(1, strerror(errno));
+ goto file_error;
state.real_filename[state.rfn_len] = 0;
#ifdef __OpenBSD__
if (unveil(state.real_filename, "rwc") < 0)
@@ -2253,11 +2253,14 @@ main(int argc, char** argv)
}
#endif
if (stat(state.real_filename, &st) == -1)
- return print_error(1, strerror(errno));
+ goto file_error;
}
if (!(state.backup_filename = calloc(MAXPATH, 1)))
+ {
+ free(state.real_filename);
return print_error(1,
"Allocation failed (out of memory?)");
+ }
/* Backup filename is the target file + suffix if the file to
* write is a symlink, otherwise file + suffix */
@@ -2273,7 +2276,7 @@ main(int argc, char** argv)
#endif
}
else
- return print_error(1, strerror(errno));
+ goto file_error;
#endif /* CREATE_BACKUPS */
if (state.rfn_len > 0)
@@ -2306,7 +2309,10 @@ main(int argc, char** argv)
}
if (!S_ISREG(st.st_mode))
- return print_error(EINVAL, "Is not a regular file");
+ {
+ result = print_error(EINVAL, "Is not a regular file");
+ goto general_error;
+ }
#ifdef __OpenBSD__
if (unveil(NULL, NULL) < 0)
@@ -2330,30 +2336,45 @@ main(int argc, char** argv)
{
case LOAD_ERR_CANT_ALLOC:
case LOAD_ERR_P_ALLOC:
- return print_error(result, "Allocation failed (out of memory?)");
+ (void)print_error(result, "Allocation failed (out of memory?)");
+ goto general_error;
case LOAD_ERR_CANT_OPEN_FILE:
- return print_error(result, "Cannot open file `%s'", filename);
+ (void)print_error(result, "Cannot open file `%s'", filename);
+ goto general_error;
case LOAD_ERR_NOT_PO_FILE:
- return print_error(result, "Not a .po file `%s'", filename);
+ (void)print_error(result, "Not a .po file `%s'", filename);
+ goto general_error;
case LOAD_ERR_P_INVAL:
- return print_error(result, "Invalid value");
+ (void)print_error(result, "Invalid value");
+ goto general_error;
case LOAD_ERR_P_SYNTAX:
- return print_error(result, "%s:%ld:%ld: Syntax error", filename,
+ (void)print_error(result, "%s:%ld:%ld: Syntax error", filename,
lineno, col);
+ goto general_error;
case LOAD_ERR_NONE:
if (*error)
- return print_error(1, error);
+ {
+ result = print_error(1, error);
+ goto general_error;
+ }
break;
default:
- return print_error(1, "Unknown error (%d)", result);
+ result = print_error(1, "Unknown error (%d)", result);
+ goto general_error;
}
state.msgid_number = state.msgid_count > 0 ? 1 : 0;
state.first_shown_msgid = state.msgid_number;
goto init_termbox;
file_error:
+ result = errno;
perror(PROGRAMNAME);
- return errno;
+ /* FALLTHROUGH */
+
+general_error:
+ free(state.real_filename);
+ free(state.backup_filename);
+ return result;
init_termbox:
tb_init();