Skip to content

Fix Coverity issues for pkg_editor.c #247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 51 additions & 49 deletions lib/pkg_editor/src/pkg_editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,13 @@ static char *read_file_into_buffer(struct acl_pkg_file *pkg,

// get file size
fseek(f, 0, SEEK_END);
file_size = ftell(f);
const long ftell_return = ftell(f);
if (ftell_return < 0) {
fprintf(stderr, "Couldn't determine size of file %s\n", in_file);
fclose(f);
return NULL;
}
file_size = (size_t)ftell_return;
rewind(f);

// slurp the whole file into allocated buf
Expand Down Expand Up @@ -1307,9 +1313,6 @@ static acl_pack_kind add_file(const char *out_file, FILE *of, const char *file,

static acl_pack_kind add_directory(const char *out_file, FILE *of,
const char *dir_name, ZInfo *z_info) {
#ifdef FULL_NAME_LENGTH
#undef FULL_NAME_LENGTH
#endif
acl_pkg_pack_info info;
size_t name_length = strlen(dir_name) + 1;

Expand All @@ -1335,24 +1338,31 @@ static acl_pack_kind add_directory(const char *out_file, FILE *of,

// Now walk the directory processing each name.
{

#ifdef _WIN32
#define FULL_NAME_LENGTH (2 * MAX_PATH)
#else
#define FULL_NAME_LENGTH (2 * PATH_MAX)
#endif

char full_name[FULL_NAME_LENGTH];
if (FULL_NAME_LENGTH < name_length) {

// Full name must be large enough to store dir_name plus a trailing path
// separator
if (name_length + 1 > FULL_NAME_LENGTH) {
fprintf(stderr, "acl_pkg_pack: Failed to write to %s: %s\n", out_file,
"Directory name too long");
return PACK_END;
}
#ifdef _WIN32
HANDLE file_handle;
WIN32_FIND_DATA file_info;

// Partially initialize the full path name.
strncpy(full_name, dir_name, FULL_NAME_LENGTH);
strncpy(full_name, dir_name, FULL_NAME_LENGTH - 1);
strncpy(full_name + name_length - 1, "\\*.*",
FULL_NAME_LENGTH - name_length + 1);
if (full_name[FULL_NAME_LENGTH - 1] != '\0') {
full_name[FULL_NAME_LENGTH - 1] = '\0';
}
FULL_NAME_LENGTH - name_length);
full_name[FULL_NAME_LENGTH - 1] = '\0';

// Walk through all the files in the directory.
file_handle = FindFirstFile(full_name, &file_info);
Expand All @@ -1366,10 +1376,9 @@ static acl_pack_kind add_directory(const char *out_file, FILE *of,

// Finish the full file name
strncpy(full_name + name_length, file_info.cFileName,
FULL_NAME_LENGTH - name_length);
if (full_name[FULL_NAME_LENGTH - 1] != '\0') {
full_name[FULL_NAME_LENGTH - 1] = '\0';
}
FULL_NAME_LENGTH - name_length - 1);
full_name[FULL_NAME_LENGTH - 1] = '\0';

if (add_file_or_dir(out_file, of, full_name, z_info) == PACK_END) {
FindClose(file_handle);
return PACK_END;
Expand All @@ -1380,14 +1389,6 @@ static acl_pack_kind add_directory(const char *out_file, FILE *of,
// Linux
DIR *dir;
struct dirent *entry;
#define FULL_NAME_LENGTH (2 * PATH_MAX)
char full_name[FULL_NAME_LENGTH];
if (FULL_NAME_LENGTH < name_length) {
fprintf(stderr, "acl_pkg_pack: Failed to write to %s: %s\n", out_file,
"Directory name too long");
return PACK_END;
}

// Partially initialize the full path name.
strncpy(full_name, dir_name, FULL_NAME_LENGTH - 1);
full_name[FULL_NAME_LENGTH - 1] = '\0';
Expand All @@ -1408,10 +1409,9 @@ static acl_pack_kind add_directory(const char *out_file, FILE *of,
// Finish the full file name, truncate name if the file is too long to
// avoid buffer overflow
size_t buffer_space_left = FULL_NAME_LENGTH - name_length;
strncpy(full_name + name_length, entry->d_name, buffer_space_left);
if (full_name[FULL_NAME_LENGTH - 1] != '\0') {
full_name[FULL_NAME_LENGTH - 1] = '\0';
}
strncpy(full_name + name_length, entry->d_name, buffer_space_left - 1);
full_name[FULL_NAME_LENGTH - 1] = '\0';

if (add_file_or_dir(out_file, of, full_name, z_info) == PACK_END) {
closedir(dir);
return PACK_END;
Expand All @@ -1421,6 +1421,7 @@ static acl_pack_kind add_directory(const char *out_file, FILE *of,
}
closedir(dir);
#endif
#undef FULL_NAME_LENGTH
}
return PACK_DIR;
}
Expand Down Expand Up @@ -1513,6 +1514,17 @@ int acl_pkg_pack(const char *out_file, const char **input_files_dirs) {
return 1 /* success */;
}

static void create_dir(const char *dir_name) {
// Create output directory. We can ignore the error output since it will
// only delay the failure to the first attempt of creating a file in the
// (not) newly created directory.
#ifdef _WIN32
(void)CreateDirectory(dir_name, NULL);
#else
(void)mkdir(dir_name, 0755);
#endif
}

static int read_data(void *data, size_t size, ZInfo *z_info, FILE *in_fd) {
// We want to fill 'data' with 'size' bytes.
z_info->strm.next_out = data;
Expand Down Expand Up @@ -1555,12 +1567,6 @@ static int read_data(void *data, size_t size, ZInfo *z_info, FILE *in_fd) {
static int acl_pkg_unpack_buffer_or_file(const char *buffer, size_t buffer_size,
FILE *input, const char *out_dir,
const char *routine_name) {
#ifdef FULL_NAME_LEN
#undef FULL_NAME_LEN
#endif
#ifdef NAME_LEN
#undef NAME_LEN
#endif
#ifdef _WIN32
#define FULL_NAME_LEN (3 * MAX_PATH)
#define NAME_LEN (2 * MAX_PATH)
Expand Down Expand Up @@ -1598,12 +1604,7 @@ static int acl_pkg_unpack_buffer_or_file(const char *buffer, size_t buffer_size,
return 0;
}

// Create output directory (ignore any errors).
#ifdef _WIN32
CreateDirectory(full_name, NULL);
#else
mkdir(full_name, 0755);
#endif
create_dir(full_name);
full_name[out_dir_length] = '/';

// Process the file until we hit the PACK_END record (or finish the
Expand Down Expand Up @@ -1635,22 +1636,21 @@ static int acl_pkg_unpack_buffer_or_file(const char *buffer, size_t buffer_size,
return 0;
}

// Generate the full name, truncate or zero pad to avoid buffer overflow
if (FULL_NAME_LEN < out_dir_length) {
// Generate the full name, truncate or zero pad to avoid buffer overflow.
// FULL_NAME_LEN must be large enough to store out_dir and a trailing path
// separator and null terminator
if (out_dir_length + 2 > FULL_NAME_LEN) {
fprintf(stderr, "%s: Directory name too long\n", routine_name);
inflateEnd(&z_info.strm);
return 0;
}

strncpy(full_name + out_dir_length + 1, name,
FULL_NAME_LEN - out_dir_length - 1);
if (full_name[FULL_NAME_LEN - 1] != '\0') {
full_name[FULL_NAME_LEN - 1] = '\0';
}
FULL_NAME_LEN - out_dir_length - 2);
full_name[FULL_NAME_LEN - 1] = '\0';

if (info.kind == PACK_DIR) {
#ifdef _WIN32
CreateDirectory(full_name, NULL);
#else
mkdir(full_name, 0755);
#endif
create_dir(full_name);
} else {
// Read file contents
FILE *out_file = fopen(full_name, "wb");
Expand Down Expand Up @@ -1712,6 +1712,8 @@ static int acl_pkg_unpack_buffer_or_file(const char *buffer, size_t buffer_size,

inflateEnd(&z_info.strm);
return 1;
#undef FULL_NAME_LEN
#undef NAME_LEN
}

int acl_pkg_unpack_buffer(const char *buffer, size_t buffer_size,
Expand Down