mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
Windows: Fix filepath basename issue
On Windows, the cli_basename function should treat both '/' and '\' as path separators. Most Windows APIs also accept both. On Linux/Unix, it makes sense when using a filepath that is more for informational purposes or where it may have come from a Windows system, to treat the '\' as a path separator. But in situations where the the path is needed for some critical action, like moving or deleting a file, we can't treat it as a path separator.
This commit is contained in:
parent
0cc5d75093
commit
18854bf4bc
7 changed files with 42 additions and 21 deletions
|
@ -452,7 +452,7 @@ static int traverse_rename(const char *source, const char *destination)
|
|||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
ret = cli_basename(source, strlen(source), &source_basename);
|
||||
ret = cli_basename(source, strlen(source), &source_basename, false /* posix_support_backslash_pathsep */);
|
||||
if (CL_SUCCESS != ret) {
|
||||
logg(LOGG_INFO, "traverse_rename: Failed to get basename of source path:%s\n\tError: %d\n", source, (int)ret);
|
||||
goto done;
|
||||
|
@ -564,7 +564,7 @@ static int traverse_unlink(const char *target)
|
|||
goto done;
|
||||
}
|
||||
|
||||
ret = cli_basename(target, strlen(target), &target_basename);
|
||||
ret = cli_basename(target, strlen(target), &target_basename, false /* posix_support_backslash_pathsep */);
|
||||
if (CL_SUCCESS != ret) {
|
||||
logg(LOGG_INFO, "traverse_unlink: Failed to get basename of target path: %s\n\tError: %d\n", target, (int)ret);
|
||||
goto done;
|
||||
|
|
|
@ -995,7 +995,7 @@ cl_error_t fmap_dump_to_file(fmap_t *map, const char *filepath, const char *tmpd
|
|||
|
||||
/* Create a filename prefix that includes the original filename, if available */
|
||||
if (filepath != NULL) {
|
||||
if (CL_SUCCESS != cli_basename(filepath, strlen(filepath), &filebase)) {
|
||||
if (CL_SUCCESS != cli_basename(filepath, strlen(filepath), &filebase, true /* posix_support_backslash_pathsep */)) {
|
||||
cli_dbgmsg("fmap_dump_to_file: Unable to determine basename from filepath.\n");
|
||||
} else if ((start_offset != 0) && (end_offset != map->real_len)) {
|
||||
/* If we're only dumping a portion of the file, include the offsets in the prefix,...
|
||||
|
|
|
@ -389,7 +389,7 @@ static cl_error_t cli_scanrar_file(const char *filepath, int desc, cli_ctx *ctx)
|
|||
* Extract the file...
|
||||
*/
|
||||
if (0 != metadata.filename[0]) {
|
||||
(void)cli_basename(metadata.filename, strlen(metadata.filename), &filename_base);
|
||||
(void)cli_basename(metadata.filename, strlen(metadata.filename), &filename_base, true /* posix_support_backslash_pathsep */);
|
||||
}
|
||||
|
||||
if (!(ctx->engine->keeptmp) ||
|
||||
|
@ -837,7 +837,7 @@ static cl_error_t cli_scanegg(cli_ctx *ctx)
|
|||
* Drop to a temp file, if requested.
|
||||
*/
|
||||
if (NULL != metadata.filename) {
|
||||
(void)cli_basename(metadata.filename, strlen(metadata.filename), &filename_base);
|
||||
(void)cli_basename(metadata.filename, strlen(metadata.filename), &filename_base, true /* posix_support_backslash_pathsep */);
|
||||
}
|
||||
|
||||
if (ctx->engine->keeptmp) {
|
||||
|
@ -4716,7 +4716,7 @@ cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type)
|
|||
* Keep-temp enabled, so create a sub-directory to provide extraction directory recursion.
|
||||
*/
|
||||
if ((NULL != ctx->fmap->name) &&
|
||||
(CL_SUCCESS == cli_basename(ctx->fmap->name, strlen(ctx->fmap->name), &fmap_basename))) {
|
||||
(CL_SUCCESS == cli_basename(ctx->fmap->name, strlen(ctx->fmap->name), &fmap_basename, true /* posix_support_backslash_pathsep */))) {
|
||||
/*
|
||||
* The fmap has a name, lets include it in the new sub-directory.
|
||||
*/
|
||||
|
@ -5910,7 +5910,7 @@ static cl_error_t scan_common(cl_fmap_t *map, const char *filepath, const char *
|
|||
|
||||
if ((ctx.engine->keeptmp) &&
|
||||
(NULL != ctx.target_filepath) &&
|
||||
(CL_SUCCESS == cli_basename(ctx.target_filepath, strlen(ctx.target_filepath), &target_basename))) {
|
||||
(CL_SUCCESS == cli_basename(ctx.target_filepath, strlen(ctx.target_filepath), &target_basename, true /* posix_support_backslash_pathsep */))) {
|
||||
/* Include the basename in the temp directory */
|
||||
new_temp_prefix_len = strlen("YYYYMMDD_HHMMSS-") + strlen(target_basename);
|
||||
new_temp_prefix = cli_max_calloc(1, new_temp_prefix_len + 1);
|
||||
|
@ -6186,7 +6186,7 @@ cl_error_t cl_scandesc_callback(int desc, const char *filename, const char **vir
|
|||
}
|
||||
|
||||
if (NULL != filename) {
|
||||
(void)cli_basename(filename, strlen(filename), &filename_base);
|
||||
(void)cli_basename(filename, strlen(filename), &filename_base, true /* posix_support_backslash_pathsep */);
|
||||
}
|
||||
|
||||
if (NULL == (map = fmap(desc, 0, sb.st_size, filename_base))) {
|
||||
|
@ -6226,7 +6226,7 @@ cl_error_t cl_scanmap_callback(cl_fmap_t *map, const char *filename, const char
|
|||
|
||||
if (NULL != filename && map->name == NULL) {
|
||||
// Use the provided name for the fmap name if one wasn't already set.
|
||||
cli_basename(filename, strlen(filename), &map->name);
|
||||
cli_basename(filename, strlen(filename), &map->name, true /* posix_support_backslash_pathsep */);
|
||||
}
|
||||
|
||||
return scan_common(map, filename, virname, scanned, engine, scanoptions, context);
|
||||
|
|
|
@ -424,8 +424,7 @@ char *cli_strrcpy(char *dest, const char *source) /* by NJH */
|
|||
return NULL;
|
||||
}
|
||||
|
||||
while ((*dest++ = *source++))
|
||||
;
|
||||
while ((*dest++ = *source++));
|
||||
|
||||
return --dest;
|
||||
}
|
||||
|
@ -470,8 +469,7 @@ char *__cli_strndup(const char *s, size_t n)
|
|||
size_t __cli_strnlen(const char *s, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; (i < n) && s[i] != '\0'; ++i)
|
||||
;
|
||||
for (; (i < n) && s[i] != '\0'; ++i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -1058,8 +1056,11 @@ int cli_hexnibbles(char *str, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
cl_error_t cli_basename(const char *filepath, size_t filepath_len,
|
||||
char **filebase)
|
||||
cl_error_t cli_basename(
|
||||
const char *filepath,
|
||||
size_t filepath_len,
|
||||
char **filebase,
|
||||
bool posix_support_backslash_pathsep)
|
||||
{
|
||||
cl_error_t status = CL_EARG;
|
||||
const char *index = NULL;
|
||||
|
@ -1071,13 +1072,25 @@ cl_error_t cli_basename(const char *filepath, size_t filepath_len,
|
|||
|
||||
index = filepath + filepath_len - 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
while (index > filepath) {
|
||||
if (index[0] == PATHSEP[0])
|
||||
if ((index[0] == '/') || (index[0] == '\\'))
|
||||
break;
|
||||
index--;
|
||||
}
|
||||
if ((index != filepath) || (index[0] == PATHSEP[0]))
|
||||
if ((index != filepath) || (index[0] == '/') || (index[0] == '\\')) {
|
||||
index++;
|
||||
}
|
||||
#else
|
||||
while (index > filepath) {
|
||||
if ((index[0] == '/') || (index[0] == '\\' && posix_support_backslash_pathsep))
|
||||
break;
|
||||
index--;
|
||||
}
|
||||
if ((index != filepath) || (index[0] == '/') || (index[0] == '\\' && posix_support_backslash_pathsep)) {
|
||||
index++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (0 == CLI_STRNLEN(index, filepath_len - (index - filepath))) {
|
||||
cli_dbgmsg("cli_basename: Provided path does not include a file name.\n");
|
||||
|
|
|
@ -96,15 +96,23 @@ int cli_hexnibbles(char *str, int len);
|
|||
size_t cli_strlcat(char *dst, const char *src, size_t sz); /* libclamav/strlcat.c */
|
||||
|
||||
/**
|
||||
* @brief Get the file basename including extension from a file path.
|
||||
* @brief Get the file basename including extension from a file path.
|
||||
*
|
||||
* Will treat both '/' and '\' as path separators.
|
||||
*
|
||||
* Caller is responsible for freeing filebase.
|
||||
* An empty string will be returned if the caller inputs a directory with a trailing slash (no file).
|
||||
*
|
||||
* @param filepath The filepath in question.
|
||||
* @param[out] filebase An allocated string containing the file basename.
|
||||
* @param posix_support_backslash_pathsep Whether to treat backslashes as path separators on Linux/Unix systems.
|
||||
*
|
||||
* @return cl_error_t CL_SUCCESS, CL_EARG, CL_EFORMAT, or CL_EMEM
|
||||
*/
|
||||
cl_error_t cli_basename(const char *filepath, size_t filepath_len, char **filebase);
|
||||
cl_error_t cli_basename(
|
||||
const char *filepath,
|
||||
size_t filepath_len,
|
||||
char **filebase,
|
||||
bool posix_support_backslash_pathsep);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -658,7 +658,7 @@ static cl_error_t parse_local_file_header(
|
|||
src = fmap_need_ptr_once(map, zip, name_size);
|
||||
if (name_size && (NULL != src)) {
|
||||
memcpy(name, zip, name_size);
|
||||
if (CL_SUCCESS != cli_basename(name, name_size, &original_filename)) {
|
||||
if (CL_SUCCESS != cli_basename(name, name_size, &original_filename, true /* posix_support_backslash_pathsep */)) {
|
||||
original_filename = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2623,7 +2623,7 @@ fc_error_t updatedb(
|
|||
logg(LOGG_DEBUG, "updatedb: Moving signature file %s to database directory\n", signfile);
|
||||
|
||||
// get the basename of the signfile
|
||||
if (CL_SUCCESS != cli_basename(signfile, strlen(signfile), &newSignFilename)) {
|
||||
if (CL_SUCCESS != cli_basename(signfile, strlen(signfile), &newSignFilename, false /* posix_support_backslash_pathsep */)) {
|
||||
logg(LOGG_ERROR, "updatedb: Failed to get basename of '%s'\n", signfile);
|
||||
goto done;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue