Skip to content

Commit

Permalink
path: new funcs to merge paths
Browse files Browse the repository at this point in the history
Take windows directory separators into account.

Path is not checked or "resolved".

(cherry picked from commit 228caa6)
  • Loading branch information
victorjulien authored and jlucovsky committed Sep 6, 2023
1 parent 6a8865b commit 8a8aa1c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/util-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ const char * SCErrorToString(SCError err)
CASE_CODE(SC_ERR_HASH_ADD);
CASE_CODE(SC_ERR_SIGNAL);
CASE_CODE(SC_WARN_REFCNT);
CASE_CODE(SC_ERR_PATH_JOIN);
CASE_CODE(SC_ERR_PATH_RESOLVE);

CASE_CODE (SC_ERR_MAX);
}
Expand Down
2 changes: 2 additions & 0 deletions src/util-error.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ typedef enum {
SC_ERR_HASH_ADD,
SC_ERR_SIGNAL,
SC_WARN_REFCNT,
SC_ERR_PATH_JOIN,
SC_ERR_PATH_RESOLVE,

SC_ERR_MAX
} SCError;
Expand Down
80 changes: 65 additions & 15 deletions src/util-path.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2007-2012 Open Information Security Foundation
/* Copyright (C) 2007-2023 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
Expand Down Expand Up @@ -72,36 +72,86 @@ int PathIsRelative(const char *path)
return PathIsAbsolute(path) ? 0 : 1;
}

int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
{
char path[PATH_MAX];
if (dir == NULL || strlen(dir) == 0)
return -1;

size_t r = strlcpy(path, dir, sizeof(path));
if (r >= sizeof(path)) {
return -1;
}

#if defined OS_WIN32 || defined __CYGWIN__
if (path[strlen(path) - 1] != '\\')
r = strlcat(path, "\\\\", sizeof(path));
#else
if (path[strlen(path) - 1] != '/')
r = strlcat(path, "/", sizeof(path));
#endif
if (r >= sizeof(path)) {
return -1;
}
r = strlcat(path, fname, sizeof(path));
if (r >= sizeof(path)) {
return -1;
}
r = strlcpy(out_buf, path, buf_size);
if (r >= buf_size) {
return -1;
}

return 0;
}

char *PathMergeAlloc(const char *const dir, const char *const fname)
{
char path[PATH_MAX];
if (PathMerge(path, sizeof(path), dir, fname) != 0)
return NULL;

char *ret = SCStrdup(path);
if (ret == NULL)
return NULL;

return ret;
}

/**
* \brief Wrapper to join a directory and filename and resolve using realpath
* _fullpath is used for WIN32
*
* \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure.
* \param buf_len length of output buffer
* \param buf_size length of output buffer, must be PATH_MAX
* \param dir the directory
* \param fname the filename
*
* \retval TM_ECODE_OK on success
* \retval TM_ECODE_FAILED on failure
* \retval 0 on success
* \retval -1 on failure
*/
TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname)
int PathJoin(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
{
SCEnter();
uint16_t max_path_len = MAX(buf_len, PATH_MAX);
int bytes_written = snprintf(out_buf, max_path_len, "%s%c%s", dir, DIRECTORY_SEPARATOR, fname);
if (bytes_written <= 0) {
SCLogError(SC_ERR_SPRINTF, "Could not join filename to path");
SCReturnInt(TM_ECODE_FAILED);
if (buf_size != PATH_MAX) {
return -1;
}
if (PathMerge(out_buf, buf_size, dir, fname) != 0) {
SCLogError(SC_ERR_PATH_JOIN, "Could not join filename to path");
return -1;
}
char *tmp_buf = SCRealPath(out_buf, NULL);
if (tmp_buf == NULL) {
SCLogError(SC_ERR_SPRINTF, "Error resolving path: %s", strerror(errno));
SCReturnInt(TM_ECODE_FAILED);
SCLogError(SC_ERR_PATH_RESOLVE, "Error resolving path: %s", strerror(errno));
return -1;
}
memset(out_buf, 0, buf_len);
strlcpy(out_buf, tmp_buf, max_path_len);
memset(out_buf, 0, buf_size);
size_t ret = strlcpy(out_buf, tmp_buf, buf_size);
free(tmp_buf);
SCReturnInt(TM_ECODE_OK);
if (ret >= buf_size) {
return -1;
}
return 0;
}

/**
Expand Down
10 changes: 9 additions & 1 deletion src/util-path.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ typedef struct stat SCStat;
#define SCStatFn(pathname, statbuf) stat((pathname), (statbuf))
#endif

#if defined OS_WIN32 || defined __CYGWIN__
#define PATH_SEPARATOR_SIZE 2
#else
#define PATH_SEPARATOR_SIZE 1
#endif

#ifndef HAVE_NON_POSIX_MKDIR
#define SCMkDir(a, b) mkdir(a, b)
#else
Expand All @@ -43,7 +49,9 @@ typedef struct stat SCStat;

int PathIsAbsolute(const char *);
int PathIsRelative(const char *);
TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname);
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname);
char *PathMergeAlloc(const char *const dir, const char *const fname);
int PathJoin(char *out_buf, size_t buf_len, const char *const dir, const char *const fname);
int SCDefaultMkDir(const char *path);
int SCCreateDirectoryTree(const char *path, const bool final);
bool SCPathExists(const char *path);
Expand Down

0 comments on commit 8a8aa1c

Please sign in to comment.