]> git.seodisparate.com - SimpleArchiver/commitdiff
WIP white/black-list: Impl. case-insensitive
authorStephen Seo <seo.disparate@gmail.com>
Mon, 17 Feb 2025 06:23:44 +0000 (15:23 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Mon, 17 Feb 2025 06:23:44 +0000 (15:23 +0900)
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.

Changelog.md
README.md
src/archiver.c
src/helpers.c
src/helpers.h
src/parser.c
src/parser.h
src/test.c

index 505dd5931fbdec13500fa05bbd8e2ac2f6ca7484..fe2a33a7e7aa94f677838862e63fee09dfac7313 100644 (file)
@@ -9,6 +9,7 @@ Add white/black-list flags:
     - `--blacklist-contains <text>`
     - `--blacklist-begins-with <text>`
     - `--blacklist-ends-with <text>`
+    - `--wb-case-insensitive`
 
 These flags should affect what entries are archived, what entries are printed
 (with `-t`), and what entries are extracted.
index 5e4d0ed7814f0a2348074cc2b7fe7b9cd3e6a33c..fd0b2e0708cf5641c4dd7c783a3c11ece84c8347 100644 (file)
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ API calls.
     --blacklist-contains <text> : blacklist entries that contains "<text>", specify multiple times to deny multiple "<text>" entries at once.
     --blacklist-begins-with <text> : blacklist entries that starts with "<text>", specify multiple times to deny multiple entries starting with different "<text>" entries.
     --blacklist-ends-with <text> : blacklist entries that ends with "<text>", specify multiple times to deny multiple entries ending with different "<text>" 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.
index d956d3e44c36d505bf48a7eac3bfdda276372a3a..74a1c75afa5e425096b5b772fd25889883dc79f2 100644 (file)
@@ -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,
index 5d102e0bfc1f32ea41b0d24e0eb2d9f05f8c6039..8150e2c0682b46afc3957771a148f099f6b75e85 100644 (file)
@@ -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;
         }
       }
index 37d549379de807719d66ca1851722ec00b53c71b..04936cd0e7be6459f57b889f308a1cfcdf2c552a 100644 (file)
@@ -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,
index 4ef9813e87b5b52f34e64edc4d96767e9a939424..b5c231110922c40fa40c57acff69bd7447f138bd 100644 (file)
@@ -267,6 +267,9 @@ void simple_archiver_print_usage(void) {
           "--blacklist-ends-with <text> : blacklist entries that ends with "
           "\"<text>\", specify multiple times to deny multiple entries ending "
           "with different \"<text>\" 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);
index bfecf6206cf60ce6eadf7dacadbd8b9188356435..241d595f7315ecb36fa8315894a84912f12c563b 100644 (file)
@@ -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;
index a84ca34c7bb7407eb87a213534c79f2c4eb58608..5ccfade0aa8cacc3ca044e7a9c32793872b8cd94 100644 (file)
@@ -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);