From ecdcabd10f4a64defc05317e842527cc2fffce0e Mon Sep 17 00:00:00 2001 From: magnum Date: Tue, 7 Oct 2025 14:44:46 +0200 Subject: [PATCH] Format selection: Add an "after" option Matches all formats after a specific one. Put in other words, skip all formats up to and including the named one. This is for situations where you test all formats and it segfaults on eg. foo-opencl. You can now resume the tests from the next format, using --format=/foo-opencl. --- src/formats.c | 36 ++++++++++++++++++++++++++++++++---- src/john.c | 10 +++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/formats.c b/src/formats.c index b6fba4094c..495c916e8a 100644 --- a/src/formats.c +++ b/src/formats.c @@ -235,6 +235,27 @@ static int exclude_formats(char *rej_format, struct fmt_main **full_fmt_list) return removed; } +/* Exclusions. Drop all format(s) up to and including the matching rej_format from full list */ +static int exclude_formats_up_to(char *rej_format, struct fmt_main **full_fmt_list) +{ + static int drop = 1; + struct fmt_main *current; + int removed = 0; + + if ((current = *full_fmt_list)) + do { + if (drop) { + if (fmt_match(rej_format, current, 1)) + drop = 0; + *full_fmt_list = current->next; + removed++; + } else + break; + } while ((current = current->next)); + + return removed; +} + /* Inclusions. Move any format(s) matching req_format from full list to new list */ static int include_formats(char *req_format, struct fmt_main **full_fmt_list) { @@ -329,7 +350,7 @@ static void comma_split(struct list_main *dst, const char *src) char* fmt_type(char *name) { - if (name[1] && (name[0] == '+' || name[0] == '-')) + if (name[1] && (name[0] == '+' || name[0] == '-' || name[0] == '/')) name++; if (fmt_is_class(name)) @@ -357,9 +378,16 @@ int fmt_check_custom_list(void) fmt_list = NULL; fmt_tail = &fmt_list; - /* "-" Exclusions first, from the full list. */ + /* "-" or "/" Exclusions first, from the full list. */ do { - if (req_format->data[0] == '-') { + if (req_format->data[0] == '/') { + char *exclude_fmt = &(req_format->data[1]); + + if (!exclude_fmt[0]) + error_msg("Error: '%s' in format list doesn't make sense\n", req_format->data); + num_e += exclude_formats_up_to(exclude_fmt, &full_fmt_list); + } + else if (req_format->data[0] == '-') { char *exclude_fmt = &(req_format->data[1]); if (!exclude_fmt[0]) @@ -371,7 +399,7 @@ int fmt_check_custom_list(void) /* Inclusions. Move to the new list. */ req_format = req_formats->head; do { - if ((req_format->data[0] != '-') && (req_format->data[0] != '+')) { + if ((req_format->data[0] != '-') && (req_format->data[0] != '+') && (req_format->data[0] != '/')) { had_i = 1; if (!include_formats(req_format->data, &full_fmt_list) && !is_in_fmt_list(req_format->data)) { if (john_main_process) diff --git a/src/john.c b/src/john.c index 29d9411704..d7b90a9227 100644 --- a/src/john.c +++ b/src/john.c @@ -202,7 +202,15 @@ static int exit_status = 0; static void john_register_one(struct fmt_main *format) { if (options.format) { - if (options.format[0] == '-' && options.format[1]) { + if (options.format[0] == '/' && options.format[1]) { + static int drop = 1; + + if (drop) { + if (fmt_match(&options.format[1], format, 1)) + drop = 0; + return; + } + } else if (options.format[0] == '-' && options.format[1]) { if (fmt_match(&options.format[1], format, 1)) return; } else if (options.format[0] == '+' && options.format[1]) {