... | ... |
@@ -116,6 +116,7 @@ CLAMAV_PRIVATE { |
116 | 116 |
cli_memstr; |
117 | 117 |
cli_strdup; |
118 | 118 |
cli_strndup; |
119 |
+ cli_strnstr; |
|
119 | 120 |
cli_realloc; |
120 | 121 |
cli_ctime; |
121 | 122 |
tableCreate; |
... | ... |
@@ -257,6 +258,7 @@ CLAMAV_PRIVATE { |
257 | 257 |
cl_get_pkey_file; |
258 | 258 |
cl_base64_decode; |
259 | 259 |
cl_base64_encode; |
260 |
+ cli_sanitize_filepath; |
|
260 | 261 |
local: |
261 | 262 |
*; |
262 | 263 |
}; |
... | ... |
@@ -755,19 +755,28 @@ int cli_writen(int fd, const void *buff, unsigned int count); |
755 | 755 |
const char *cli_gettmpdir(void); |
756 | 756 |
|
757 | 757 |
/** |
758 |
+ * @brief Sanitize a relative path, so it cannot have a negative depth. |
|
759 |
+ * |
|
760 |
+ * Caller is responsible for freeing the filename. |
|
761 |
+ * |
|
762 |
+ * @return char* filename or NULL. |
|
763 |
+ */ |
|
764 |
+char *cli_sanitize_filepath(const char *filepath, size_t filepath_len); |
|
765 |
+ |
|
766 |
+/** |
|
758 | 767 |
* @brief Generate tempfile filename (no path) with a random MD5 hash. |
759 |
- * |
|
768 |
+ * |
|
760 | 769 |
* Caller is responsible for freeing the filename. |
761 |
- * |
|
770 |
+ * |
|
762 | 771 |
* @return char* filename or NULL. |
763 | 772 |
*/ |
764 | 773 |
char *cli_genfname(const char *prefix); |
765 | 774 |
|
766 | 775 |
/** |
767 | 776 |
* @brief Generate a full tempfile filepath with a random MD5 hash and prefix the name, if provided. |
768 |
- * |
|
777 |
+ * |
|
769 | 778 |
* Caller is responsible for freeing the filename. |
770 |
- * |
|
779 |
+ * |
|
771 | 780 |
* @param dir Alternative temp directory. (optional) |
772 | 781 |
* @return char* filename or NULL. |
773 | 782 |
*/ |
... | ... |
@@ -775,9 +784,9 @@ char *cli_gentemp_with_prefix(const char *dir, const char *prefix); |
775 | 775 |
|
776 | 776 |
/** |
777 | 777 |
* @brief Generate a full tempfile filepath with a random MD5 hash. |
778 |
- * |
|
778 |
+ * |
|
779 | 779 |
* Caller is responsible for freeing the filename. |
780 |
- * |
|
780 |
+ * |
|
781 | 781 |
* @param dir Alternative temp directory. (optional) |
782 | 782 |
* @return char* filename or NULL. |
783 | 783 |
*/ |
... | ... |
@@ -789,18 +798,18 @@ char *cli_gentemp(const char *dir); |
789 | 789 |
* @param dir Alternative temp directory (optional). |
790 | 790 |
* @param[out] name Allocated filepath, must be freed by caller. |
791 | 791 |
* @param[out] fd File descriptor of open temp file. |
792 |
- * @return cl_error_t CL_SUCCESS, CL_ECREAT, or CL_EMEM. |
|
792 |
+ * @return cl_error_t CL_SUCCESS, CL_ECREAT, or CL_EMEM. |
|
793 | 793 |
*/ |
794 | 794 |
cl_error_t cli_gentempfd(const char *dir, char **name, int *fd); |
795 | 795 |
|
796 | 796 |
/** |
797 | 797 |
* @brief Create a temp filename, create the file, open it, and pass back the filepath and open file descriptor. |
798 |
- * |
|
798 |
+ * |
|
799 | 799 |
* @param dir Alternative temp directory (optional). |
800 | 800 |
* @param prefix (Optional) Prefix for new file tempfile. |
801 | 801 |
* @param[out] name Allocated filepath, must be freed by caller. |
802 | 802 |
* @param[out] fd File descriptor of open temp file. |
803 |
- * @return cl_error_t CL_SUCCESS, CL_ECREAT, or CL_EMEM. |
|
803 |
+ * @return cl_error_t CL_SUCCESS, CL_ECREAT, or CL_EMEM. |
|
804 | 804 |
*/ |
805 | 805 |
cl_error_t cli_gentempfd_with_prefix(const char *dir, char *prefix, char **name, int *fd); |
806 | 806 |
|
... | ... |
@@ -849,11 +858,11 @@ struct cli_ftw_cbdata { |
849 | 849 |
void *data; |
850 | 850 |
}; |
851 | 851 |
|
852 |
-/* |
|
852 |
+/* |
|
853 | 853 |
* return CL_BREAK to break out without an error, CL_SUCCESS to continue, |
854 | 854 |
* or any CL_E* to break out due to error. |
855 | 855 |
* The callback is responsible for freeing filename when it is done using it. |
856 |
- * Note that callback decides if directory traversal should continue |
|
856 |
+ * Note that callback decides if directory traversal should continue |
|
857 | 857 |
* after an error, we call the callback with reason == error, |
858 | 858 |
* and if it returns CL_BREAK we break. |
859 | 859 |
*/ |
... | ... |
@@ -866,7 +875,7 @@ typedef int (*cli_ftw_cb)(STATBUF *stat_buf, char *filename, const char *path, e |
866 | 866 |
typedef int (*cli_ftw_pathchk)(const char *path, struct cli_ftw_cbdata *data); |
867 | 867 |
|
868 | 868 |
/* |
869 |
- * returns |
|
869 |
+ * returns |
|
870 | 870 |
* CL_SUCCESS if it traversed all files and subdirs |
871 | 871 |
* CL_BREAK if traversal has stopped at some point |
872 | 872 |
* CL_E* if error encountered during traversal and we had to break out |
... | ... |
@@ -885,10 +894,10 @@ const char *cli_strerror(int errnum, char *buf, size_t len); |
885 | 885 |
|
886 | 886 |
/** |
887 | 887 |
* @brief Attempt to get a filename from an open file descriptor. |
888 |
- * |
|
888 |
+ * |
|
889 | 889 |
* Caller is responsible for free'ing the filename. |
890 | 890 |
* Should work on Linux, macOS, Windows. |
891 |
- * |
|
891 |
+ * |
|
892 | 892 |
* @param desc File descriptor |
893 | 893 |
* @param[out] filepath Will be set to file path if found, or NULL. |
894 | 894 |
* @return cl_error_t CL_SUCCESS if found, else an error code. |
... | ... |
@@ -55,6 +55,7 @@ |
55 | 55 |
|
56 | 56 |
#include "clamav.h" |
57 | 57 |
#include "others.h" |
58 |
+#include "platform.h" |
|
58 | 59 |
#include "regex/regex.h" |
59 | 60 |
#include "ltdl.h" |
60 | 61 |
#include "matcher-ac.h" |
... | ... |
@@ -852,16 +853,132 @@ unsigned int cli_rndnum(unsigned int max) |
852 | 852 |
return 1 + (unsigned int)(max * (rand() / (1.0 + RAND_MAX))); |
853 | 853 |
} |
854 | 854 |
|
855 |
+char *cli_sanitize_filepath(const char *filepath, size_t filepath_len) |
|
856 |
+{ |
|
857 |
+ uint32_t depth = 0; |
|
858 |
+ size_t index = 0; |
|
859 |
+ size_t sanitized_index = 0; |
|
860 |
+ char *sanitized_filepath = NULL; |
|
861 |
+ |
|
862 |
+ if ((NULL == filepath) || (0 == filepath_len) || (MAX_PATH < filepath_len)) { |
|
863 |
+ goto done; |
|
864 |
+ } |
|
865 |
+ |
|
866 |
+ sanitized_filepath = cli_calloc(filepath_len + 1, sizeof(unsigned char)); |
|
867 |
+ if (NULL == sanitized_filepath) { |
|
868 |
+ cli_dbgmsg("cli_sanitize_filepath: out of memory\n"); |
|
869 |
+ goto done; |
|
870 |
+ } |
|
871 |
+ |
|
872 |
+ while (index < filepath_len) { |
|
873 |
+ char *next_pathsep = NULL; |
|
874 |
+ |
|
875 |
+ if (0 == strncmp(filepath + index, PATHSEP, strlen(PATHSEP))) { |
|
876 |
+ /* |
|
877 |
+ * Is "/" (or "\\" on Windows) |
|
878 |
+ */ |
|
879 |
+ /* Skip leading pathsep in absolute path, or extra pathsep) */ |
|
880 |
+ index += strlen(PATHSEP); |
|
881 |
+ continue; |
|
882 |
+ } else if (0 == strncmp(filepath + index, "." PATHSEP, strlen("." PATHSEP))) { |
|
883 |
+ /* |
|
884 |
+ * Is "./" (or ".\\" on Windows) |
|
885 |
+ */ |
|
886 |
+ /* Current directory indicator is meaningless and should not add to the depth. Skip it. */ |
|
887 |
+ index += strlen("." PATHSEP); |
|
888 |
+ continue; |
|
889 |
+ } else if (0 == strncmp(filepath + index, ".." PATHSEP, strlen(".." PATHSEP))) { |
|
890 |
+ /* |
|
891 |
+ * Is "../" (or "..\\" on Windows) |
|
892 |
+ */ |
|
893 |
+ if (depth == 0) { |
|
894 |
+ /* Relative path would traverse parent directory. Skip it. */ |
|
895 |
+ index += strlen(".." PATHSEP); |
|
896 |
+ continue; |
|
897 |
+ } else { |
|
898 |
+ /* Relative path is safe. Allow it. */ |
|
899 |
+ strncpy(sanitized_filepath + sanitized_index, filepath + index, strlen(".." PATHSEP)); |
|
900 |
+ sanitized_index += strlen(".." PATHSEP); |
|
901 |
+ index += strlen(".." PATHSEP); |
|
902 |
+ depth--; |
|
903 |
+ } |
|
904 |
+#ifdef _WIN32 |
|
905 |
+ /* |
|
906 |
+ * Windows' POSIX style API's accept both "/" and "\\" style path separators. |
|
907 |
+ * The following checks using POSIX style path separators on Windows. |
|
908 |
+ */ |
|
909 |
+ } else if (0 == strncmp(filepath + index, "/", strlen("/"))) { |
|
910 |
+ /* |
|
911 |
+ * Is "/". |
|
912 |
+ */ |
|
913 |
+ /* Skip leading pathsep in absolute path, or extra pathsep) */ |
|
914 |
+ index += strlen("/"); |
|
915 |
+ continue; |
|
916 |
+ } else if (0 == strncmp(filepath + index, "./", strlen("./"))) { |
|
917 |
+ /* |
|
918 |
+ * Is "./" |
|
919 |
+ */ |
|
920 |
+ /* Current directory indicator is meaningless and should not add to the depth. Skip it. */ |
|
921 |
+ index += strlen("./"); |
|
922 |
+ continue; |
|
923 |
+ } else if (0 == strncmp(filepath + index, "../", strlen("../"))) { |
|
924 |
+ /* |
|
925 |
+ * Is "../" |
|
926 |
+ */ |
|
927 |
+ if (depth == 0) { |
|
928 |
+ /* Relative path would traverse parent directory. Skip it. */ |
|
929 |
+ index += strlen("../"); |
|
930 |
+ continue; |
|
931 |
+ } else { |
|
932 |
+ /* Relative path is safe. Allow it. */ |
|
933 |
+ strncpy(sanitized_filepath + sanitized_index, filepath + index, strlen("../")); |
|
934 |
+ sanitized_index += strlen("../"); |
|
935 |
+ index += strlen("../"); |
|
936 |
+ depth--; |
|
937 |
+ } |
|
938 |
+#endif |
|
939 |
+ } else { |
|
940 |
+ /* |
|
941 |
+ * Is not "/", "./", or "../". |
|
942 |
+ */ |
|
943 |
+ /* Find the next path separator. */ |
|
944 |
+ next_pathsep = cli_strnstr(filepath + index, PATHSEP, filepath_len - index); |
|
945 |
+ if (NULL == next_pathsep) { |
|
946 |
+ /* No more path separators, copy the rest (filename) into the sanitized path */ |
|
947 |
+ strncpy(sanitized_filepath + sanitized_index, filepath + index, filepath_len - index); |
|
948 |
+ break; |
|
949 |
+ } |
|
950 |
+ next_pathsep += strlen(PATHSEP); /* Include the path separator in the copy */ |
|
951 |
+ |
|
952 |
+ /* Copy next directory name into the sanitized path */ |
|
953 |
+ strncpy(sanitized_filepath + sanitized_index, filepath + index, next_pathsep - (filepath + index)); |
|
954 |
+ sanitized_index += next_pathsep - (filepath + index); |
|
955 |
+ index += next_pathsep - (filepath + index); |
|
956 |
+ depth++; |
|
957 |
+ } |
|
958 |
+ } |
|
959 |
+ |
|
960 |
+done: |
|
961 |
+ if ((NULL != sanitized_filepath) && (0 == strlen(sanitized_filepath))) { |
|
962 |
+ free(sanitized_filepath); |
|
963 |
+ sanitized_filepath = NULL; |
|
964 |
+ } |
|
965 |
+ |
|
966 |
+ return sanitized_filepath; |
|
967 |
+} |
|
968 |
+ |
|
855 | 969 |
char *cli_genfname(const char *prefix) |
856 | 970 |
{ |
857 |
- char *fname; |
|
971 |
+ char *sanitized_prefix = NULL; |
|
972 |
+ char *fname = NULL; |
|
858 | 973 |
unsigned char salt[16 + 32]; |
859 | 974 |
char *tmp; |
860 | 975 |
int i; |
861 | 976 |
size_t len; |
862 | 977 |
|
863 | 978 |
if (prefix && (strlen(prefix) > 0)) { |
864 |
- len = strlen(prefix) + 1 + 5 + 1; /* {prefix}.{5}\0 */ |
|
979 |
+ sanitized_prefix = cli_sanitize_filepath(prefix, strlen(prefix)); |
|
980 |
+ len = strlen(sanitized_prefix) + 1 + 5 + 1; /* {prefix}.{5}\0 */ |
|
865 | 981 |
} else { |
866 | 982 |
len = 6 + 1 + 48 + 4 + 1; /* clamav-{48}.tmp\0 */ |
867 | 983 |
} |
... | ... |
@@ -893,9 +1010,10 @@ char *cli_genfname(const char *prefix) |
893 | 893 |
return NULL; |
894 | 894 |
} |
895 | 895 |
|
896 |
- if (prefix && (strlen(prefix) > 0)) { |
|
896 |
+ if (sanitized_prefix && (strlen(sanitized_prefix) > 0)) { |
|
897 | 897 |
fname[5] = '\0'; |
898 |
- snprintf(fname, len, "%s.%s", prefix, tmp); |
|
898 |
+ snprintf(fname, len, "%s.%s", sanitized_prefix, tmp); |
|
899 |
+ free(sanitized_prefix); |
|
899 | 900 |
} else { |
900 | 901 |
snprintf(fname, len, "clamav-%s.tmp", tmp); |
901 | 902 |
} |
... | ... |
@@ -431,7 +431,7 @@ static cl_error_t cli_scanrar(const char *filepath, int desc, cli_ctx *ctx) |
431 | 431 |
/* |
432 | 432 |
* Extract the file... |
433 | 433 |
*/ |
434 |
- extract_fullpath = cli_gentemp_with_prefix(extract_dir, metadata.filename); |
|
434 |
+ extract_fullpath = cli_gentemp(extract_dir); |
|
435 | 435 |
if (NULL == extract_fullpath) { |
436 | 436 |
cli_dbgmsg("RAR: Memory error allocating filename for extracted file."); |
437 | 437 |
status = CL_EMEM; |
... | ... |
@@ -502,6 +502,48 @@ char *cli_strndup(const char *s, size_t n) |
502 | 502 |
} |
503 | 503 |
#endif |
504 | 504 |
|
505 |
+#if !defined(HAVE_STRNSTR) || defined(HAVE_STRNI) |
|
506 |
+/* |
|
507 |
+ * @brief Find the first occurrence of find in s. |
|
508 |
+ * |
|
509 |
+ * The search is limited to the first slen characters of s. |
|
510 |
+ * |
|
511 |
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> |
|
512 |
+ * Copyright (c) 1990, 1993 |
|
513 |
+ * The Regents of the University of California. All rights reserved. |
|
514 |
+ * |
|
515 |
+ * This code is derived from software contributed to Berkeley by |
|
516 |
+ * Chris Torek. |
|
517 |
+ * |
|
518 |
+ * Copyright (c) 1990 The Regents of the University of California. |
|
519 |
+ * All rights reserved. |
|
520 |
+ * |
|
521 |
+ * @param s haystack |
|
522 |
+ * @param find needle |
|
523 |
+ * @param slen haystack length |
|
524 |
+ * @return char* Address of the needle, if found, else NULL. |
|
525 |
+ */ |
|
526 |
+char *cli_strnstr(const char *s, const char *find, size_t slen) |
|
527 |
+{ |
|
528 |
+ char c, sc; |
|
529 |
+ size_t len; |
|
530 |
+ |
|
531 |
+ if ((c = *find++) != '\0') { |
|
532 |
+ len = strlen(find); |
|
533 |
+ do { |
|
534 |
+ do { |
|
535 |
+ if (slen-- < 1 || (sc = *s++) == '\0') |
|
536 |
+ return (NULL); |
|
537 |
+ } while (sc != c); |
|
538 |
+ if (len > slen) |
|
539 |
+ return (NULL); |
|
540 |
+ } while (strncmp(s, find, len) != 0); |
|
541 |
+ s--; |
|
542 |
+ } |
|
543 |
+ return ((char *)s); |
|
544 |
+} |
|
545 |
+#endif |
|
546 |
+ |
|
505 | 547 |
size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, |
506 | 548 |
const char **tokens) |
507 | 549 |
{ |
... | ... |
@@ -3,7 +3,7 @@ |
3 | 3 |
* Copyright (C) 2007-2013 Sourcefire, Inc. |
4 | 4 |
* |
5 | 5 |
* Authors: Tomasz Kojm, Nigel Horne, Török Edvin |
6 |
- * |
|
6 |
+ * |
|
7 | 7 |
* Acknowledgements: cli_strcasestr() contains a public domain code from: |
8 | 8 |
* http://unixpapa.com/incnote/string.html |
9 | 9 |
* |
... | ... |
@@ -52,6 +52,12 @@ char *cli_strndup(const char *s, size_t n); |
52 | 52 |
size_t cli_strnlen(const char *s, size_t n); |
53 | 53 |
#endif |
54 | 54 |
|
55 |
+#if defined(HAVE_STRNSTR) && !defined(HAVE_STRNI) |
|
56 |
+#define cli_strnstr strnstr |
|
57 |
+#else |
|
58 |
+char *cli_strnstr(const char *s, const char *find, size_t slen); |
|
59 |
+#endif |
|
60 |
+ |
|
55 | 61 |
#include <stdio.h> |
56 | 62 |
#define cli_nocase(val) tolower(val) |
57 | 63 |
#define cli_nocasei(val) toupper(val) |
... | ... |
@@ -95,10 +101,10 @@ size_t cli_strlcat(char *dst, const char *src, size_t sz); /* libclamav/strlcat. |
95 | 95 |
|
96 | 96 |
/** |
97 | 97 |
* @brief Get the file basename including extension from a file path. |
98 |
- * |
|
98 |
+ * |
|
99 | 99 |
* Caller is responsible for freeing filebase. |
100 | 100 |
* An empty string will be returned if the caller inputs a directory with a trailing slash (no file). |
101 |
- * |
|
101 |
+ * |
|
102 | 102 |
* @param filepath The filepath in question. |
103 | 103 |
* @param[out] filebase An allocated string containing the file basename. |
104 | 104 |
* @return cl_error_t CL_SUCCESS, CL_EARG, CL_EFORMAT, or CL_EMEM |
... | ... |
@@ -5,6 +5,7 @@ AC_SEARCH_LIBS([gethostent],[nsl], [(LIBS="$LIBS -lnsl"; CLAMAV_MILTER_LIBS="$CL |
5 | 5 |
AC_CHECK_FUNCS_ONCE([poll setsid memcpy snprintf vsnprintf strerror_r strlcpy strlcat strcasestr inet_ntop setgroups initgroups ctime_r mkstemp mallinfo madvise getnameinfo]) |
6 | 6 |
AC_CHECK_FUNCS([strndup]) |
7 | 7 |
AC_CHECK_FUNCS([strnlen]) |
8 |
+AC_CHECK_FUNCS([strnstr]) |
|
8 | 9 |
AC_FUNC_FSEEKO |
9 | 10 |
|
10 | 11 |
dnl Check if anon maps are available, check if we can determine the page size |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
#include "../libclamav/version.h" |
24 | 24 |
#include "../libclamav/dsig.h" |
25 | 25 |
#include "../libclamav/fpu.h" |
26 |
+#include "../platform.h" |
|
26 | 27 |
#include "checks.h" |
27 | 28 |
|
28 | 29 |
static int fpu_words = FPU_ENDIAN_INITME; |
... | ... |
@@ -882,11 +883,107 @@ START_TEST(test_sha256) |
882 | 882 |
} |
883 | 883 |
END_TEST |
884 | 884 |
|
885 |
+START_TEST(test_sanitize_path) |
|
886 |
+{ |
|
887 |
+ char *sanitized = NULL; |
|
888 |
+ const char *unsanitized = NULL; |
|
889 |
+ |
|
890 |
+ unsanitized = ""; |
|
891 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
892 |
+ fail_if(NULL != sanitized, "sanitize_path: Empty path test failed"); |
|
893 |
+ |
|
894 |
+ unsanitized = NULL; |
|
895 |
+ sanitized = cli_sanitize_filepath(unsanitized, 0); |
|
896 |
+ fail_if(NULL != sanitized, "sanitize_path: NULL path #1 test failed"); |
|
897 |
+ |
|
898 |
+ unsanitized = NULL; |
|
899 |
+ sanitized = cli_sanitize_filepath(unsanitized, 50); |
|
900 |
+ fail_if(NULL != sanitized, "sanitize_path: NULL path #2 test failed"); |
|
901 |
+ |
|
902 |
+ unsanitized = "badlen"; |
|
903 |
+ sanitized = cli_sanitize_filepath(unsanitized, 0); |
|
904 |
+ fail_if(NULL != sanitized, "sanitize_path: Zero/bad path length test failed"); |
|
905 |
+ |
|
906 |
+ unsanitized = ".." PATHSEP; |
|
907 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
908 |
+ fail_if(NULL != sanitized, "sanitize_path: sanitized path should have been NULL"); |
|
909 |
+ |
|
910 |
+ unsanitized = "." PATHSEP; |
|
911 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
912 |
+ fail_if(NULL != sanitized, "sanitize_path: sanitized path should have been NULL (2)"); |
|
913 |
+ |
|
914 |
+ unsanitized = PATHSEP; |
|
915 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
916 |
+ fail_if(NULL != sanitized, "sanitize_path: sanitized path should have been NULL (3)"); |
|
917 |
+ |
|
918 |
+ unsanitized = ".." PATHSEP "relative_bad_1"; |
|
919 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
920 |
+ fail_if(NULL == sanitized); |
|
921 |
+ fail_unless(!strcmp(sanitized, "relative_bad_1"), "sanitize_path: bad relative path test #1 failed"); |
|
922 |
+ free(sanitized); |
|
923 |
+ |
|
924 |
+ unsanitized = "relative" PATHSEP ".." PATHSEP "good"; |
|
925 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
926 |
+ fail_if(NULL == sanitized); |
|
927 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP ".." PATHSEP "good"), "sanitize_path: good relative path test failed"); |
|
928 |
+ free(sanitized); |
|
929 |
+ |
|
930 |
+ unsanitized = "relative" PATHSEP ".." PATHSEP ".." PATHSEP "bad_2"; |
|
931 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
932 |
+ fail_if(NULL == sanitized); |
|
933 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP ".." PATHSEP "bad_2"), "sanitize_path: bad relative path test failed"); |
|
934 |
+ free(sanitized); |
|
935 |
+ |
|
936 |
+ unsanitized = "relative" PATHSEP "." PATHSEP ".." PATHSEP ".." PATHSEP "bad_current"; |
|
937 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
938 |
+ fail_if(NULL == sanitized); |
|
939 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP ".." PATHSEP "bad_current"), "sanitize_path: bad relative current path test failed"); |
|
940 |
+ free(sanitized); |
|
941 |
+ |
|
942 |
+ unsanitized = "relative/../../bad_win_posix_path"; |
|
943 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
944 |
+ fail_if(NULL == sanitized); |
|
945 |
+ fail_unless(!strcmp(sanitized, "relative/../bad_win_posix_path"), "sanitize_path: bad relative win posix path test failed"); |
|
946 |
+ free(sanitized); |
|
947 |
+ |
|
948 |
+ unsanitized = "" PATHSEP "absolute" PATHSEP ".." PATHSEP ".." PATHSEP "bad"; |
|
949 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
950 |
+ fail_if(NULL == sanitized); |
|
951 |
+ fail_unless(!strcmp(sanitized, "absolute" PATHSEP ".." PATHSEP "bad"), "sanitize_path: bad absolute path test failed"); |
|
952 |
+ free(sanitized); |
|
953 |
+ |
|
954 |
+ unsanitized = "" PATHSEP "absolute" PATHSEP ".." PATHSEP "good"; |
|
955 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
956 |
+ fail_if(NULL == sanitized); |
|
957 |
+ fail_unless(!strcmp(sanitized, "absolute" PATHSEP ".." PATHSEP "good"), "sanitize_path: good absolute path test failed"); |
|
958 |
+ free(sanitized); |
|
959 |
+ |
|
960 |
+ unsanitized = "relative" PATHSEP "normal"; |
|
961 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
962 |
+ fail_if(NULL == sanitized); |
|
963 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP "normal"), "sanitize_path: relative normal path test failed"); |
|
964 |
+ free(sanitized); |
|
965 |
+ |
|
966 |
+ unsanitized = "relative" PATHSEP PATHSEP "doublesep"; |
|
967 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
968 |
+ fail_if(NULL == sanitized); |
|
969 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP "doublesep"), "sanitize_path: relative double sep path test failed"); |
|
970 |
+ free(sanitized); |
|
971 |
+ |
|
972 |
+ unsanitized = "relative" PATHSEP "shortname" PATHSEP "1"; |
|
973 |
+ sanitized = cli_sanitize_filepath(unsanitized, strlen(unsanitized)); |
|
974 |
+ fail_if(NULL == sanitized); |
|
975 |
+ fail_unless(!strcmp(sanitized, "relative" PATHSEP "shortname" PATHSEP "1"), "sanitize_path: relative short name path test failed"); |
|
976 |
+ free(sanitized); |
|
977 |
+} |
|
978 |
+END_TEST |
|
979 |
+ |
|
885 | 980 |
static Suite *test_cli_suite(void) |
886 | 981 |
{ |
887 |
- Suite *s = suite_create("cli"); |
|
888 |
- TCase *tc_cli_others = tcase_create("byteorder_macros"); |
|
889 |
- TCase *tc_cli_dsig = tcase_create("digital signatures"); |
|
982 |
+ Suite *s = suite_create("cli"); |
|
983 |
+ TCase *tc_cli_others = tcase_create("byteorder_macros"); |
|
984 |
+ TCase *tc_cli_dsig = tcase_create("digital signatures"); |
|
985 |
+ TCase *tc_cli_assorted = tcase_create("assorted functions"); |
|
890 | 986 |
|
891 | 987 |
suite_add_tcase(s, tc_cli_others); |
892 | 988 |
tcase_add_checked_fixture(tc_cli_others, data_setup, data_teardown); |
... | ... |
@@ -898,6 +995,9 @@ static Suite *test_cli_suite(void) |
898 | 898 |
tcase_add_loop_test(tc_cli_dsig, test_cli_dsig, 0, dsig_tests_cnt); |
899 | 899 |
tcase_add_test(tc_cli_dsig, test_sha256); |
900 | 900 |
|
901 |
+ suite_add_tcase(s, tc_cli_assorted); |
|
902 |
+ tcase_add_test(tc_cli_assorted, test_sanitize_path); |
|
903 |
+ |
|
901 | 904 |
return s; |
902 | 905 |
} |
903 | 906 |
#endif /* CHECK_HAVE_LOOPS */ |
... | ... |
@@ -361,6 +361,12 @@ |
361 | 361 |
/* Define to 1 if you have the `strlcpy' function. */ |
362 | 362 |
/* #undef HAVE_STRLCPY */ |
363 | 363 |
|
364 |
+/* Define to 1 if you have the `strndup' function. */ |
|
365 |
+/* #undef HAVE_STRNDUP */ |
|
366 |
+ |
|
367 |
+/* Define to 1 if you have the `strnstr' function. */ |
|
368 |
+/* #undef HAVE_STRNSTR */ |
|
369 |
+ |
|
364 | 370 |
/* Define to 1 if sysconf(_SC_PAGESIZE) is available */ |
365 | 371 |
/* #undef HAVE_SYSCONF_SC_PAGESIZE */ |
366 | 372 |
|
... | ... |
@@ -8,7 +8,7 @@ use File::Temp 'tempfile'; |
8 | 8 |
|
9 | 9 |
|
10 | 10 |
######################################################### |
11 |
-# HACK HERE HACK HERE HACK HERE HACK HERE HACK HERE # |
|
11 |
+# HACK HERE HACK HERE HACK HERE HACK HERE HACK HERE # |
|
12 | 12 |
######################################################### |
13 | 13 |
|
14 | 14 |
use constant DEBUG => 0; |
... | ... |
@@ -135,6 +135,8 @@ my %CONF = ( |
135 | 135 |
'HAVE_STRING_H' => '1', |
136 | 136 |
'HAVE_STRLCAT' => -1, |
137 | 137 |
'HAVE_STRLCPY' => -1, |
138 |
+ 'HAVE_STRNDUP' => -1, |
|
139 |
+ 'HAVE_STRNSTR' => -1, |
|
138 | 140 |
'HAVE_SYSCONF_SC_PAGESIZE' => -1, |
139 | 141 |
'HAVE_SYSTEM_TOMMATH' => -1, |
140 | 142 |
'HAVE_SYS_DL_H' => -1, |
... | ... |
@@ -257,7 +259,7 @@ my @PROJECTS = ( |
257 | 257 |
); |
258 | 258 |
|
259 | 259 |
########################################################### |
260 |
-# STOP HACKING HERE STOP HACKING HERE STOP HACKING HERE # |
|
260 |
+# STOP HACKING HERE STOP HACKING HERE STOP HACKING HERE # |
|
261 | 261 |
########################################################### |
262 | 262 |
|
263 | 263 |
|