]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
path: new funcs to merge paths
authorVictor Julien <vjulien@oisf.net>
Thu, 10 Aug 2023 08:07:22 +0000 (10:07 +0200)
committerVictor Julien <vjulien@oisf.net>
Thu, 7 Sep 2023 19:15:38 +0000 (21:15 +0200)
Take windows directory separators into account.

Path is not checked or "resolved".

(cherry picked from commit 228caa640b3f961fd13ca8744cbbee789116bd30)

src/util-error.c
src/util-error.h
src/util-path.c
src/util-path.h

index 975e12ae9eef0560b4b406c344eee00c089416e3..d516aca57d89af9d9bbd82a206e826366cf091ea 100644 (file)
@@ -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);
     }
index 398aee9eebe46a41c61957522fdb83f242298505..841cc128a9358a3f20de6e3c8d041a60768d95f3 100644 (file)
@@ -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;
index 22d5e94e0b22e68f1ef1b8724115e3e9468fe7c5..7063aba595b5902a9da25b5c4052d4e0b5e7c8b2 100644 (file)
@@ -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
@@ -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;
 }
 
 /**
index b8a5dd25939dc188e8c4563e86a7b14b4cc1703b..141b6fc2472e77c768fa490d0f016bcdedfd066d 100644 (file)
@@ -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
@@ -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);