Skip to content

Commit

Permalink
Minor refactoring of file path manipulation function
Browse files Browse the repository at this point in the history
  • Loading branch information
bfabiszewski committed Feb 26, 2022
1 parent 93c70a1 commit e3578bd
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 39 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
2022-02-26: Minor refactoring of file path manipulation function
2022-02-26: Fix memory handling issues
2022-02-26: Add coverity scan workflow
2022-02-25: Remove obsolete changelog
Expand Down
2 changes: 1 addition & 1 deletion src/opf.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ MOBI_RET mobi_build_opf_guide(OPF *opf, const MOBIRawml *rawml) {
}
debug_print("<reference type=\"%s\" title=\"%s\" href=\"part%05u.html\" />", ref_type, ref_title, file_number);
char href[FILENAME_MAX + 1];
snprintf(href, FILENAME_MAX, "part%05u.html", file_number);
snprintf(href, sizeof(href), "part%05u.html", file_number);
char *ref_href = strdup(href);
reference[j] = calloc(1, sizeof(OPFreference));
*reference[j] = (OPFreference) { ref_type, ref_title, ref_href };
Expand Down
41 changes: 26 additions & 15 deletions tools/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ char outdir[FILENAME_MAX];

#define UNUSED(x) (void)(x)

#ifndef min
# define min(a, b) ((a) < (b) ? (a) : (b))
#endif

/**
@brief Messages for libmobi return codes
For reference see enum MOBI_RET in mobi.h
Expand Down Expand Up @@ -72,29 +76,35 @@ const char * libmobi_msg(const MOBI_RET ret) {
/**
@brief Parse file name into file path and base name.
Dirname or basename can be skipped by setting to null.
All buffers must have FILENAME_MAX size.
@param[in] fullpath Full file path
@param[in,out] dirname Will be set to full dirname
@param[in,out] basename Will be set to file basename
@param[in] buf_len Size of each ouput buffer: dirname and basename
*/
void split_fullpath(const char *fullpath, char *dirname, char *basename) {
void split_fullpath(const char *fullpath, char *dirname, char *basename, const size_t buf_len) {
if (buf_len == 0) {
return;
}
char *p = strrchr(fullpath, separator);
if (p) {
p += 1;
if (dirname) {
strncpy(dirname, fullpath, (unsigned long)(p - fullpath));
dirname[p - fullpath] = '\0';
size_t dirlen = min(buf_len - 1, (size_t) (p - fullpath));
strncpy(dirname, fullpath, dirlen);
dirname[dirlen] = '\0';
}
if (basename) {
strcpy(basename, p);
strncpy(basename, p, buf_len - 1);
basename[buf_len - 1] = '\0';
}
}
else {
if (dirname) {
dirname[0] = '\0';
}
if (basename) {
strcpy(basename, fullpath);
strncpy(basename, fullpath, buf_len - 1);
basename[buf_len - 1] = '\0';
}
}
if (basename) {
Expand All @@ -106,8 +116,8 @@ void split_fullpath(const char *fullpath, char *dirname, char *basename) {
}

/**
* @brief Make directory
* @param[in] path Path
@brief Make directory
@param[in] path Path
@return SUCCESS or ERROR
*/
int make_directory(const char *path) {
Expand All @@ -122,18 +132,19 @@ int make_directory(const char *path) {

/**
@brief Create subfolder in directory
@param[in,out] newdir Path to created subfolder, must have FILENAME_MAX size
@param[in,out] newdir Path to created subfolder
@param[in] buf_len Buffer size fo created subfolder
@param[in] parent_dir Directory path
@param[in] subdir_name Subfolder name
@return SUCCESS or ERROR
*/
int create_subdir(char *newdir, const char *parent_dir, const char *subdir_name) {
int n = snprintf(newdir, FILENAME_MAX, "%s%c%s", parent_dir, separator, subdir_name);
int create_subdir(char *newdir, const size_t buf_len, const char *parent_dir, const char *subdir_name) {
int n = snprintf(newdir, buf_len, "%s%c%s", parent_dir, separator, subdir_name);
if (n < 0) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > FILENAME_MAX) {
if ((size_t) n >= buf_len) {
printf("File name too long: %s\n", newdir);
return ERROR;
}
Expand Down Expand Up @@ -181,7 +192,7 @@ int write_to_dir(const char *dir, const char *name, const unsigned char *buffer,
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > sizeof(path)) {
if ((size_t) n >= sizeof(path)) {
printf("File name too long\n");
return ERROR;
}
Expand Down Expand Up @@ -574,7 +585,7 @@ int save_mobi(MOBIData *m, const char *fullpath, const char *suffix) {
char outfile[FILENAME_MAX];
char basename[FILENAME_MAX];
char dirname[FILENAME_MAX];
split_fullpath(fullpath, dirname, basename);
split_fullpath(fullpath, dirname, basename, FILENAME_MAX);
const char *ext = (mobi_get_fileversion(m) >= 8) ? "azw3" : "mobi";
int n;
if (outdir_opt) {
Expand All @@ -586,7 +597,7 @@ int save_mobi(MOBIData *m, const char *fullpath, const char *suffix) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > sizeof(outfile)) {
if ((size_t) n >= sizeof(outfile)) {
printf("File name too long\n");
return ERROR;
}
Expand Down
4 changes: 2 additions & 2 deletions tools/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ extern bool outdir_opt;
extern char outdir[FILENAME_MAX];

const char * libmobi_msg(const MOBI_RET ret);
void split_fullpath(const char *fullpath, char *dirname, char *basename);
void split_fullpath(const char *fullpath, char *dirname, char *basename, const size_t buf_len);
int make_directory(const char *path);
int create_subdir(char *newdir, const char *parent_dir, const char *subdir_name);
int create_subdir(char *newdir, const size_t buf_len, const char *parent_dir, const char *subdir_name);
int write_file(const unsigned char *buffer, const size_t len, const char *path);
int write_to_dir(const char *dir, const char *name, const unsigned char *buffer, const size_t len);
bool dir_exists(const char *path);
Expand Down
44 changes: 23 additions & 21 deletions tools/mobitool.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,27 @@ static void print_records_meta(const MOBIData *m) {
/**
@brief Create new path. Name is derived from input file path.
[dirname]/[basename][suffix]
@param[out] newpath Created path, buffer must have FILENAME_MAX size
@param[out] newpath Created path
@param[in] buf_len Created path buffer size
@param[in] fullpath Input file path
@param[in] suffix Path name suffix
@return SUCCESS or ERROR
*/
static int create_path(char *newpath, const char *fullpath, const char *suffix) {
static int create_path(char *newpath, const size_t buf_len, const char *fullpath, const char *suffix) {
char dirname[FILENAME_MAX];
char basename[FILENAME_MAX];
split_fullpath(fullpath, dirname, basename);
split_fullpath(fullpath, dirname, basename, FILENAME_MAX);
int n;
if (outdir_opt) {
n = snprintf(newpath, FILENAME_MAX, "%s%s%s", outdir, basename, suffix);
n = snprintf(newpath, buf_len, "%s%s%s", outdir, basename, suffix);
} else {
n = snprintf(newpath, FILENAME_MAX, "%s%s%s", dirname, basename, suffix);
n = snprintf(newpath, buf_len, "%s%s%s", dirname, basename, suffix);
}
if (n < 0) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > FILENAME_MAX) {
if ((size_t) n >= buf_len) {
printf("File name too long\n");
return ERROR;
}
Expand All @@ -268,13 +269,14 @@ static int create_path(char *newpath, const char *fullpath, const char *suffix)
/**
@brief Create directory. Path is derived from input file path.
[dirname]/[basename][suffix]
@param[out] newdir Created directory path, buffer must have FILENAME_MAX size
@param[out] newdir Created directory path
@param[in] buf_len Created directory buffer size
@param[in] fullpath Input file path
@param[in] suffix Directory name suffix
@return SUCCESS or ERROR
*/
static int create_dir(char *newdir, const char *fullpath, const char *suffix) {
if (create_path(newdir, fullpath, suffix) == ERROR) {
static int create_dir(char *newdir, const size_t buf_len, const char *fullpath, const char *suffix) {
if (create_path(newdir, buf_len, fullpath, suffix) == ERROR) {
return ERROR;
}
return make_directory(newdir);
Expand All @@ -288,7 +290,7 @@ static int create_dir(char *newdir, const char *fullpath, const char *suffix) {
*/
static int dump_records(const MOBIData *m, const char *fullpath) {
char newdir[FILENAME_MAX];
if (create_dir(newdir, fullpath, "_records") == ERROR) {
if (create_dir(newdir, sizeof(newdir), fullpath, "_records") == ERROR) {
return ERROR;
}
printf("Saving records to %s\n", newdir);
Expand All @@ -315,7 +317,7 @@ static int dump_records(const MOBIData *m, const char *fullpath) {
*/
static int dump_rawml(const MOBIData *m, const char *fullpath) {
char newpath[FILENAME_MAX];
if (create_path(newpath, fullpath, ".rawml") == ERROR) {
if (create_path(newpath, sizeof(newpath), fullpath, ".rawml") == ERROR) {
return ERROR;
}
printf("Saving rawml to %s\n", newpath);
Expand Down Expand Up @@ -380,7 +382,7 @@ static int dump_cover(const MOBIData *m, const char *fullpath) {
snprintf(suffix, sizeof(suffix), "_cover.%s", ext);

char cover_path[FILENAME_MAX];
if (create_path(cover_path, fullpath, suffix) == ERROR) {
if (create_path(cover_path, sizeof(cover_path), fullpath, suffix) == ERROR) {
return ERROR;
}

Expand All @@ -402,15 +404,15 @@ static int dump_rawml_parts(const MOBIRawml *rawml, const char *fullpath) {
}

char newdir[FILENAME_MAX];
if (create_dir(newdir, fullpath, "_markup") == ERROR) {
if (create_dir(newdir, sizeof(newdir), fullpath, "_markup") == ERROR) {
return ERROR;
}
printf("Saving markup to %s\n", newdir);

if (create_epub_opt) {
/* create META_INF directory */
char opfdir[FILENAME_MAX];
if (create_subdir(opfdir, newdir, "META-INF") == ERROR) {
if (create_subdir(opfdir, sizeof(opfdir), newdir, "META-INF") == ERROR) {
return ERROR;
}

Expand All @@ -425,7 +427,7 @@ static int dump_rawml_parts(const MOBIRawml *rawml, const char *fullpath) {
}

/* create OEBPS directory */
if (create_subdir(opfdir, newdir, "OEBPS") == ERROR) {
if (create_subdir(opfdir, sizeof(opfdir), newdir, "OEBPS") == ERROR) {
return ERROR;
}

Expand Down Expand Up @@ -478,7 +480,7 @@ static int dump_rawml_parts(const MOBIRawml *rawml, const char *fullpath) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > sizeof(partname)) {
if ((size_t) n >= sizeof(partname)) {
printf("File name too long: %s\n", partname);
return ERROR;
}
Expand Down Expand Up @@ -520,7 +522,7 @@ static int create_epub(const MOBIRawml *rawml, const char *fullpath) {
}

char zipfile[FILENAME_MAX];
if (create_path(zipfile, fullpath, ".epub") == ERROR) {
if (create_path(zipfile, sizeof(zipfile), fullpath, ".epub") == ERROR) {
return ERROR;
}
printf("Saving EPUB to %s\n", zipfile);
Expand Down Expand Up @@ -638,7 +640,7 @@ static int dump_embedded_source(const MOBIData *m, const char *fullpath) {
}

char newdir[FILENAME_MAX];
if (create_dir(newdir, fullpath, "_source") == ERROR) {
if (create_dir(newdir, sizeof(newdir), fullpath, "_source") == ERROR) {
return ERROR;
}

Expand All @@ -654,13 +656,13 @@ static int dump_embedded_source(const MOBIData *m, const char *fullpath) {

char srcsname[FILENAME_MAX];
char basename[FILENAME_MAX];
split_fullpath(fullpath, NULL, basename);
split_fullpath(fullpath, NULL, basename, FILENAME_MAX);
int n = snprintf(srcsname, sizeof(srcsname), "%s_source.%s", basename, ext);
if (n < 0) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > sizeof(srcsname)) {
if ((size_t) n >= sizeof(srcsname)) {
printf("File name too long\n");
return ERROR;
}
Expand All @@ -687,7 +689,7 @@ static int dump_embedded_source(const MOBIData *m, const char *fullpath) {
printf("Creating file name failed\n");
return ERROR;
}
if ((size_t) n > sizeof(srcsname)) {
if ((size_t) n >= sizeof(srcsname)) {
printf("File name too long\n");
return ERROR;
}
Expand Down

0 comments on commit e3578bd

Please sign in to comment.