]> 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>
Fri, 11 Aug 2023 05:02:06 +0000 (07:02 +0200)
Take windows directory separators into account.

Path is not checked or "resolved".

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

index 8182109c684e9d23026ceb37a005610c51d8a7e9..34c4cc75ca79f3434fcd01799e2afeaee219b276 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
@@ -71,36 +71,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) {
+    if (buf_size != PATH_MAX) {
+        return -1;
+    }
+    if (PathMerge(out_buf, buf_size, dir, fname) != 0) {
         SCLogError("Could not join filename to path");
-        SCReturnInt(TM_ECODE_FAILED);
+        return -1;
     }
     char *tmp_buf = SCRealPath(out_buf, NULL);
     if (tmp_buf == NULL) {
         SCLogError("Error resolving path: %s", strerror(errno));
-        SCReturnInt(TM_ECODE_FAILED);
+        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);