Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Molkentin <daniel@molkentin.de>2014-10-24 23:39:21 +0400
committerDaniel Molkentin <daniel@molkentin.de>2014-10-24 23:39:21 +0400
commitd0b40bab4773d29e762be70e1ab2e0da6ee4e69a (patch)
tree5f43d98b8be7e53cd401319ed31ed89c6c2c7c1b
parent0e828d802e1e37d01bd6c1d53a20181f493b540c (diff)
parentd76192cce12658d08122204df75c3c29b59895a5 (diff)
Merge pull request #2391 from owncloud/ignore_windows_reserved_charactersv1.7.0-rc1
Ignore reserved words on Windows
-rw-r--r--csync/src/csync_exclude.c41
-rw-r--r--csync/src/csync_exclude.h8
-rw-r--r--csync/src/std/c_string.c8
-rw-r--r--csync/src/std/c_string.h11
-rw-r--r--csync/tests/csync_tests/check_csync_exclude.c20
5 files changed, 88 insertions, 0 deletions
diff --git a/csync/src/csync_exclude.c b/csync/src/csync_exclude.c
index 0855b9829..f4500b9b1 100644
--- a/csync/src/csync_exclude.c
+++ b/csync/src/csync_exclude.c
@@ -156,6 +156,40 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
return match;
}
+// See http://support.microsoft.com/kb/74496
+static const char *win_reserved_words[] = {"CON","PRN","AUX", "NUL",
+ "COM1", "COM2", "COM3", "COM4",
+ "LPT1", "LPT2", "LPT3", "CLOCK$" };
+
+
+bool csync_is_windows_reserved_word(const char* filename) {
+
+ size_t win_reserve_words_len = sizeof(win_reserved_words) / sizeof(char*);
+ size_t j;
+
+ for (j = 0; j < win_reserve_words_len; j++) {
+ int len_reserved_word = strlen(win_reserved_words[j]);
+ int len_filename = strlen(filename);
+ if (len_filename == 2 && filename[1] == ':') {
+ if (filename[0] >= 'a' && filename[0] <= 'z') {
+ return true;
+ }
+ if (filename[0] >= 'A' && filename[0] <= 'Z') {
+ return true;
+ }
+ }
+ if (c_strncasecmp(filename, win_reserved_words[j], len_reserved_word) == 0) {
+ if (len_filename == len_reserved_word) {
+ return true;
+ }
+ if ((len_filename > len_reserved_word) && (filename[len_reserved_word] == '.')) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) {
size_t i = 0;
const char *p = NULL;
@@ -214,6 +248,13 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
SAFE_FREE(dname);
goto out;
}
+
+ if (csync_is_windows_reserved_word(bname)) {
+ match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
+ SAFE_FREE(bname);
+ SAFE_FREE(dname);
+ goto out;
+ }
#endif
rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
diff --git a/csync/src/csync_exclude.h b/csync/src/csync_exclude.h
index 84a65bef7..efc809f74 100644
--- a/csync/src/csync_exclude.h
+++ b/csync/src/csync_exclude.h
@@ -80,4 +80,12 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype);
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
#endif /* _CSYNC_EXCLUDE_H */
+/**
+ * @brief Checks if filename is considered reserved by Windows
+ * @param file_name filename
+ * @return true if file is reserved, false otherwise
+ */
+bool csync_is_windows_reserved_word(const char *file_name);
+
+
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/std/c_string.c b/csync/src/std/c_string.c
index 9d2c087ec..f1ca5f747 100644
--- a/csync/src/std/c_string.c
+++ b/csync/src/std/c_string.c
@@ -134,6 +134,14 @@ static char *c_iconv(const char* str, enum iconv_direction dir)
}
#endif /* defined(HAVE_ICONV) && defined(WITH_ICONV) */
+int c_strncasecmp(const char *a, const char *b, size_t n) {
+#ifdef _WIN32
+ return _strnicmp(a, b, n);
+#else
+ return strncasecmp(a, b, n);
+#endif
+}
+
int c_streq(const char *a, const char *b) {
register const char *s1 = a;
register const char *s2 = b;
diff --git a/csync/src/std/c_string.h b/csync/src/std/c_string.h
index d80727a63..920266c5c 100644
--- a/csync/src/std/c_string.h
+++ b/csync/src/std/c_string.h
@@ -60,6 +60,17 @@ struct c_strlist_s {
};
/**
+ * @brief Compare to strings case insensitively.
+ *
+ * @param a First string to compare.
+ * @param b Second string to compare.
+ * @param n Max comparison length.
+ *
+ * @return see strncasecmp
+ */
+int c_strncasecmp(const char *a, const char *b, size_t n);
+
+/**
* @brief Compare to strings if they are equal.
*
* @param a First string to compare.
diff --git a/csync/tests/csync_tests/check_csync_exclude.c b/csync/tests/csync_tests/check_csync_exclude.c
index 1d216eba0..94430eafc 100644
--- a/csync/tests/csync_tests/check_csync_exclude.c
+++ b/csync/tests/csync_tests/check_csync_exclude.c
@@ -174,6 +174,25 @@ static void check_csync_pathes(void **state)
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
}
+static void check_csync_is_windows_reserved_word() {
+ assert_true(csync_is_windows_reserved_word("CON"));
+ assert_true(csync_is_windows_reserved_word("con"));
+ assert_true(csync_is_windows_reserved_word("CON."));
+ assert_true(csync_is_windows_reserved_word("con."));
+ assert_true(csync_is_windows_reserved_word("CON.ference"));
+ assert_false(csync_is_windows_reserved_word("CONference"));
+ assert_false(csync_is_windows_reserved_word("conference"));
+ assert_false(csync_is_windows_reserved_word("conf.erence"));
+ assert_false(csync_is_windows_reserved_word("co"));
+ assert_true(csync_is_windows_reserved_word("A:"));
+ assert_true(csync_is_windows_reserved_word("a:"));
+ assert_true(csync_is_windows_reserved_word("z:"));
+ assert_true(csync_is_windows_reserved_word("Z:"));
+ assert_true(csync_is_windows_reserved_word("M:"));
+ assert_true(csync_is_windows_reserved_word("m:"));
+
+}
+
int torture_run_tests(void)
{
const UnitTest tests[] = {
@@ -181,6 +200,7 @@ int torture_run_tests(void)
unit_test_setup_teardown(check_csync_exclude_load, setup, teardown),
unit_test_setup_teardown(check_csync_excluded, setup_init, teardown),
unit_test_setup_teardown(check_csync_pathes, setup_init, teardown),
+ unit_test_setup_teardown(check_csync_is_windows_reserved_word, setup_init, teardown),
};
return run_tests(tests);