diff --git a/docs/commandline.rst b/docs/commandline.rst index 1454ac28..c7f6c187 100644 --- a/docs/commandline.rst +++ b/docs/commandline.rst @@ -97,6 +97,10 @@ Available options are: Disable warnings. +.. option:: --fail-on-warnings + + Treat warnings as errors. Has no effect if used with --no-warnings. + .. option:: -v --version Show version information. diff --git a/yara.c b/yara.c index efd5f6bf..3a3d8e39 100644 --- a/yara.c +++ b/yara.c @@ -82,6 +82,7 @@ typedef struct _MODULE_DATA } MODULE_DATA; + typedef struct _THREAD_ARGS { YR_RULES* rules; @@ -90,13 +91,21 @@ typedef struct _THREAD_ARGS } THREAD_ARGS; -typedef struct _QUEUED_FILE { - +typedef struct _QUEUED_FILE +{ char* path; } QUEUED_FILE; +typedef struct COMPILER_RESULTS +{ + int errors; + int warnings; + +} COMPILER_RESULTS; + + #define MAX_ARGS_TAG 32 #define MAX_ARGS_IDENTIFIER 32 #define MAX_ARGS_EXT_VAR 32 @@ -125,6 +134,7 @@ int limit = 0; int timeout = 1000000; int stack_size = DEFAULT_STACK_SIZE; int threads = 8; +int fail_on_warnings = FALSE; #define USAGE_STRING \ @@ -184,6 +194,9 @@ args_option_t options[] = OPT_BOOLEAN('w', "no-warnings", &ignore_warnings, "disable warnings"), + OPT_BOOLEAN(0, "fail-on-warnings", &fail_on_warnings, + "fail on warnings"), + OPT_BOOLEAN('v', "version", &show_version, "show version information"), @@ -526,10 +539,12 @@ void print_compiler_error( { fprintf(stderr, "%s(%d): error: %s\n", file_name, line_number, message); } - else + else if (!ignore_warnings) { - if (!ignore_warnings) - fprintf(stderr, "%s(%d): warning: %s\n", file_name, line_number, message); + COMPILER_RESULTS* compiler_results = (COMPILER_RESULTS*) user_data; + compiler_results->warnings++; + + fprintf(stderr, "%s(%d): warning: %s\n", file_name, line_number, message); } } @@ -1091,7 +1106,12 @@ int main( exit_with_code(EXIT_FAILURE); } - yr_compiler_set_callback(compiler, print_compiler_error, NULL); + COMPILER_RESULTS cr = { + .errors = 0, + .warnings = 0 + }; + + yr_compiler_set_callback(compiler, print_compiler_error, &cr); FILE* rule_file = fopen(argv[0], "r"); @@ -1101,11 +1121,14 @@ int main( exit_with_code(EXIT_FAILURE); } - int errors = yr_compiler_add_file(compiler, rule_file, NULL, argv[0]); + cr.errors = yr_compiler_add_file(compiler, rule_file, NULL, argv[0]); fclose(rule_file); - if (errors > 0) + if (cr.errors > 0) + exit_with_code(EXIT_FAILURE); + + if (fail_on_warnings && cr.warnings > 0) exit_with_code(EXIT_FAILURE); result = yr_compiler_get_rules(compiler, &rules); diff --git a/yara.man b/yara.man index 0d6ceb11..9d62f5c8 100644 --- a/yara.man +++ b/yara.man @@ -74,6 +74,10 @@ Speeds up scanning by searching only for the first occurrence of each pattern. .B \-w " --no-warnings" Disable warnings. .TP +.B " --fail-on-warnings" +Treat warnings as errors. Has no effect if used with +.B --no-warnings. +.TP .B \-v " --version" Show version information. .SH EXAMPLES diff --git a/yarac.c b/yarac.c index 65d5b9dd..61499350 100644 --- a/yarac.c +++ b/yarac.c @@ -56,10 +56,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define MAX_ARGS_EXT_VAR 32 +typedef struct COMPILER_RESULTS +{ + int errors; + int warnings; + +} COMPILER_RESULTS; + + char* ext_vars[MAX_ARGS_EXT_VAR + 1]; int ignore_warnings = FALSE; int show_version = FALSE; int show_help = FALSE; +int fail_on_warnings = FALSE; #define USAGE_STRING \ @@ -73,6 +82,9 @@ args_option_t options[] = OPT_BOOLEAN('w', "no-warnings", &ignore_warnings, "disable warnings"), + OPT_BOOLEAN(0, "fail-on-warnings", &fail_on_warnings, + "fail on warnings"), + OPT_BOOLEAN('v', "version", &show_version, "show version information"), @@ -108,10 +120,12 @@ void report_error( { fprintf(stderr, "%s(%d): error: %s\n", file_name, line_number, message); } - else + else if (!ignore_warnings) { - if (!ignore_warnings) - fprintf(stderr, "%s(%d): warning: %s\n", file_name, line_number, message); + COMPILER_RESULTS* compiler_results = (COMPILER_RESULTS*) user_data; + compiler_results->warnings++; + + fprintf(stderr, "%s(%d): warning: %s\n", file_name, line_number, message); } } @@ -189,7 +203,7 @@ int main( { printf("%s\n\n", USAGE_STRING); - args_print_usage(options, 25); + args_print_usage(options, 35); printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT); return EXIT_SUCCESS; @@ -215,7 +229,12 @@ int main( if (!define_external_variables(compiler)) exit_with_code(EXIT_FAILURE); - yr_compiler_set_callback(compiler, report_error, NULL); + COMPILER_RESULTS cr = { + .errors = 0, + .warnings = 0 + }; + + yr_compiler_set_callback(compiler, report_error, &cr); for (int i = 0; i < argc - 1; i++) { @@ -239,12 +258,15 @@ int main( if (rule_file != NULL) { - int errors = yr_compiler_add_file( + cr.errors = yr_compiler_add_file( compiler, rule_file, ns, file_name); fclose(rule_file); - if (errors) // errors during compilation + if (cr.errors) // errors during compilation + exit_with_code(EXIT_FAILURE); + + if (fail_on_warnings && cr.warnings > 0) exit_with_code(EXIT_FAILURE); } else diff --git a/yarac.man b/yarac.man index 2a1bfed2..0852da90 100644 --- a/yarac.man +++ b/yarac.man @@ -29,13 +29,15 @@ if it’s a path to a directory all the files contained in it will be scanned. \fB-d\fP = define external variable. .TP -.B -\fB-w\fP -disable warnings. +.B \-w " --no-warnings" +Disable warnings. .TP -.B -\fB-v\fP -show version information. +.B " --fail-on-warnings" +Treat warnings as errors. Has no effect if used with +.B --no-warnings. +.TP +.B \-v " --version" +Show version information. .SH EXAMPLE The \fB-d\fP is used to define external variables. For example: .PP