Skip to content

Commit cccc6dc

Browse files
committed
Fix: correct broken parsing of config strings on Windows
Config strings were parsed as garbage on Windows.
1 parent 176935b commit cccc6dc

2 files changed

Lines changed: 33 additions & 17 deletions

File tree

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
Mon 06 Apr 2026 Aleksey Kravchenko
2+
* Bugfix: Fix parsing of config strings on Windows
3+
14
Wed 14 May 2025 Aleksey Kravchenko
25
* === Version 1.4.6 ===
36

parse_cmdline.c

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ enum option_type_t
394394
F_TSTR = 3 | F_NEED_PARAM, /* store parameter as a tstr_t */
395395
F_TOUT = 4 | F_NEED_PARAM | F_OUTPUT_OPT,
396396
F_VFNC = 5, /* just call a function */
397-
F_PFNC = 6 | F_NEED_PARAM, /* process option parameter by calling a handler */
398397
F_TFNC = 7 | F_NEED_PARAM, /* process option parameter by calling a handler */
399398
F_UFNC = 8 | F_NEED_PARAM, /* pass UTF-8 encoded parameter to the handler */
400399
F_PRNT = 9, /* print a constant C-string and exit */
@@ -483,18 +482,18 @@ cmdline_opt_t cmdline_opt[] =
483482
{ F_UFLG, 0, 0, "speed", 0, &opt.flags, OPT_SPEED },
484483
{ F_UFLG, 'e', 0, "embed-crc", 0, &opt.flags, OPT_EMBED_CRC },
485484
{ F_CSTR, 0, 0, "embed-crc-delimiter", 0, &opt.embed_crc_delimiter, 0 },
486-
{ F_PFNC, 0, 0, "path-separator", (opt_handler_t)set_path_separator, 0, 0 },
485+
{ F_UFNC, 0, 0, "path-separator", (opt_handler_t)set_path_separator, 0, 0 },
487486
{ F_TOUT, 'o', 0, "output", 0, &opt.output, 0 },
488487
{ F_TOUT, 'l', 0, "log", 0, &opt.log, 0 },
489-
{ F_PFNC, 'q', 0, "accept", (opt_handler_t)add_file_suffix, 0, MASK_ACCEPT },
490-
{ F_PFNC, 't', 0, "crc-accept", (opt_handler_t)add_file_suffix, 0, MASK_CRC_ACCEPT },
491-
{ F_PFNC, 0, 0, "exclude", (opt_handler_t)add_file_suffix, 0, MASK_EXCLUDE },
488+
{ F_UFNC, 'q', 0, "accept", (opt_handler_t)add_file_suffix, 0, MASK_ACCEPT },
489+
{ F_UFNC, 't', 0, "crc-accept", (opt_handler_t)add_file_suffix, 0, MASK_CRC_ACCEPT },
490+
{ F_UFNC, 0, 0, "exclude", (opt_handler_t)add_file_suffix, 0, MASK_EXCLUDE },
492491
{ F_VFNC, 0, 0, "video", (opt_handler_t)accept_video, 0, 0 },
493492
{ F_VFNC, 0, 0, "nya", (opt_handler_t)nya, 0, 0 },
494-
{ F_PFNC, 0, 0, "max-depth", (opt_handler_t)set_max_depth, 0, 0 },
493+
{ F_UFNC, 0, 0, "max-depth", (opt_handler_t)set_max_depth, 0, 0 },
495494
{ F_UFLG, 0, 0, "bt-private", 0, &opt.flags, OPT_BT_PRIVATE },
496495
{ F_UFLG, 0, 0, "bt-transmission", 0, &opt.flags, OPT_BT_TRANSMISSION },
497-
{ F_PFNC, 0, 0, "bt-piece-length", (opt_handler_t)set_bt_piece_length, 0, 0 },
496+
{ F_UFNC, 0, 0, "bt-piece-length", (opt_handler_t)set_bt_piece_length, 0, 0 },
498497
{ F_UFNC, 0, 0, "bt-announce", (opt_handler_t)bt_announce, 0, 0 },
499498
{ F_TSTR, 0, 0, "bt-batch", 0, &opt.bt_batch_file, 0 },
500499
{ F_UFLG, 0, 0, "benchmark-raw", 0, &opt.flags, OPT_BENCH_RAW },
@@ -503,10 +502,10 @@ cmdline_opt_t cmdline_opt[] =
503502
{ F_UFLG, 0, 0, "hex", 0, &opt.flags, OPT_HEX },
504503
{ F_UFLG, 0, 0, "base32", 0, &opt.flags, OPT_BASE32 },
505504
{ F_UFLG, 'b', 0, "base64", 0, &opt.flags, OPT_BASE64 },
506-
{ F_PFNC, 0, 0, "openssl", (opt_handler_t)openssl_flags, 0, 0 },
505+
{ F_UFNC, 0, 0, "openssl", (opt_handler_t)openssl_flags, 0, 0 },
507506

508507
/* for compatibility */
509-
{ F_PFNC, 0, 0, "maxdepth", (opt_handler_t)set_max_depth, 0, 0 },
508+
{ F_UFNC, 0, 0, "maxdepth", (opt_handler_t)set_max_depth, 0, 0 },
510509

511510
#ifdef _WIN32 /* code pages (windows only) */
512511
{ F_UENC, 0, 0, "utf8", 0, &opt.flags, OPT_UTF8 },
@@ -553,25 +552,35 @@ static void apply_option(options_t* opts, parsed_option_t* option)
553552

554553
/* check if option requires a parameter */
555554
if (is_param_required(option_type)) {
556-
if (!option->parameter) {
555+
#ifdef _WIN32
556+
int from_config = (opts == &conf_opt);
557+
#endif
558+
rsh_tchar* tparam = (rsh_tchar*)option->parameter;
559+
if (!tparam) {
557560
die(_("argument is required for option %s\n"), option->name);
558561
}
559562

560563
#ifdef _WIN32
564+
if (from_config) {
565+
/* treat config lines as UTF-8 encoded and convert it to UTF-16 */
566+
tparam = convert_str_to_wcs((char*)option->parameter, ConvertToUtf8);
567+
}
561568
if (option_type == F_TOUT || option_type == F_TFNC || option_type == F_TSTR) {
562569
/* leave the value in UTF-16 */
563-
value = (char*)rsh_wcsdup((wchar_t*)option->parameter);
570+
value = (char*)rsh_wcsdup(tparam);
564571
}
565572
else if (option_type == F_UFNC) {
566573
/* convert from UTF-16 to UTF-8 */
567-
value = convert_wcs_to_str((wchar_t*)option->parameter, ConvertToUtf8 | ConvertExact);
574+
value = convert_wcs_to_str(tparam, ConvertToUtf8 | ConvertExact);
568575
} else {
569576
/* convert from UTF-16 */
570-
value = convert_wcs_to_str((wchar_t*)option->parameter, ConvertToPrimaryEncoding);
577+
value = convert_wcs_to_str(tparam, ConvertToPrimaryEncoding);
571578
}
572579
rsh_vector_add_ptr(opt.mem, value);
580+
if (from_config)
581+
free(tparam);
573582
#else
574-
value = (char*)option->parameter;
583+
value = tparam;
575584
#endif
576585
}
577586

@@ -587,7 +596,6 @@ static void apply_option(options_t* opts, parsed_option_t* option)
587596
/* save the option parameter */
588597
*(char**)((char*)opts + ((char*)o->ptr - (char*)&opt)) = value;
589598
break;
590-
case F_PFNC:
591599
case F_TFNC:
592600
case F_UFNC:
593601
/* call option parameter handler */
@@ -741,7 +749,7 @@ static int read_config(void)
741749
int res;
742750

743751
/* initialize conf_opt */
744-
memset(&conf_opt, 0, sizeof(opt));
752+
memset(&conf_opt, 0, sizeof(conf_opt));
745753
conf_opt.find_max_depth = -1;
746754

747755
if (!find_conf_file()) return 0;
@@ -750,14 +758,19 @@ static int read_config(void)
750758

751759
fd = file_fopen(&rhash_data.config_file, FOpenRead);
752760
if (!fd) return -1;
761+
memset(&option, 0, sizeof(option));
753762

754763
while (fgets(buf, LINE_BUF_SIZE, fd)) {
755764
size_t index;
756765
cmdline_opt_t* t;
757-
char* line = str_trim(buf);
766+
char* line = buf;
758767
char* name;
759768
char* value;
760769

770+
if (STARTS_WITH_UTF8_BOM(line))
771+
line += 3;
772+
line = str_trim(line);
773+
761774
line_number++;
762775
if (*line == 0 || IS_COMMENT(*line))
763776
continue;

0 commit comments

Comments
 (0)