Skip to content

Commit

Permalink
Merge pull request owncloud#2391 from owncloud/ignore_windows_reserve…
Browse files Browse the repository at this point in the history
…d_characters

Ignore reserved words on Windows
  • Loading branch information
danimo committed Oct 24, 2014
2 parents 0e828d8 + d76192c commit d0b40ba
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
41 changes: 41 additions & 0 deletions csync/src/csync_exclude.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions csync/src/csync_exclude.h
Original file line number Diff line number Diff line change
Expand Up @@ -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: */
8 changes: 8 additions & 0 deletions csync/src/std/c_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions csync/src/std/c_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ struct c_strlist_s {
size_t size;
};

/**
* @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.
*
Expand Down
20 changes: 20 additions & 0 deletions csync/tests/csync_tests/check_csync_exclude.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,33 @@ 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[] = {
unit_test_setup_teardown(check_csync_exclude_add, setup, teardown),
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);
Expand Down

0 comments on commit d0b40ba

Please sign in to comment.