From: Stephen Seo Date: Mon, 17 Feb 2025 06:23:44 +0000 (+0900) Subject: WIP white/black-list: Impl. case-insensitive X-Git-Tag: 1.16^2~22 X-Git-Url: https://git.seodisparate.com/stephenseo/search/main.js?a=commitdiff_plain;h=7ef2d9ec4c513dec40cc9a7d4161a106b871ebcb;p=SimpleArchiver WIP white/black-list: Impl. case-insensitive Impelment flag that makes white/black-list filtering be case-insensitive. TODO: - white/black-lists for test/extract for file format version 1 and 2. - white/black-lists for create/text/extract for file format version 0. --- diff --git a/Changelog.md b/Changelog.md index 505dd59..fe2a33a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Add white/black-list flags: - `--blacklist-contains ` - `--blacklist-begins-with ` - `--blacklist-ends-with ` + - `--wb-case-insensitive` These flags should affect what entries are archived, what entries are printed (with `-t`), and what entries are extracted. diff --git a/README.md b/README.md index 5e4d0ed..fd0b2e0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ API calls. --blacklist-contains : blacklist entries that contains "", specify multiple times to deny multiple "" entries at once. --blacklist-begins-with : blacklist entries that starts with "", specify multiple times to deny multiple entries starting with different "" entries. --blacklist-ends-with : blacklist entries that ends with "", specify multiple times to deny multiple entries ending with different "" entries. + --wb-case-insensitive : Makes white/black-list checking case insensitive. --version : prints version and exits -- : specifies remaining arguments are files to archive/extract If creating archive file, remaining args specify files to archive. diff --git a/src/archiver.c b/src/archiver.c index d956d3e..74a1c75 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -1707,6 +1707,7 @@ int symlinks_and_files_from_files(void *data, void *ud) { // Check white/black lists. if (!simple_archiver_helper_string_allowed_lists( file_info->filename, + state->parsed->flags & 0x20000 ? 1 : 0, state->parsed->whitelist_contains, state->parsed->whitelist_begins, state->parsed->whitelist_ends, @@ -8359,6 +8360,7 @@ int simple_archiver_parse_archive_version_3(FILE *in_f, const uint_fast8_t lists_allowed = simple_archiver_helper_string_allowed_lists( link_name, + state->parsed->flags & 0x20000 ? 1 : 0, state->parsed->whitelist_contains, state->parsed->whitelist_begins, state->parsed->whitelist_ends, @@ -8973,6 +8975,7 @@ int simple_archiver_parse_archive_version_3(FILE *in_f, file_info->other_flags |= 1; } else if (simple_archiver_helper_string_allowed_lists( file_info->filename, + state->parsed->flags & 0x20000 ? 1 : 0, state->parsed->whitelist_contains, state->parsed->whitelist_begins, state->parsed->whitelist_ends, @@ -9704,6 +9707,7 @@ int simple_archiver_parse_archive_version_3(FILE *in_f, const uint_fast8_t lists_allowed = simple_archiver_helper_string_allowed_lists( archive_dir_name, + state->parsed->flags & 0x20000 ? 1 : 0, state->parsed->whitelist_contains, state->parsed->whitelist_begins, state->parsed->whitelist_ends, diff --git a/src/helpers.c b/src/helpers.c index 5d102e0..8150e2c 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -613,13 +613,25 @@ char *simple_archiver_helper_string_parts_combine( } uint_fast8_t simple_archiver_helper_string_contains(const char *cstring, - const char *contains) { + const char *contains, + uint_fast8_t case_i) { const size_t cstring_size = strlen(cstring); const size_t contains_size = strlen(contains); size_t contains_match_start = 0; size_t contains_match_idx = 0; for (size_t idx = 0; idx < cstring_size; ++idx) { - if (cstring[idx] == contains[contains_match_idx]) { + char cstring_next = cstring[idx]; + char contains_next = contains[contains_match_idx]; + if (case_i) { + if (cstring_next >= 'A' && cstring_next <= 'Z') { + cstring_next += 0x20; + } + if (contains_next >= 'A' && contains_next <= 'Z') { + contains_next += 0x20; + } + } + + if (cstring_next == contains_next) { if (contains_match_idx == 0) { contains_match_start = idx; } @@ -639,13 +651,25 @@ uint_fast8_t simple_archiver_helper_string_contains(const char *cstring, } uint_fast8_t simple_archiver_helper_string_starts(const char *cstring, - const char *starts) { + const char *starts, + uint_fast8_t case_i) { const size_t cstring_len = strlen(cstring); const size_t starts_len = strlen(starts); size_t starts_match_idx = 0; for (size_t idx = 0; idx < cstring_len; ++idx) { - if (cstring[idx] == starts[starts_match_idx]) { + char cstring_next = cstring[idx]; + char starts_next = starts[starts_match_idx]; + if (case_i) { + if (cstring_next >= 'A' && cstring_next <= 'Z') { + cstring_next += 0x20; + } + if (starts_next >= 'A' && starts_next <= 'Z') { + starts_next += 0x20; + } + } + + if (cstring_next == starts_next) { if (starts_match_idx == 0) { if (idx != 0) { return 0; @@ -664,13 +688,25 @@ uint_fast8_t simple_archiver_helper_string_starts(const char *cstring, } uint_fast8_t simple_archiver_helper_string_ends(const char *cstring, - const char *ends) { + const char *ends, + uint_fast8_t case_i) { const size_t cstring_len = strlen(cstring); const size_t ends_len = strlen(ends); size_t ends_idx = 0; for (size_t idx = cstring_len - ends_len; idx < cstring_len; ++idx) { - if (cstring[idx] == ends[ends_idx]) { + char cstring_next = cstring[idx]; + char ends_next = ends[ends_idx]; + if (case_i) { + if (cstring_next >= 'A' && cstring_next <= 'Z') { + cstring_next += 0x20; + } + if (ends_next >= 'A' && ends_next <= 'Z') { + ends_next += 0x20; + } + } + + if (cstring_next == ends_next) { ++ends_idx; if (ends_idx == ends_len) { return 1; @@ -685,6 +721,7 @@ uint_fast8_t simple_archiver_helper_string_ends(const char *cstring, uint_fast8_t simple_archiver_helper_string_allowed_lists( const char *cstring, + uint_fast8_t case_i, const SDArchiverLinkedList *w_contains, const SDArchiverLinkedList *w_begins, const SDArchiverLinkedList *w_ends, @@ -696,7 +733,8 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != w_contains->tail; node = node->next) { if (node->data) { - if (!simple_archiver_helper_string_contains(cstring, node->data)) { + if (!simple_archiver_helper_string_contains( + cstring, node->data, case_i)) { return 0; } } @@ -707,7 +745,8 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != w_begins->tail; node = node->next) { if (node->data) { - if (!simple_archiver_helper_string_starts(cstring, node->data)) { + if (!simple_archiver_helper_string_starts( + cstring, node->data, case_i)) { return 0; } } @@ -718,7 +757,7 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != w_ends->tail; node = node->next) { if (node->data) { - if (!simple_archiver_helper_string_ends(cstring, node->data)) { + if (!simple_archiver_helper_string_ends(cstring, node->data, case_i)) { return 0; } } @@ -730,7 +769,8 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != b_contains->tail; node = node->next) { if (node->data) { - if (simple_archiver_helper_string_contains(cstring, node->data)) { + if (simple_archiver_helper_string_contains( + cstring, node->data, case_i)) { return 0; } } @@ -741,7 +781,7 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != b_begins->tail; node = node->next) { if (node->data) { - if (simple_archiver_helper_string_starts(cstring, node->data)) { + if (simple_archiver_helper_string_starts(cstring, node->data, case_i)) { return 0; } } @@ -752,7 +792,7 @@ uint_fast8_t simple_archiver_helper_string_allowed_lists( node != b_ends->tail; node = node->next) { if (node->data) { - if (simple_archiver_helper_string_ends(cstring, node->data)) { + if (simple_archiver_helper_string_ends(cstring, node->data, case_i)) { return 0; } } diff --git a/src/helpers.h b/src/helpers.h index 37d5493..04936cd 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -120,20 +120,28 @@ char *simple_archiver_helper_string_parts_combine( SAHelperStringParts string_parts); // Returns non-zero if "cstring" contains string "contains". +// "case_i" stands for "case-insensitive". uint_fast8_t simple_archiver_helper_string_contains(const char *cstring, - const char *contains); + const char *contains, + uint_fast8_t case_i); // Returns non-zero if "cstring" starts with string "starts". +// "case_i" stands for "case-insensitive". uint_fast8_t simple_archiver_helper_string_starts(const char *cstring, - const char *starts); + const char *starts, + uint_fast8_t case_i); // Returns non-zero if "cstring" ends with string "ends". +// "case_i" stands for "case-insensitive". uint_fast8_t simple_archiver_helper_string_ends(const char *cstring, - const char *ends); + const char *ends, + uint_fast8_t case_i); // Returns non-zero if "cstring" is allowed by lists. +// "case_i" stands for "case-insensitive". uint_fast8_t simple_archiver_helper_string_allowed_lists( const char *cstring, + uint_fast8_t case_i, const SDArchiverLinkedList *w_contains, const SDArchiverLinkedList *w_begins, const SDArchiverLinkedList *w_ends, diff --git a/src/parser.c b/src/parser.c index 4ef9813..b5c2311 100644 --- a/src/parser.c +++ b/src/parser.c @@ -267,6 +267,9 @@ void simple_archiver_print_usage(void) { "--blacklist-ends-with : blacklist entries that ends with " "\"\", specify multiple times to deny multiple entries ending " "with different \"\" entries.\n"); + fprintf(stderr, + "--wb-case-insensitive : Makes white/black-list checking case " + "insensitive.\n"); fprintf(stderr, "--version : prints version and exits\n"); fprintf(stderr, "-- : specifies remaining arguments are files to archive/extract\n"); @@ -821,6 +824,8 @@ int simple_archiver_parse_args(int argc, const char **argv, --argc; ++argv; + } else if (strcmp(argv[0], "--wb-case-insensitive") == 0) { + out->flags |= 0x20000; } else if (strcmp(argv[0], "--version") == 0) { fprintf(stderr, "Version: %s\n", SIMPLE_ARCHIVER_VERSION_STR); exit(0); diff --git a/src/parser.h b/src/parser.h index bfecf62..241d595 100644 --- a/src/parser.h +++ b/src/parser.h @@ -59,6 +59,8 @@ typedef struct SDArchiverParsed { /// 0b x1xx xxxx xxxx xxxx - Prefer UID over Username when extracting. /// 0b 1xxx xxxx xxxx xxxx - Prefer GID over Group when extracting. /// 0b xxxx xxx1 xxxx xxxx xxxx xxxx - Force set empty directory permissions. + /// 0b xxxx xx1x xxxx xxxx xxxx xxxx - white/black-list checking is + /// case-insensitive. uint32_t flags; /// Null-terminated string. char *filename; diff --git a/src/test.c b/src/test.c index a84ca34..5ccfade 100644 --- a/src/test.c +++ b/src/test.c @@ -967,21 +967,29 @@ TEST_HELPERS_PREFIX_END: // Test contains/starts/ends helpers. { CHECK_TRUE(simple_archiver_helper_string_contains( - "The string is this.", " is ")); + "The string is this.", " is ", 0)); CHECK_FALSE(simple_archiver_helper_string_contains( - "The string is this.", " is d")); + "The string is this.", " is d", 0)); CHECK_TRUE(simple_archiver_helper_string_contains( - "TheseTheThesesThe", "Theses")); + "TheseTheThesesThe", "Theses", 0)); CHECK_TRUE(simple_archiver_helper_string_starts( - "The string is this.", "The ")); + "The string is this.", "The ", 0)); CHECK_FALSE(simple_archiver_helper_string_starts( - "The string is this.", "tThe ")); + "The string is this.", "tThe ", 0)); CHECK_TRUE(simple_archiver_helper_string_ends( - "The string is this.", " this.")); + "The string is this.", " this.", 0)); CHECK_FALSE(simple_archiver_helper_string_ends( - "The string is this.", " this")); + "The string is this.", " this", 0)); + + + CHECK_TRUE(simple_archiver_helper_string_contains( + "The String Is This.", "sTRING", 1)); + CHECK_TRUE(simple_archiver_helper_string_starts( + "The String Is This.", "tHE", 1)); + CHECK_TRUE(simple_archiver_helper_string_ends( + "The String Is This.", "tHIS.", 1)); } printf("Checks checked: %" PRId32 "\n", checks_checked);