add support for uppercase and lowercase in --restrict-file-names
Mauro Tortonesi <[email protected]> Tue, 13 Jun 2006 15:53:12 +0200
| Newsgroups | gmane.comp.web.wget.patches |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. --------------050306030406090702000101 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit this patch adds support for character case restrictions by introducing the new 'uppercase' and 'lowercase' modes in the --restrict-file-names option. 2006-06-13 Mauro Tortonesi <[email protected]> * options.h (struct options): Introduced member restrict_files_case to keep track of preferences on character case restrictions for filenames. * init.c: Modified defaults and cmd_spec_restrict_file_names to support character case restrictions for filenames. Added test_cmd_spec_restrict_file_names unit test. * url.c: Modified append_uri_pathel to support character case restrictions for filenames. Added test_append_uri_pathel unit test. * test.c: Added test_cmd_spec_restrict_file_names and test_append_uri_pathel to the list of unit tests to run. -- Aequam memento rebus in arduis servare mentem... Mauro Tortonesi http://www.tortonesi.com University of Ferrara - Dept. of Eng. http://www.ing.unife.it GNU Wget - HTTP/FTP file retrieval tool http://www.gnu.org/software/wget Deep Space 6 - IPv6 for Linux http://www.deepspace6.net Ferrara Linux User Group http://www.ferrara.linux.it --------------050306030406090702000101 Content-Type: text/plain; name="restrict-case.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="restrict-case.diff" Index: options.h =================================================================== --- options.h (revisione 2146) +++ options.h (copia locale) @@ -203,6 +203,11 @@ bool restrict_files_ctrl; /* non-zero if control chars in URLs are restricted from appearing in generated file names. */ + enum { + restrict_no_case_restriction, + restrict_lowercase, + restrict_uppercase + } restrict_files_case; /* file name case restriction. */ bool strict_comments; /* whether strict SGML comments are enforced. */ Index: init.c =================================================================== --- init.c (revisione 2146) +++ init.c (copia locale) @@ -54,6 +54,10 @@ #include "http.h" /* for http_cleanup */ #include "retr.h" /* for output_stream */ +#ifdef TESTING +#include "test.h" +#endif + /* We want tilde expansion enabled only when reading `.wgetrc' lines; otherwise, it will be performed by the shell. This variable will be set by the wgetrc-reading function. */ @@ -314,6 +318,7 @@ opt.restrict_files_os = restrict_windows; #endif opt.restrict_files_ctrl = true; + opt.restrict_files_case = restrict_no_case_restriction; opt.content_disposition = true; } @@ -1178,40 +1183,47 @@ { int restrict_os = opt.restrict_files_os; int restrict_ctrl = opt.restrict_files_ctrl; + int restrict_case = opt.restrict_files_case; - const char *end = strchr (val, ','); - if (!end) - end = val + strlen (val); + const char *end; #define VAL_IS(string_literal) BOUNDED_EQUAL (val, end, string_literal) + do + { + end = strchr (val, ','); + if (!end) + end = val + strlen (val); + if (VAL_IS ("unix")) restrict_os = restrict_unix; else if (VAL_IS ("windows")) restrict_os = restrict_windows; + else if (VAL_IS ("lowercase")) + restrict_case = restrict_lowercase; + else if (VAL_IS ("uppercase")) + restrict_case = restrict_uppercase; else if (VAL_IS ("nocontrol")) - restrict_ctrl = 0; + restrict_ctrl = false; else { - err: fprintf (stderr, - _("%s: %s: Invalid restriction `%s', use `unix' or `windows'.\n"), + _("%s: %s: Invalid restriction `%s', use [unix|windows],[lowercase|uppercase],[nocontrol].\n"), exec_name, com, val); return false; } -#undef VAL_IS - if (*end) - { - if (!strcmp (end + 1, "nocontrol")) - restrict_ctrl = false; - else - goto err; + val = end + 1; } + while (*val && *end); + +#undef VAL_IS opt.restrict_files_os = restrict_os; opt.restrict_files_ctrl = restrict_ctrl; + opt.restrict_files_case = restrict_case; + return true; } @@ -1492,3 +1504,50 @@ xfree_null (opt.passwd); #endif /* DEBUG_MALLOC */ } + +/* Unit testing routines. */ + +#ifdef TESTING + +const char * +test_cmd_spec_restrict_file_names() +{ + int i; + struct { + char *val; + int expected_restrict_files_os; + int expected_restrict_files_ctrl; + int expected_restrict_files_case; + bool result; + } test_array[] = { + { "windows", restrict_windows, true, restrict_no_case_restriction, true }, + { "windows,", restrict_windows, true, restrict_no_case_restriction, true }, + { "windows,lowercase", restrict_windows, true, restrict_lowercase, true }, + { "unix,nocontrol,lowercase,", restrict_unix, false, restrict_lowercase, true }, + }; + + for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) + { + bool res; + + defaults(); + res = cmd_spec_restrict_file_names ("dummy", test_array[i].val, NULL); + + /* + fprintf (stderr, "test_cmd_spec_restrict_file_names: TEST %d\n", i); fflush (stderr); + fprintf (stderr, "opt.restrict_files_os: %d\n", opt.restrict_files_os); fflush (stderr); + fprintf (stderr, "opt.restrict_files_ctrl: %d\n", opt.restrict_files_ctrl); fflush (stderr); + fprintf (stderr, "opt.restrict_files_case: %d\n", opt.restrict_files_case); fflush (stderr); + */ + mu_assert ("test_cmd_spec_restrict_file_names: wrong result", + res == test_array[i].result + && opt.restrict_files_os == test_array[i].expected_restrict_files_os + && opt.restrict_files_ctrl == test_array[i].expected_restrict_files_ctrl + && opt.restrict_files_case == test_array[i].expected_restrict_files_case); + } + + return NULL; +} + +#endif /* TESTING */ + Index: ChangeLog =================================================================== --- ChangeLog (revisione 2150) +++ ChangeLog (copia locale) @@ -1,3 +1,19 @@ +2006-06-13 Mauro Tortonesi <[email protected]> + + * options.h (struct options): Introduced member restrict_files_case to + keep track of preferences on character case restrictions for + filenames. + + * init.c: Modified defaults and cmd_spec_restrict_file_names to + support character case restrictions for filenames. Added + test_cmd_spec_restrict_file_names unit test. + + * url.c: Modified append_uri_pathel to support character case + restrictions for filenames. Added test_append_uri_pathel unit test. + + * test.c: Added test_cmd_spec_restrict_file_names and + test_append_uri_pathel to the list of unit tests to run. + 2006-06-12 Mauro Tortonesi <[email protected]> * retr.c (retrieve_from_file): Use retrieve_tree and automatically Index: test.c =================================================================== --- test.c (revisione 2146) +++ test.c (copia locale) @@ -38,6 +38,8 @@ const char *test_parse_content_disposition(); const char *test_subdir_p(); const char *test_dir_matches_p(); +const char *test_cmd_spec_restrict_file_names(); +const char *test_append_uri_pathel(); int tests_run; @@ -47,6 +49,8 @@ mu_run_test (test_parse_content_disposition); mu_run_test (test_subdir_p); mu_run_test (test_dir_matches_p); + mu_run_test (test_cmd_spec_restrict_file_names); + mu_run_test (test_append_uri_pathel); return NULL; } Index: url.c =================================================================== --- url.c (revisione 2146) +++ url.c (copia locale) @@ -43,6 +43,10 @@ #include "url.h" #include "host.h" /* for is_valid_ipv6_address */ +#ifdef TESTING +#include "test.h" +#endif + enum { scm_disabled = 1, /* for https when OpenSSL fails to init. */ scm_has_params = 2, /* whether scheme has ;params */ @@ -1360,6 +1364,21 @@ } assert (q - TAIL (dest) == outlen); } + + /* Perform inline case transformation if required. */ + if (opt.restrict_files_case == restrict_lowercase + || opt.restrict_files_case == restrict_uppercase) + { + char *q; + for (q = TAIL (dest); *q; ++q) + { + if (opt.restrict_files_case == restrict_lowercase) + *q = TOLOWER (*q); + else + *q = TOUPPER (*q); + } + } + TAIL_INCR (dest, outlen); } @@ -1984,3 +2003,38 @@ } } #endif + +#ifdef TESTING + +const char * +test_append_uri_pathel() +{ + int i; + struct { + char *original_url; + char *input; + bool escaped; + char *expected_result; + } test_array[] = { + { "http://www.yoyodyne.com/path/", "somepage.html", false, "http://www.yoyodyne.com/path/somepage.html" }, + }; + + for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i) + { + struct growable dest; + const char *p = test_array[i].input; + + memset (&dest, 0, sizeof (dest)); + + append_string (test_array[i].original_url, &dest); + append_uri_pathel (p, p + strlen(p), test_array[i].escaped, &dest); + + mu_assert ("test_append_uri_pathel: wrong result", + strcmp (dest.base, test_array[i].expected_result) == 0); + } + + return NULL; +} + +#endif /* TESTING */ + --------------050306030406090702000101--