From 23be0104f7f0395f8a8c3a24d77faae58eb94e1a Mon Sep 17 00:00:00 2001 From: edhoedt Date: Thu, 24 Aug 2017 16:59:58 +0200 Subject: [PATCH 01/13] Full structure implemented, callback available. TODO: actually use the callback's result to import rules files. --- libyara/compiler.c | 23 ++++ libyara/include/yara/compiler.h | 14 +++ libyara/lexer.c | 197 ++++++++++++++++++-------------- libyara/lexer.l | 131 ++++++++++++--------- 4 files changed, 228 insertions(+), 137 deletions(-) diff --git a/libyara/compiler.c b/libyara/compiler.c index 4280c3061e..8b597befe8 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -56,6 +56,7 @@ YR_API int yr_compiler_create( new_compiler->errors = 0; new_compiler->callback = NULL; + new_compiler->include_callback = NULL; new_compiler->last_error = ERROR_SUCCESS; new_compiler->last_error_line = 0; new_compiler->current_line = 0; @@ -182,6 +183,28 @@ YR_API void yr_compiler_set_callback( } +YR_API void yr_compiler_set_include_callback( + YR_COMPILER* compiler, + YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, + void* user_data) +{ + printf("DEBUG setting C callback\n"); + compiler->include_callback = include_callback; + if(compiler->include_callback == NULL) + printf("DEBUG C callback FAILED\n"); + else + printf("DEBUG C callback set\n"); + + printf("DEBUG setting python callback\n"); + compiler->user_data = user_data; + if(compiler->user_data == NULL) + printf("DEBUG python callback FAILED\n"); + else + printf("DEBUG python callback set\n"); + +} + + int _yr_compiler_push_file( YR_COMPILER* compiler, FILE* fh) diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h index 356380f269..93a6263cc8 100644 --- a/libyara/include/yara/compiler.h +++ b/libyara/include/yara/compiler.h @@ -52,6 +52,13 @@ typedef void (*YR_COMPILER_CALLBACK_FUNC)( void* user_data); +typedef const char* (*YR_COMPILER_INCLUDE_CALLBACK_FUNC)( + const char* include_name, + const char* calling_rule_filename, + const char* calling_rule_namespace, + void* user_data); + + typedef struct _YR_FIXUP { void* address; @@ -116,6 +123,7 @@ typedef struct _YR_COMPILER void* user_data; YR_COMPILER_CALLBACK_FUNC callback; + YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback; } YR_COMPILER; @@ -166,6 +174,12 @@ YR_API void yr_compiler_set_callback( void* user_data); +YR_API void yr_compiler_set_include_callback( + YR_COMPILER* compiler, + YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, + void* user_data); + + YR_API int yr_compiler_add_file( YR_COMPILER* compiler, FILE* rules_file, diff --git a/libyara/lexer.c b/libyara/lexer.c index 291124570e..cca5af6114 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1363,8 +1363,8 @@ YY_RULE_SETUP char *f; FILE* fh; - if (compiler->allow_includes) - { + if (compiler->allow_includes)//EDHOEDT + {//EDHOEDT *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer @@ -1378,80 +1378,107 @@ YY_RULE_SETUP { buffer[0] = '\0'; } + if (compiler->include_callback == NULL) + { + // make included file path relative to current source file + s = strrchr(buffer, '/'); - // make included file path relative to current source file - s = strrchr(buffer, '/'); - - #ifdef _WIN32 - b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted - #endif + #ifdef _WIN32 + b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted + #endif - #ifdef _WIN32 - if (s != NULL || b != NULL) - #else - if (s != NULL) - #endif - { #ifdef _WIN32 - f = (b > s)? (b + 1): (s + 1); + if (s != NULL || b != NULL) #else - f = s + 1; + if (s != NULL) #endif + { + #ifdef _WIN32 + f = (b > s)? (b + 1): (s + 1); + #else + f = s + 1; + #endif - strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); + strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); - f = buffer; + f = buffer; - // SECURITY: Potential for directory traversal here. - fh = fopen(buffer, "r"); + // SECURITY: Potential for directory traversal here. + fh = fopen(buffer, "r"); - // if include file was not found relative to current source file, - // try to open it with path as specified by user (maybe user wrote - // a full path) + // if include file was not found relative to current source file, + // try to open it with path as specified by user (maybe user wrote + // a full path) - if (fh == NULL) + if (fh == NULL) + { + f = yyextra->lex_buf; + + // SECURITY: Potential for directory traversal here. + fh = fopen(yyextra->lex_buf, "r"); + } + } + else { f = yyextra->lex_buf; // SECURITY: Potential for directory traversal here. fh = fopen(yyextra->lex_buf, "r"); } - } - else - { - f = yyextra->lex_buf; - - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); - } - - if (fh != NULL) - { - int error_code = _yr_compiler_push_file_name(compiler, f); - if (error_code != ERROR_SUCCESS) + if (fh != NULL) { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + int error_code = _yr_compiler_push_file_name(compiler, f); + + if (error_code != ERROR_SUCCESS) { - yyerror(yyscanner, compiler, "includes depth exceeded"); + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) + { + yyerror(yyscanner, compiler, "includes circular reference"); + } + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + { + yyerror(yyscanner, compiler, "includes depth exceeded"); + } + + yyterminate(); } - yyterminate(); + _yr_compiler_push_file(compiler, fh); + yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); } - - _yr_compiler_push_file(compiler, fh); - yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); - } + else + { + snprintf(buffer, sizeof(buffer), + "can't open include file: %s", yyextra->lex_buf); + yyerror(yyscanner, compiler, buffer); + } + }//EDHOEDT + //EDHOEDT vvvvvvvvvvvvvvv else { - snprintf(buffer, sizeof(buffer), - "can't open include file: %s", yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + printf("YARA SO WAS CALLED\n"); + const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); + printf("Yara.SO callback result: %s\n", res); + + /*-------- + f = yyextra->lex_buf; + fh = fopen(yyextra->lex_buf, "r"); + if (fh != NULL){ + int error_code = _yr_compiler_push_file_name(compiler, f); + if (error_code != ERROR_SUCCESS){ + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE){yyerror(yyscanner, compiler, "includes circular reference");} + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED){yyerror(yyscanner, compiler, "includes depth exceeded");} + yyterminate();} + _yr_compiler_push_file(compiler, fh); + yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); + }else{ + snprintf(buffer, sizeof(buffer), "can't open include file: %s", yyextra->lex_buf); + yyerror(yyscanner, compiler, buffer); + } + ---------*/ } + //EDHOEDT ^^^^^^^^^^^^^^^ } else // not allowing includes { @@ -1467,7 +1494,7 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 300 "lexer.l" +#line 327 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); @@ -1489,7 +1516,7 @@ case YY_STATE_EOF(comment): YY_BREAK case 44: YY_RULE_SETUP -#line 320 "lexer.l" +#line 347 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1505,7 +1532,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 334 "lexer.l" +#line 361 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1521,7 +1548,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 348 "lexer.l" +#line 375 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1538,7 +1565,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 363 "lexer.l" +#line 390 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1555,7 +1582,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 378 "lexer.l" +#line 405 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1572,7 +1599,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 393 "lexer.l" +#line 420 "lexer.l" { char* text = yytext; @@ -1613,7 +1640,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 432 "lexer.l" +#line 459 "lexer.l" { if (strlen(yytext) > 128) @@ -1634,7 +1661,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 451 "lexer.l" +#line 478 "lexer.l" { #ifdef _MSC_VER @@ -1656,7 +1683,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 470 "lexer.l" +#line 497 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1664,7 +1691,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 475 "lexer.l" +#line 502 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1672,7 +1699,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 480 "lexer.l" +#line 507 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1680,7 +1707,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 486 "lexer.l" +#line 513 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1696,7 +1723,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 500 "lexer.l" +#line 527 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1706,7 +1733,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 508 "lexer.l" +#line 535 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1716,7 +1743,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 516 "lexer.l" +#line 543 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1726,7 +1753,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 524 "lexer.l" +#line 551 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1736,7 +1763,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 532 "lexer.l" +#line 559 "lexer.l" { int result; @@ -1749,13 +1776,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 543 "lexer.l" +#line 570 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 546 "lexer.l" +#line 573 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1765,7 +1792,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 552 "lexer.l" +#line 579 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1774,7 +1801,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 559 "lexer.l" +#line 586 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1803,7 +1830,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 586 "lexer.l" +#line 613 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1813,7 +1840,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 594 "lexer.l" +#line 621 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1831,13 +1858,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 610 "lexer.l" +#line 637 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 613 "lexer.l" +#line 640 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1846,7 +1873,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 620 "lexer.l" +#line 647 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1856,7 +1883,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 628 "lexer.l" +#line 655 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1867,7 +1894,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 636 "lexer.l" +#line 663 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1883,12 +1910,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 649 "lexer.l" +#line 676 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 651 "lexer.l" +#line 678 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1904,10 +1931,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 664 "lexer.l" +#line 691 "lexer.l" ECHO; YY_BREAK -#line 1911 "lexer.c" +#line 1938 "lexer.c" case YY_END_OF_BUFFER: { @@ -3056,7 +3083,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 664 "lexer.l" +#line 691 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index 032bbd274a..40778182ca 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -196,8 +196,8 @@ include[ \t]+\" { char *f; FILE* fh; - if (compiler->allow_includes) - { + if (compiler->allow_includes)//EDHOEDT + {//EDHOEDT *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer @@ -211,81 +211,108 @@ include[ \t]+\" { { buffer[0] = '\0'; } + if (compiler->include_callback == NULL) + { + // make included file path relative to current source file + s = strrchr(buffer, '/'); - // make included file path relative to current source file - s = strrchr(buffer, '/'); - - #ifdef _WIN32 - b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted - #endif + #ifdef _WIN32 + b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted + #endif - #ifdef _WIN32 - if (s != NULL || b != NULL) - #else - if (s != NULL) - #endif - { #ifdef _WIN32 - f = (b > s)? (b + 1): (s + 1); + if (s != NULL || b != NULL) #else - f = s + 1; + if (s != NULL) #endif + { + #ifdef _WIN32 + f = (b > s)? (b + 1): (s + 1); + #else + f = s + 1; + #endif - strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); + strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); - f = buffer; + f = buffer; - // SECURITY: Potential for directory traversal here. - fh = fopen(buffer, "r"); + // SECURITY: Potential for directory traversal here. + fh = fopen(buffer, "r"); - // if include file was not found relative to current source file, - // try to open it with path as specified by user (maybe user wrote - // a full path) + // if include file was not found relative to current source file, + // try to open it with path as specified by user (maybe user wrote + // a full path) - if (fh == NULL) + if (fh == NULL) + { + f = yyextra->lex_buf; + + // SECURITY: Potential for directory traversal here. + fh = fopen(yyextra->lex_buf, "r"); + } + } + else { f = yyextra->lex_buf; // SECURITY: Potential for directory traversal here. fh = fopen(yyextra->lex_buf, "r"); } - } - else - { - f = yyextra->lex_buf; - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); - } - - if (fh != NULL) - { - int error_code = _yr_compiler_push_file_name(compiler, f); - - if (error_code != ERROR_SUCCESS) + if (fh != NULL) { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + int error_code = _yr_compiler_push_file_name(compiler, f); + + if (error_code != ERROR_SUCCESS) { - yyerror(yyscanner, compiler, "includes depth exceeded"); + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) + { + yyerror(yyscanner, compiler, "includes circular reference"); + } + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + { + yyerror(yyscanner, compiler, "includes depth exceeded"); + } + + yyterminate(); } - yyterminate(); + _yr_compiler_push_file(compiler, fh); + yypush_buffer_state( + yy_create_buffer(fh, YY_BUF_SIZE, yyscanner), yyscanner); } - - _yr_compiler_push_file(compiler, fh); - yypush_buffer_state( - yy_create_buffer(fh, YY_BUF_SIZE, yyscanner), yyscanner); - } + else + { + snprintf(buffer, sizeof(buffer), + "can't open include file: %s", yyextra->lex_buf); + yyerror(yyscanner, compiler, buffer); + } + }//EDHOEDT + //EDHOEDT vvvvvvvvvvvvvvv else { - snprintf(buffer, sizeof(buffer), - "can't open include file: %s", yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + printf("YARA SO WAS CALLED\n"); + const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); + printf("Yara.SO callback result: %s\n", res); + + /*-------- + f = yyextra->lex_buf; + fh = fopen(yyextra->lex_buf, "r"); + if (fh != NULL){ + int error_code = _yr_compiler_push_file_name(compiler, f); + if (error_code != ERROR_SUCCESS){ + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE){yyerror(yyscanner, compiler, "includes circular reference");} + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED){yyerror(yyscanner, compiler, "includes depth exceeded");} + yyterminate();} + _yr_compiler_push_file(compiler, fh); + yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); + }else{ + snprintf(buffer, sizeof(buffer), "can't open include file: %s", yyextra->lex_buf); + yyerror(yyscanner, compiler, buffer); + } + ---------*/ } + //EDHOEDT ^^^^^^^^^^^^^^^ } else // not allowing includes { From c9854654a8bdc20e63065caa5e900490b3dbdc46 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Sun, 27 Aug 2017 21:50:52 +0200 Subject: [PATCH 02/13] Importing files via external callback fully implemented and working --- libyara/compiler.c | 12 ---- libyara/lexer.c | 156 ++++++++++++++++++++++++++------------------- libyara/lexer.l | 88 ++++++++++++++++--------- 3 files changed, 148 insertions(+), 108 deletions(-) diff --git a/libyara/compiler.c b/libyara/compiler.c index 8b597befe8..a7e4ca5119 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -188,20 +188,8 @@ YR_API void yr_compiler_set_include_callback( YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, void* user_data) { - printf("DEBUG setting C callback\n"); compiler->include_callback = include_callback; - if(compiler->include_callback == NULL) - printf("DEBUG C callback FAILED\n"); - else - printf("DEBUG C callback set\n"); - - printf("DEBUG setting python callback\n"); compiler->user_data = user_data; - if(compiler->user_data == NULL) - printf("DEBUG python callback FAILED\n"); - else - printf("DEBUG python callback set\n"); - } diff --git a/libyara/lexer.c b/libyara/lexer.c index cca5af6114..92a8394fef 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1363,8 +1363,8 @@ YY_RULE_SETUP char *f; FILE* fh; - if (compiler->allow_includes)//EDHOEDT - {//EDHOEDT + if (compiler->allow_includes) + { *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer @@ -1378,8 +1378,9 @@ YY_RULE_SETUP { buffer[0] = '\0'; } - if (compiler->include_callback == NULL) - { + + if (compiler->include_callback == NULL)//EDHOEDT + {//EDHOEDT // make included file path relative to current source file s = strrchr(buffer, '/'); @@ -1453,32 +1454,43 @@ YY_RULE_SETUP "can't open include file: %s", yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } + }//EDHOEDT - //EDHOEDT vvvvvvvvvvvvvvv + //EDHOEDT vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv else { - printf("YARA SO WAS CALLED\n"); const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); - printf("Yara.SO callback result: %s\n", res); + if (res != NULL) + { + int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf); - /*-------- - f = yyextra->lex_buf; - fh = fopen(yyextra->lex_buf, "r"); - if (fh != NULL){ - int error_code = _yr_compiler_push_file_name(compiler, f); - if (error_code != ERROR_SUCCESS){ - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE){yyerror(yyscanner, compiler, "includes circular reference");} - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED){yyerror(yyscanner, compiler, "includes depth exceeded");} - yyterminate();} - _yr_compiler_push_file(compiler, fh); - yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); - }else{ - snprintf(buffer, sizeof(buffer), "can't open include file: %s", yyextra->lex_buf); + if (error_code != ERROR_SUCCESS) + { + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) + { + yyerror(yyscanner, compiler, "includes circular reference"); + } + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + { + yyerror(yyscanner, compiler, "includes depth exceeded"); + } + + yyterminate(); + } + // Workaround for flex issue: https://github.com/westes/flex/issues/58 + yara_yypush_buffer_state(YY_CURRENT_BUFFER,yyscanner); + yara_yy_scan_string(res,yyscanner); + } + else + { + snprintf(buffer, sizeof(buffer), + "'include_callback' failed to return rules contained in '%s'", yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } - ---------*/ + } - //EDHOEDT ^^^^^^^^^^^^^^^ + + //EDHOEDT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } else // not allowing includes { @@ -1494,29 +1506,43 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 327 "lexer.l" +#line 339 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); - FILE* file = _yr_compiler_pop_file(compiler); - if (file != NULL) - { - fclose(file); - } + if (compiler->include_callback == NULL)//EDHOEDT + {//EDHOEDT + FILE* file = _yr_compiler_pop_file(compiler); + + if (file != NULL) + { + fclose(file); + } - _yr_compiler_pop_file_name(compiler); - yara_yypop_buffer_state(yyscanner); + _yr_compiler_pop_file_name(compiler); + yara_yypop_buffer_state(yyscanner); - if (!YY_CURRENT_BUFFER) + if (!YY_CURRENT_BUFFER) + { + yyterminate(); + } + }//EDHOEDT + else//EDHOEDT { - yyterminate(); + _yr_compiler_pop_file_name(compiler); + yara_yypop_buffer_state(yyscanner); + + if (!YY_CURRENT_BUFFER) + { + yyterminate(); + } } } YY_BREAK case 44: YY_RULE_SETUP -#line 347 "lexer.l" +#line 373 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1532,7 +1558,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 361 "lexer.l" +#line 387 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1548,7 +1574,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 375 "lexer.l" +#line 401 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1565,7 +1591,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 390 "lexer.l" +#line 416 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1582,7 +1608,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 405 "lexer.l" +#line 431 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1599,7 +1625,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 420 "lexer.l" +#line 446 "lexer.l" { char* text = yytext; @@ -1640,7 +1666,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 459 "lexer.l" +#line 485 "lexer.l" { if (strlen(yytext) > 128) @@ -1661,7 +1687,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 478 "lexer.l" +#line 504 "lexer.l" { #ifdef _MSC_VER @@ -1683,7 +1709,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 497 "lexer.l" +#line 523 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1691,7 +1717,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 502 "lexer.l" +#line 528 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1699,7 +1725,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 507 "lexer.l" +#line 533 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1707,7 +1733,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 513 "lexer.l" +#line 539 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1723,7 +1749,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 527 "lexer.l" +#line 553 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1733,7 +1759,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 535 "lexer.l" +#line 561 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1743,7 +1769,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 543 "lexer.l" +#line 569 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1753,7 +1779,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 551 "lexer.l" +#line 577 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1763,7 +1789,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 559 "lexer.l" +#line 585 "lexer.l" { int result; @@ -1776,13 +1802,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 570 "lexer.l" +#line 596 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 573 "lexer.l" +#line 599 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1792,7 +1818,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 579 "lexer.l" +#line 605 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1801,7 +1827,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 586 "lexer.l" +#line 612 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1830,7 +1856,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 613 "lexer.l" +#line 639 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1840,7 +1866,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 621 "lexer.l" +#line 647 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1858,13 +1884,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 637 "lexer.l" +#line 663 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 640 "lexer.l" +#line 666 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1873,7 +1899,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 647 "lexer.l" +#line 673 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1883,7 +1909,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 655 "lexer.l" +#line 681 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1894,7 +1920,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 663 "lexer.l" +#line 689 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1910,12 +1936,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 676 "lexer.l" +#line 702 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 678 "lexer.l" +#line 704 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1931,10 +1957,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 691 "lexer.l" +#line 717 "lexer.l" ECHO; YY_BREAK -#line 1938 "lexer.c" +#line 1964 "lexer.c" case YY_END_OF_BUFFER: { @@ -3083,7 +3109,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 691 "lexer.l" +#line 717 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index 40778182ca..976d178b63 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -196,8 +196,8 @@ include[ \t]+\" { char *f; FILE* fh; - if (compiler->allow_includes)//EDHOEDT - {//EDHOEDT + if (compiler->allow_includes) + { *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer @@ -211,8 +211,9 @@ include[ \t]+\" { { buffer[0] = '\0'; } - if (compiler->include_callback == NULL) - { + + if (compiler->include_callback == NULL)//EDHOEDT + {//EDHOEDT // make included file path relative to current source file s = strrchr(buffer, '/'); @@ -287,32 +288,43 @@ include[ \t]+\" { "can't open include file: %s", yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } + }//EDHOEDT - //EDHOEDT vvvvvvvvvvvvvvv + //EDHOEDT vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv else { - printf("YARA SO WAS CALLED\n"); const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); - printf("Yara.SO callback result: %s\n", res); + if (res != NULL) + { + int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf); - /*-------- - f = yyextra->lex_buf; - fh = fopen(yyextra->lex_buf, "r"); - if (fh != NULL){ - int error_code = _yr_compiler_push_file_name(compiler, f); - if (error_code != ERROR_SUCCESS){ - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE){yyerror(yyscanner, compiler, "includes circular reference");} - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED){yyerror(yyscanner, compiler, "includes depth exceeded");} - yyterminate();} - _yr_compiler_push_file(compiler, fh); - yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); - }else{ - snprintf(buffer, sizeof(buffer), "can't open include file: %s", yyextra->lex_buf); + if (error_code != ERROR_SUCCESS) + { + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) + { + yyerror(yyscanner, compiler, "includes circular reference"); + } + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) + { + yyerror(yyscanner, compiler, "includes depth exceeded"); + } + + yyterminate(); + } + // Workaround for flex issue: https://github.com/westes/flex/issues/58 + yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); + yy_scan_string(res, yyscanner); + } + else + { + snprintf(buffer, sizeof(buffer), + "'include_callback' failed to return rules contained in '%s'", yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } - ---------*/ + } - //EDHOEDT ^^^^^^^^^^^^^^^ + + //EDHOEDT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } else // not allowing includes { @@ -327,19 +339,33 @@ include[ \t]+\" { <> { YR_COMPILER* compiler = yyget_extra(yyscanner); - FILE* file = _yr_compiler_pop_file(compiler); - if (file != NULL) - { - fclose(file); - } + if (compiler->include_callback == NULL)//EDHOEDT + {//EDHOEDT + FILE* file = _yr_compiler_pop_file(compiler); - _yr_compiler_pop_file_name(compiler); - yypop_buffer_state(yyscanner); + if (file != NULL) + { + fclose(file); + } + + _yr_compiler_pop_file_name(compiler); + yypop_buffer_state(yyscanner); - if (!YY_CURRENT_BUFFER) + if (!YY_CURRENT_BUFFER) + { + yyterminate(); + } + }//EDHOEDT + else//EDHOEDT { - yyterminate(); + _yr_compiler_pop_file_name(compiler); + yypop_buffer_state(yyscanner); + + if (!YY_CURRENT_BUFFER) + { + yyterminate(); + } } } From 4a3c83956565c0f05c036a0e12d085cfd93491df Mon Sep 17 00:00:00 2001 From: edhoedt Date: Mon, 28 Aug 2017 00:04:13 +0200 Subject: [PATCH 03/13] Removing useless comments --- libyara/lexer.c | 85 ++++++++++++++++++++++++------------------------- libyara/lexer.l | 17 ++++------ 2 files changed, 48 insertions(+), 54 deletions(-) diff --git a/libyara/lexer.c b/libyara/lexer.c index 92a8394fef..b5d9108b21 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1379,8 +1379,8 @@ YY_RULE_SETUP buffer[0] = '\0'; } - if (compiler->include_callback == NULL)//EDHOEDT - {//EDHOEDT + if (compiler->include_callback == NULL) + { // make included file path relative to current source file s = strrchr(buffer, '/'); @@ -1455,8 +1455,7 @@ YY_RULE_SETUP yyerror(yyscanner, compiler, buffer); } - }//EDHOEDT - //EDHOEDT vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + } else { const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); @@ -1489,8 +1488,6 @@ YY_RULE_SETUP } } - - //EDHOEDT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } else // not allowing includes { @@ -1506,13 +1503,13 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 339 "lexer.l" +#line 336 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); - if (compiler->include_callback == NULL)//EDHOEDT - {//EDHOEDT + if (compiler->include_callback == NULL) + { FILE* file = _yr_compiler_pop_file(compiler); if (file != NULL) @@ -1527,8 +1524,8 @@ case YY_STATE_EOF(comment): { yyterminate(); } - }//EDHOEDT - else//EDHOEDT + } + else { _yr_compiler_pop_file_name(compiler); yara_yypop_buffer_state(yyscanner); @@ -1542,7 +1539,7 @@ case YY_STATE_EOF(comment): YY_BREAK case 44: YY_RULE_SETUP -#line 373 "lexer.l" +#line 370 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1558,7 +1555,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 387 "lexer.l" +#line 384 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1574,7 +1571,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 401 "lexer.l" +#line 398 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1591,7 +1588,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 416 "lexer.l" +#line 413 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1608,7 +1605,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 431 "lexer.l" +#line 428 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1625,7 +1622,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 446 "lexer.l" +#line 443 "lexer.l" { char* text = yytext; @@ -1666,7 +1663,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 485 "lexer.l" +#line 482 "lexer.l" { if (strlen(yytext) > 128) @@ -1687,7 +1684,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 504 "lexer.l" +#line 501 "lexer.l" { #ifdef _MSC_VER @@ -1709,7 +1706,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 523 "lexer.l" +#line 520 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1717,7 +1714,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 528 "lexer.l" +#line 525 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1725,7 +1722,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 533 "lexer.l" +#line 530 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1733,7 +1730,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 539 "lexer.l" +#line 536 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1749,7 +1746,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 553 "lexer.l" +#line 550 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1759,7 +1756,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 561 "lexer.l" +#line 558 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1769,7 +1766,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 569 "lexer.l" +#line 566 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1779,7 +1776,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 577 "lexer.l" +#line 574 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1789,7 +1786,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 585 "lexer.l" +#line 582 "lexer.l" { int result; @@ -1802,13 +1799,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 596 "lexer.l" +#line 593 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 599 "lexer.l" +#line 596 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1818,7 +1815,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 605 "lexer.l" +#line 602 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1827,7 +1824,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 612 "lexer.l" +#line 609 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1856,7 +1853,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 639 "lexer.l" +#line 636 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1866,7 +1863,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 647 "lexer.l" +#line 644 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1884,13 +1881,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 663 "lexer.l" +#line 660 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 666 "lexer.l" +#line 663 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1899,7 +1896,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 673 "lexer.l" +#line 670 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1909,7 +1906,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 681 "lexer.l" +#line 678 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1920,7 +1917,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 689 "lexer.l" +#line 686 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1936,12 +1933,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 702 "lexer.l" +#line 699 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 704 "lexer.l" +#line 701 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1957,10 +1954,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 717 "lexer.l" +#line 714 "lexer.l" ECHO; YY_BREAK -#line 1964 "lexer.c" +#line 1961 "lexer.c" case YY_END_OF_BUFFER: { @@ -3109,7 +3106,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 717 "lexer.l" +#line 714 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index 976d178b63..d4a29d65c2 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -212,8 +212,8 @@ include[ \t]+\" { buffer[0] = '\0'; } - if (compiler->include_callback == NULL)//EDHOEDT - {//EDHOEDT + if (compiler->include_callback == NULL) + { // make included file path relative to current source file s = strrchr(buffer, '/'); @@ -289,8 +289,7 @@ include[ \t]+\" { yyerror(yyscanner, compiler, buffer); } - }//EDHOEDT - //EDHOEDT vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + } else { const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); @@ -323,8 +322,6 @@ include[ \t]+\" { } } - - //EDHOEDT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } else // not allowing includes { @@ -340,8 +337,8 @@ include[ \t]+\" { YR_COMPILER* compiler = yyget_extra(yyscanner); - if (compiler->include_callback == NULL)//EDHOEDT - {//EDHOEDT + if (compiler->include_callback == NULL) + { FILE* file = _yr_compiler_pop_file(compiler); if (file != NULL) @@ -356,8 +353,8 @@ include[ \t]+\" { { yyterminate(); } - }//EDHOEDT - else//EDHOEDT + } + else { _yr_compiler_pop_file_name(compiler); yypop_buffer_state(yyscanner); From 99391a321af309054b100f41e7ba6f6d4960ca87 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Mon, 28 Aug 2017 12:04:18 +0200 Subject: [PATCH 04/13] Adding documentation --- docs/capi.rst | 20 ++++++++++++++++++++ docs/yarapython.rst | 30 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/docs/capi.rst b/docs/capi.rst index 8eca9a1286..cd4e98dbee 100644 --- a/docs/capi.rst +++ b/docs/capi.rst @@ -63,6 +63,26 @@ contains the file name and line number where the error or warning occurs. you're using :c:func:`yr_compiler_add_string`. The ``user_data`` pointer is the same you passed to :c:func:`yr_compiler_set_callback`. +By default, for rules containing references to other files +(``include "filename.yara"``), yara will try to find those files on disk. +However, if you want to fetch the imported rules from another source (eg: from a +database or remote service), a callback function can be set with +:c:func:`yr_compiler_set_include_callback`. + The callback receives the following parameters: + ``include_name``: name of the requested file. + ``calling_rule_filename``: the requesting file name (NULL if not a file). + ``calling_rule_namespace``: namespace (NULL if undefined). + And should return the requested file as a string. +The callback function has the following prototype: + +.. code-block:: c + + const char* callback_function( + const char* include_name, + const char* calling_rule_filename, + const char* calling_rule_namespace, + void* user_data); + After you successfully added some sources you can get the compiled rules using the :c:func:`yr_compiler_get_rules()` function. You'll get a pointer to a :c:type:`YR_RULES` structure which can be used to scan your data as diff --git a/docs/yarapython.rst b/docs/yarapython.rst index 81b57aad08..da4a78daae 100644 --- a/docs/yarapython.rst +++ b/docs/yarapython.rst @@ -74,6 +74,36 @@ should be accepted in the source files, for example: If the source file contains include directives the previous line would raise an exception. +If includes are used, a python callback can be set to define a custom source for +the imported files (by default they are read from disk). This callback function +is set through the ``include_callback`` optional parameter. +It receives the following parameters: + ``requested_filename``: file requested with 'include' + ``filename``: file containing the 'include' directive if applicable, else None + ``namespace``: namespace +And returns the requested rules sources as a single string. + +.. code-block:: python + import yara + import sys + if sys.version_info >= (3, 0): + import urllib.request as urllib + else: + import urllib as urllib + + def mycallback(requested_filename, filename, namespace): + if requested_filename == 'req.yara': + uf = urllib.urlopen('https://pastebin.com/raw/siZ2sMTM') + sources = uf.read() + if sys.version_info >= (3, 0): + sources = str(sources, 'utf-8') + return sources + else: + raise Exception(filename+": Can't fetch "+requested_filename) + + rules = yara.compile(source='include "req.yara" rule r{ condition: true }', + include_callback=mycallback) + If you are using external variables in your rules you must define those external variables either while compiling the rules, or while applying the rules to some file. To define your variables at the moment of compilation you From df2c1df9fc19584b8839a0661f8b5b688178f591 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Mon, 28 Aug 2017 12:22:55 +0200 Subject: [PATCH 05/13] Updating doc for include callbacks --- docs/capi.rst | 19 +++++++++++++------ docs/yarapython.rst | 6 +++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/capi.rst b/docs/capi.rst index cd4e98dbee..08d8a1c2ef 100644 --- a/docs/capi.rst +++ b/docs/capi.rst @@ -68,16 +68,17 @@ By default, for rules containing references to other files However, if you want to fetch the imported rules from another source (eg: from a database or remote service), a callback function can be set with :c:func:`yr_compiler_set_include_callback`. - The callback receives the following parameters: - ``include_name``: name of the requested file. - ``calling_rule_filename``: the requesting file name (NULL if not a file). - ``calling_rule_namespace``: namespace (NULL if undefined). - And should return the requested file as a string. +The callback receives the following parameters: + *``include_name``: name of the requested file. + *``calling_rule_filename``: the requesting file name (NULL if not a file). + *``calling_rule_namespace``: namespace (NULL if undefined). +And should return the requested file as a string. + The callback function has the following prototype: .. code-block:: c - const char* callback_function( + const char* include_callback( const char* include_name, const char* calling_rule_filename, const char* calling_rule_namespace, @@ -422,6 +423,12 @@ Functions pointer is passed to the callback function. +.. c:function:: const char* yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, void* user_data) + + Set a callback to provide rules from a custom source when ``include`` directive + is invoked. The *user_data* pointer is passed to the callback function. + + .. c:function:: int yr_compiler_add_file(YR_COMPILER* compiler, FILE* file, const char* namespace, const char* file_name) Compile rules from a *file*. Rules are put into the specified *namespace*, diff --git a/docs/yarapython.rst b/docs/yarapython.rst index da4a78daae..3a586814d8 100644 --- a/docs/yarapython.rst +++ b/docs/yarapython.rst @@ -78,9 +78,9 @@ If includes are used, a python callback can be set to define a custom source for the imported files (by default they are read from disk). This callback function is set through the ``include_callback`` optional parameter. It receives the following parameters: - ``requested_filename``: file requested with 'include' - ``filename``: file containing the 'include' directive if applicable, else None - ``namespace``: namespace + *``requested_filename``: file requested with 'include' + *``filename``: file containing the 'include' directive if applicable, else None + *``namespace``: namespace And returns the requested rules sources as a single string. .. code-block:: python From dc2d3fa33b572ca79831551fddfebd0d4dba8d79 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Mon, 28 Aug 2017 12:36:44 +0200 Subject: [PATCH 06/13] Fixing compiler_set_include_callback's signature --- docs/capi.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/capi.rst b/docs/capi.rst index 08d8a1c2ef..104262bde1 100644 --- a/docs/capi.rst +++ b/docs/capi.rst @@ -423,7 +423,7 @@ Functions pointer is passed to the callback function. -.. c:function:: const char* yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, void* user_data) +.. c:function:: void yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, void* user_data) Set a callback to provide rules from a custom source when ``include`` directive is invoked. The *user_data* pointer is passed to the callback function. From e98f434c586d0fb5d42a559aa8d2f2b022e023a2 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Thu, 31 Aug 2017 15:23:08 +0200 Subject: [PATCH 07/13] Fixing issues according to @plusvic 's advice * Limited lines to 80 chars * include callback is now using its own user_data and does not conflict with other callbacks * Copying include callback result to the stack before pushing it into the flex scanner * yara's memory management functions are now exposed through the API * Making the lexer reponsible for freeing the memory allocated by the include callback * Updating docs accordingly --- docs/capi.rst | 37 +++++++++++-- libyara/compiler.c | 2 +- libyara/include/yara.h | 1 + libyara/include/yara/compiler.h | 1 + libyara/include/yara/mem.h | 13 ++--- libyara/lexer.c | 96 +++++++++++++++++++-------------- libyara/lexer.l | 28 ++++++++-- libyara/mem.c | 26 ++++----- 8 files changed, 136 insertions(+), 68 deletions(-) diff --git a/docs/capi.rst b/docs/capi.rst index 104262bde1..245bcca862 100644 --- a/docs/capi.rst +++ b/docs/capi.rst @@ -69,10 +69,14 @@ However, if you want to fetch the imported rules from another source (eg: from a database or remote service), a callback function can be set with :c:func:`yr_compiler_set_include_callback`. The callback receives the following parameters: - *``include_name``: name of the requested file. - *``calling_rule_filename``: the requesting file name (NULL if not a file). - *``calling_rule_namespace``: namespace (NULL if undefined). -And should return the requested file as a string. + * ``include_name``: name of the requested file. + * ``calling_rule_filename``: the requesting file name (NULL if not a file). + * ``calling_rule_namespace``: namespace (NULL if undefined). + * ``user_data`` pointer is the same you passed to + :c:func:`yr_compiler_set_include_callback`. +It should return the requested file's content as a string. The memory for this string +should be allocated by the callback function (yr_malloc can be used) but will +be automatically freed by the yara compiler. The callback function has the following prototype: @@ -695,6 +699,31 @@ Functions Enables the specified rule. After being disabled with :c:func:`yr_rule_disable` a rule can be enabled again by using this function. +.. c:function:: void* yr_calloc(size_t count, size_t size); + + Cross-platform wrapper for HeapAlloc on Windows and calloc on other platforms. + +.. c:function:: void* yr_malloc(size_t size); + + Cross-platform wrapper for HeapAlloc on Windows and malloc on other platforms. + +.. c:function:: void* yr_realloc(void* ptr, size_t size); + + Cross-platform wrapper for HeapReAlloc on Windows and realloc on other platforms. + +.. c:function:: void yr_free(void* ptr); + + Cross-platform wrapper for HeapFree on Windows and free on other platforms. + +.. c:function:: char* yr_strdup(const char *str); + + Allocates a new buffer the same size as str and copies str to the new buffer. + +.. c:function:: char* yr_strdup(const char *str, size_t n); + + Allocates a new buffer of size n and copies the n first character of str. + + Error codes ----------- diff --git a/libyara/compiler.c b/libyara/compiler.c index a7e4ca5119..f405ec3574 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -189,7 +189,7 @@ YR_API void yr_compiler_set_include_callback( void* user_data) { compiler->include_callback = include_callback; - compiler->user_data = user_data; + compiler->incl_clbk_user_data = user_data; } diff --git a/libyara/include/yara.h b/libyara/include/yara.h index 3a35518663..a627e90bf9 100644 --- a/libyara/include/yara.h +++ b/libyara/include/yara.h @@ -39,5 +39,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "yara/error.h" #include "yara/stream.h" #include "yara/hash.h" +#include "yara/mem.h" #endif diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h index 93a6263cc8..5302442311 100644 --- a/libyara/include/yara/compiler.h +++ b/libyara/include/yara/compiler.h @@ -121,6 +121,7 @@ typedef struct _YR_COMPILER char include_base_dir[MAX_PATH]; void* user_data; + void* incl_clbk_user_data; YR_COMPILER_CALLBACK_FUNC callback; YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback; diff --git a/libyara/include/yara/mem.h b/libyara/include/yara/mem.h index ff7dc3ec7e..a556fcb583 100644 --- a/libyara/include/yara/mem.h +++ b/libyara/include/yara/mem.h @@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define YR_MEM_H #include +#include #ifdef DMALLOC @@ -45,24 +46,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #else -void* yr_calloc( +YR_API void* yr_calloc( size_t count, size_t size); -void* yr_malloc( +YR_API void* yr_malloc( size_t size); -void* yr_realloc( +YR_API void* yr_realloc( void* ptr, size_t size); -void yr_free( +YR_API void yr_free( void *ptr); -char* yr_strdup( +YR_API char* yr_strdup( const char *str); -char* yr_strndup( +YR_API char* yr_strndup( const char *str, size_t n); #endif diff --git a/libyara/lexer.c b/libyara/lexer.c index b5d9108b21..68fd25b268 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1458,10 +1458,20 @@ YY_RULE_SETUP } else { - const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); + const char* res = compiler->include_callback( + yyextra->lex_buf, + current_file_name, + compiler->current_namespace->name, + compiler->incl_clbk_user_data); + if (res != NULL) { - int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf); + const char* res_dup = yr_strdup(res); + yr_free((void*) res); + res = NULL; + + int error_code = _yr_compiler_push_file_name( compiler, + yyextra->lex_buf); if (error_code != ERROR_SUCCESS) { @@ -1474,16 +1484,24 @@ YY_RULE_SETUP yyerror(yyscanner, compiler, "includes depth exceeded"); } + yr_free((void*) res_dup); + res_dup = NULL; yyterminate(); } + // Workaround for flex issue: https://github.com/westes/flex/issues/58 yara_yypush_buffer_state(YY_CURRENT_BUFFER,yyscanner); - yara_yy_scan_string(res,yyscanner); + yara_yy_scan_string(res_dup,yyscanner); + + yr_free((void*) res_dup); + res_dup = NULL; } else { - snprintf(buffer, sizeof(buffer), - "'include_callback' failed to return rules contained in '%s'", yyextra->lex_buf); + snprintf( buffer, + sizeof(buffer), + "'include_callback' failed to return rules contained in '%s'", + yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } @@ -1503,7 +1521,7 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 336 "lexer.l" +#line 354 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); @@ -1539,7 +1557,7 @@ case YY_STATE_EOF(comment): YY_BREAK case 44: YY_RULE_SETUP -#line 370 "lexer.l" +#line 388 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1555,7 +1573,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 384 "lexer.l" +#line 402 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1571,7 +1589,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 398 "lexer.l" +#line 416 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1588,7 +1606,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 413 "lexer.l" +#line 431 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1605,7 +1623,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 428 "lexer.l" +#line 446 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1622,7 +1640,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 443 "lexer.l" +#line 461 "lexer.l" { char* text = yytext; @@ -1663,7 +1681,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 482 "lexer.l" +#line 500 "lexer.l" { if (strlen(yytext) > 128) @@ -1684,7 +1702,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 501 "lexer.l" +#line 519 "lexer.l" { #ifdef _MSC_VER @@ -1706,7 +1724,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 520 "lexer.l" +#line 538 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1714,7 +1732,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 525 "lexer.l" +#line 543 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1722,7 +1740,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 530 "lexer.l" +#line 548 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1730,7 +1748,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 536 "lexer.l" +#line 554 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1746,7 +1764,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 550 "lexer.l" +#line 568 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1756,7 +1774,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 558 "lexer.l" +#line 576 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1766,7 +1784,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 566 "lexer.l" +#line 584 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1776,7 +1794,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 574 "lexer.l" +#line 592 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1786,7 +1804,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 582 "lexer.l" +#line 600 "lexer.l" { int result; @@ -1799,13 +1817,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 593 "lexer.l" +#line 611 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 596 "lexer.l" +#line 614 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1815,7 +1833,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 602 "lexer.l" +#line 620 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1824,7 +1842,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 609 "lexer.l" +#line 627 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1853,7 +1871,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 636 "lexer.l" +#line 654 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1863,7 +1881,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 644 "lexer.l" +#line 662 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1881,13 +1899,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 660 "lexer.l" +#line 678 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 663 "lexer.l" +#line 681 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1896,7 +1914,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 670 "lexer.l" +#line 688 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1906,7 +1924,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 678 "lexer.l" +#line 696 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1917,7 +1935,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 686 "lexer.l" +#line 704 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1933,12 +1951,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 699 "lexer.l" +#line 717 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 701 "lexer.l" +#line 719 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1954,10 +1972,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 714 "lexer.l" +#line 732 "lexer.l" ECHO; YY_BREAK -#line 1961 "lexer.c" +#line 1979 "lexer.c" case YY_END_OF_BUFFER: { @@ -3106,7 +3124,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 714 "lexer.l" +#line 732 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index d4a29d65c2..84830f7453 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -292,10 +292,20 @@ include[ \t]+\" { } else { - const char* res = compiler->include_callback(yyextra->lex_buf, current_file_name, compiler->current_namespace->name, compiler->user_data); + const char* res = compiler->include_callback( + yyextra->lex_buf, + current_file_name, + compiler->current_namespace->name, + compiler->incl_clbk_user_data); + if (res != NULL) { - int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf); + const char* res_dup = yr_strdup(res); + yr_free((void*) res); + res = NULL; + + int error_code = _yr_compiler_push_file_name( compiler, + yyextra->lex_buf); if (error_code != ERROR_SUCCESS) { @@ -308,16 +318,24 @@ include[ \t]+\" { yyerror(yyscanner, compiler, "includes depth exceeded"); } + yr_free((void*) res_dup); + res_dup = NULL; yyterminate(); } + // Workaround for flex issue: https://github.com/westes/flex/issues/58 yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); - yy_scan_string(res, yyscanner); + yy_scan_string(res_dup, yyscanner); + + yr_free((void*) res_dup); + res_dup = NULL; } else { - snprintf(buffer, sizeof(buffer), - "'include_callback' failed to return rules contained in '%s'", yyextra->lex_buf); + snprintf( buffer, + sizeof(buffer), + "'include_callback' failed to return rules contained in '%s'", + yyextra->lex_buf); yyerror(yyscanner, compiler, buffer); } diff --git a/libyara/mem.c b/libyara/mem.c index 53a151fe69..55b0d8acca 100644 --- a/libyara/mem.c +++ b/libyara/mem.c @@ -27,7 +27,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#include #if defined(_WIN32) || defined(__CYGWIN__) @@ -58,31 +58,31 @@ int yr_heap_free(void) } -void* yr_calloc(size_t count, size_t size) +YR_API void* yr_calloc(size_t count, size_t size) { return (void*) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, count * size); } -void* yr_malloc(size_t size) +YR_API void* yr_malloc(size_t size) { return (void*) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size); } -void* yr_realloc(void* ptr, size_t size) +YR_API void* yr_realloc(void* ptr, size_t size) { return (void*) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, ptr, size); } -void yr_free(void* ptr) +YR_API void yr_free(void* ptr) { HeapFree(hHeap, 0, ptr); } -char* yr_strdup(const char *str) +YR_API char* yr_strdup(const char *str) { size_t len = strlen(str); char *dup = (char*) yr_malloc(len + 1); @@ -97,7 +97,7 @@ char* yr_strdup(const char *str) } -char* yr_strndup(const char *str, size_t n) +YR_API char* yr_strndup(const char *str, size_t n) { size_t len = strnlen(str, n); char *dup = (char*) yr_malloc(len + 1); @@ -133,37 +133,37 @@ int yr_heap_free(void) } -void* yr_calloc(size_t count, size_t size) +YR_API void* yr_calloc(size_t count, size_t size) { return calloc(count, size); } -void* yr_malloc(size_t size) +YR_API void* yr_malloc(size_t size) { return malloc(size); } -void* yr_realloc(void* ptr, size_t size) +YR_API void* yr_realloc(void* ptr, size_t size) { return realloc(ptr, size); } -void yr_free(void *ptr) +YR_API void yr_free(void *ptr) { free(ptr); } -char* yr_strdup(const char *str) +YR_API char* yr_strdup(const char *str) { return strdup(str); } -char* yr_strndup(const char *str, size_t n) +YR_API char* yr_strndup(const char *str, size_t n) { return strndup(str, n); } From 92877db48e408126ce0631b85c03d47899ea5623 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Tue, 5 Sep 2017 15:32:28 +0200 Subject: [PATCH 08/13] * fixing memory management issues in callbacks * adding a callback to allow external code to free the memory used to return the include callback's result * API: un-exposing yara's memory management functions * making include callbacks the only way ton include files * adding a default include callback to open files from the disk (mimicking original behavior) * updating docs accordingly --- docs/capi.rst | 52 +++---- libyara/compiler.c | 126 +++++++++++---- libyara/include/yara/compiler.h | 27 ++-- libyara/include/yara/mem.h | 12 +- libyara/lexer.c | 262 ++++++++++---------------------- libyara/lexer.l | 195 ++++++------------------ libyara/mem.c | 24 +-- 7 files changed, 273 insertions(+), 425 deletions(-) diff --git a/docs/capi.rst b/docs/capi.rst index 245bcca862..79094ec08a 100644 --- a/docs/capi.rst +++ b/docs/capi.rst @@ -72,11 +72,12 @@ The callback receives the following parameters: * ``include_name``: name of the requested file. * ``calling_rule_filename``: the requesting file name (NULL if not a file). * ``calling_rule_namespace``: namespace (NULL if undefined). - * ``user_data`` pointer is the same you passed to - :c:func:`yr_compiler_set_include_callback`. -It should return the requested file's content as a string. The memory for this string -should be allocated by the callback function (yr_malloc can be used) but will -be automatically freed by the yara compiler. + * ``user_data`` pointer is the same you passed to :c:func:`yr_compiler_set_include_callback`. +It should return the requested file's content as a string. The memory for this +string should be allocated by the callback function. Once it is safe to free the +memory used to return the callback's result, the include_free function passed to +:c:func:`yr_compiler_set_include_callback` will be called. If the memory does +not need to be freed, NULL can be passed as include_free instead. The callback function has the following prototype: @@ -88,6 +89,14 @@ The callback function has the following prototype: const char* calling_rule_namespace, void* user_data); +The free function has the following prototype: + +.. code-block:: c + + void include_free( + const char* callback_result_ptr, + void* user_data); + After you successfully added some sources you can get the compiled rules using the :c:func:`yr_compiler_get_rules()` function. You'll get a pointer to a :c:type:`YR_RULES` structure which can be used to scan your data as @@ -427,10 +436,13 @@ Functions pointer is passed to the callback function. -.. c:function:: void yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, void* user_data) +.. c:function:: void yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, YR_COMPILER_INCLUDE_FREE_FUNC include_free, void* user_data) - Set a callback to provide rules from a custom source when ``include`` directive - is invoked. The *user_data* pointer is passed to the callback function. + Set a callback to provide rules from a custom source when ``include`` + directive is invoked. The *user_data* pointer is untouched and passed back to + the callback function and to the free function. Once the callback's result + is no longer needed, the include_free function will be called. If the memory + does not need to be freed, include_free can be set to NULL. .. c:function:: int yr_compiler_add_file(YR_COMPILER* compiler, FILE* file, const char* namespace, const char* file_name) @@ -699,30 +711,6 @@ Functions Enables the specified rule. After being disabled with :c:func:`yr_rule_disable` a rule can be enabled again by using this function. -.. c:function:: void* yr_calloc(size_t count, size_t size); - - Cross-platform wrapper for HeapAlloc on Windows and calloc on other platforms. - -.. c:function:: void* yr_malloc(size_t size); - - Cross-platform wrapper for HeapAlloc on Windows and malloc on other platforms. - -.. c:function:: void* yr_realloc(void* ptr, size_t size); - - Cross-platform wrapper for HeapReAlloc on Windows and realloc on other platforms. - -.. c:function:: void yr_free(void* ptr); - - Cross-platform wrapper for HeapFree on Windows and free on other platforms. - -.. c:function:: char* yr_strdup(const char *str); - - Allocates a new buffer the same size as str and copies str to the new buffer. - -.. c:function:: char* yr_strdup(const char *str, size_t n); - - Allocates a new buffer of size n and copies the n first character of str. - Error codes ----------- diff --git a/libyara/compiler.c b/libyara/compiler.c index f405ec3574..179cb48574 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -56,12 +56,12 @@ YR_API int yr_compiler_create( new_compiler->errors = 0; new_compiler->callback = NULL; - new_compiler->include_callback = NULL; + new_compiler->include_callback = _yr_compiler_default_include_callback; + new_compiler->include_free = _yr_compiler_default_include_free; new_compiler->last_error = ERROR_SUCCESS; new_compiler->last_error_line = 0; new_compiler->current_line = 0; new_compiler->last_result = ERROR_SUCCESS; - new_compiler->file_stack_ptr = 0; new_compiler->file_name_stack_ptr = 0; new_compiler->fixup_stack_head = NULL; new_compiler->allow_includes = 1; @@ -183,48 +183,116 @@ YR_API void yr_compiler_set_callback( } -YR_API void yr_compiler_set_include_callback( - YR_COMPILER* compiler, - YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, - void* user_data) +const char* _yr_compiler_default_include_callback( + const char* include_name, + const char* calling_rule_filename, + const char* calling_rule_namespace, + void* user_data) { - compiler->include_callback = include_callback; - compiler->incl_clbk_user_data = user_data; -} - - -int _yr_compiler_push_file( - YR_COMPILER* compiler, - FILE* fh) -{ - if (compiler->file_stack_ptr < MAX_INCLUDE_DEPTH) + char* buffer; + //char buffer[1024]; + char* s = NULL; + #ifdef _WIN32 + char* b = NULL; + #endif + char* f; + FILE* fh; + char* file_buffer; + size_t file_length; + + if(calling_rule_filename != NULL) { - compiler->file_stack[compiler->file_stack_ptr] = fh; - compiler->file_stack_ptr++; - return ERROR_SUCCESS; + buffer = (char*) calling_rule_filename; + //strlcpy(buffer, calling_rule_filename, sizeof(buffer)); } else { - compiler->last_result = ERROR_INCLUDE_DEPTH_EXCEEDED; - return ERROR_INCLUDE_DEPTH_EXCEEDED; + buffer = "\0"; + //buffer[0] = '\0'; + } + // make included file path relative to current source file + s = strrchr(buffer, '/'); + + #ifdef _WIN32 + b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted + #endif + #ifdef _WIN32 + if (s != NULL || b != NULL) + #else + if (s != NULL) + #endif + { + #ifdef _WIN32 + f = (b > s)? (b + 1): (s + 1); + #else + f = s + 1; + #endif + strlcpy(f, include_name, sizeof(buffer) - (f - buffer)); + f = buffer; + // SECURITY: Potential for directory traversal here. + fh = fopen(buffer, "r"); + // if include file was not found relative to current source file, + // try to open it with path as specified by user (maybe user wrote + // a full path) + if (fh == NULL) + { + f = (char*) include_name; + // SECURITY: Potential for directory traversal here. + fh = fopen(include_name, "r"); + } + } + else + { + f = (char*) include_name; + // SECURITY: Potential for directory traversal here. + fh = fopen(include_name, "r"); + } + if (fh != NULL) + { + file_buffer = NULL; + file_length = 0; + + fseek(fh, 0, SEEK_END); + file_length = ftell(fh); + fseek(fh, 0, SEEK_SET); + file_buffer = (char*) yr_malloc((file_length+1)*sizeof(char)); + if(file_buffer) + { + if(file_length != fread(file_buffer, sizeof(char), file_length, fh)) + { + return NULL; + } + } + fclose(fh); + return file_buffer; } + else return NULL; } -FILE* _yr_compiler_pop_file( - YR_COMPILER* compiler) +void _yr_compiler_default_include_free( + const char* callback_result_ptr, + void* user_data) { - FILE* result = NULL; - - if (compiler->file_stack_ptr > 0) + if(callback_result_ptr != NULL) { - compiler->file_stack_ptr--; - result = compiler->file_stack[compiler->file_stack_ptr]; + yr_free((void*)callback_result_ptr); } +} - return result; + +YR_API void yr_compiler_set_include_callback( + YR_COMPILER* compiler, + YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, + YR_COMPILER_INCLUDE_FREE_FUNC include_free, + void* user_data) +{ + compiler->include_callback = include_callback; + compiler->include_free = include_free; + compiler->incl_clbk_user_data = user_data; } + int _yr_compiler_push_file_name( YR_COMPILER* compiler, const char* file_name) diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h index 5302442311..2b2df0a900 100644 --- a/libyara/include/yara/compiler.h +++ b/libyara/include/yara/compiler.h @@ -58,6 +58,10 @@ typedef const char* (*YR_COMPILER_INCLUDE_CALLBACK_FUNC)( const char* calling_rule_namespace, void* user_data); +typedef void (*YR_COMPILER_INCLUDE_FREE_FUNC)( + const char* callback_result_ptr, + void* user_data ); + typedef struct _YR_FIXUP { @@ -110,9 +114,6 @@ typedef struct _YR_COMPILER char* file_name_stack[MAX_INCLUDE_DEPTH]; int file_name_stack_ptr; - FILE* file_stack[MAX_INCLUDE_DEPTH]; - int file_stack_ptr; - char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO]; char lex_buf[LEX_BUF_SIZE]; @@ -125,6 +126,8 @@ typedef struct _YR_COMPILER YR_COMPILER_CALLBACK_FUNC callback; YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback; + YR_COMPILER_INCLUDE_FREE_FUNC include_free; + } YR_COMPILER; @@ -143,14 +146,6 @@ typedef struct _YR_COMPILER fmt, __VA_ARGS__); -int _yr_compiler_push_file( - YR_COMPILER* compiler, - FILE* fh); - - -FILE* _yr_compiler_pop_file( - YR_COMPILER* compiler); - int _yr_compiler_push_file_name( YR_COMPILER* compiler, @@ -160,6 +155,15 @@ int _yr_compiler_push_file_name( void _yr_compiler_pop_file_name( YR_COMPILER* compiler); +const char* _yr_compiler_default_include_callback( + const char* include_name, + const char* calling_rule_filename, + const char* calling_rule_namespace, + void* user_data); + +void _yr_compiler_default_include_free( + const char* callback_result_ptr, + void* user_data); YR_API int yr_compiler_create( YR_COMPILER** compiler); @@ -178,6 +182,7 @@ YR_API void yr_compiler_set_callback( YR_API void yr_compiler_set_include_callback( YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback, + YR_COMPILER_INCLUDE_FREE_FUNC include_free, void* user_data); diff --git a/libyara/include/yara/mem.h b/libyara/include/yara/mem.h index a556fcb583..b18d2a68a5 100644 --- a/libyara/include/yara/mem.h +++ b/libyara/include/yara/mem.h @@ -46,24 +46,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #else -YR_API void* yr_calloc( +void* yr_calloc( size_t count, size_t size); -YR_API void* yr_malloc( +void* yr_malloc( size_t size); -YR_API void* yr_realloc( +void* yr_realloc( void* ptr, size_t size); -YR_API void yr_free( +void yr_free( void *ptr); -YR_API char* yr_strdup( +char* yr_strdup( const char *str); -YR_API char* yr_strndup( +char* yr_strndup( const char *str, size_t n); #endif diff --git a/libyara/lexer.c b/libyara/lexer.c index 68fd25b268..d0017d7680 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1354,158 +1354,71 @@ YY_RULE_SETUP #line 188 "lexer.l" { - char buffer[1024]; - char *current_file_name; - char *s = NULL; - #ifdef _WIN32 - char *b = NULL; - #endif - char *f; - FILE* fh; - if (compiler->allow_includes) { *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer - current_file_name = yr_compiler_get_current_file_name(compiler); + char* current_file_name = yr_compiler_get_current_file_name( + compiler); - if (current_file_name != NULL) - { - strlcpy(buffer, current_file_name, sizeof(buffer)); - } - else - { - buffer[0] = '\0'; - } + const char* res = compiler->include_callback( + yyextra->lex_buf, + current_file_name, + compiler->current_namespace->name, + compiler->incl_clbk_user_data); - if (compiler->include_callback == NULL) + if (res != NULL) { - // make included file path relative to current source file - s = strrchr(buffer, '/'); - - #ifdef _WIN32 - b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted - #endif - - #ifdef _WIN32 - if (s != NULL || b != NULL) - #else - if (s != NULL) - #endif - { - #ifdef _WIN32 - f = (b > s)? (b + 1): (s + 1); - #else - f = s + 1; - #endif - - strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); - - f = buffer; - - // SECURITY: Potential for directory traversal here. - fh = fopen(buffer, "r"); - // if include file was not found relative to current source file, - // try to open it with path as specified by user (maybe user wrote - // a full path) + int error_code = _yr_compiler_push_file_name( compiler, + yyextra->lex_buf); - if (fh == NULL) + if (error_code != ERROR_SUCCESS) + { + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) { - f = yyextra->lex_buf; - - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); + yyerror(yyscanner, compiler, "includes circular reference"); } - } - else - { - f = yyextra->lex_buf; - - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); - } - - if (fh != NULL) - { - int error_code = _yr_compiler_push_file_name(compiler, f); - - if (error_code != ERROR_SUCCESS) + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) - { - yyerror(yyscanner, compiler, "includes depth exceeded"); - } - - yyterminate(); + yyerror(yyscanner, compiler, "includes depth exceeded"); } - - _yr_compiler_push_file(compiler, fh); - yara_yypush_buffer_state(yara_yy_create_buffer(fh,YY_BUF_SIZE,yyscanner),yyscanner); + if(compiler->include_free != NULL) + { + compiler->include_free(res, compiler->incl_clbk_user_data); + } + yyterminate(); } - else + + // Workaround for flex issue: https://github.com/westes/flex/issues/58 + yara_yypush_buffer_state(YY_CURRENT_BUFFER,yyscanner); + yara_yy_scan_string(res,yyscanner); + if(compiler->include_free != NULL) { - snprintf(buffer, sizeof(buffer), - "can't open include file: %s", yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + compiler->include_free(res, compiler->incl_clbk_user_data); } - } else { - const char* res = compiler->include_callback( - yyextra->lex_buf, - current_file_name, - compiler->current_namespace->name, - compiler->incl_clbk_user_data); - - if (res != NULL) + char* base_err_msg = NULL; + if(compiler->include_callback == _yr_compiler_default_include_callback) { - const char* res_dup = yr_strdup(res); - yr_free((void*) res); - res = NULL; - - int error_code = _yr_compiler_push_file_name( compiler, - yyextra->lex_buf); - - if (error_code != ERROR_SUCCESS) - { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) - { - yyerror(yyscanner, compiler, "includes depth exceeded"); - } - - yr_free((void*) res_dup); - res_dup = NULL; - yyterminate(); - } - - // Workaround for flex issue: https://github.com/westes/flex/issues/58 - yara_yypush_buffer_state(YY_CURRENT_BUFFER,yyscanner); - yara_yy_scan_string(res_dup,yyscanner); - - yr_free((void*) res_dup); - res_dup = NULL; + base_err_msg = "can't open include file: %s"; } else { - snprintf( buffer, - sizeof(buffer), - "'include_callback' failed to return rules contained in '%s'", - yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + base_err_msg = "callback failed to provide include resource: %s"; } - + size_t err_buff_len = sizeof(base_err_msg) + sizeof(yyextra->lex_buf); + char* error_buffer = yr_malloc(err_buff_len); + snprintf( error_buffer, + err_buff_len, + base_err_msg, + yyextra->lex_buf); + yyerror(yyscanner, compiler, error_buffer); } + } else // not allowing includes { @@ -1521,43 +1434,24 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 354 "lexer.l" +#line 266 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); - if (compiler->include_callback == NULL) - { - FILE* file = _yr_compiler_pop_file(compiler); - - if (file != NULL) - { - fclose(file); - } - - _yr_compiler_pop_file_name(compiler); - yara_yypop_buffer_state(yyscanner); + _yr_compiler_pop_file_name(compiler); + yara_yypop_buffer_state(yyscanner); - if (!YY_CURRENT_BUFFER) - { - yyterminate(); - } - } - else + if (!YY_CURRENT_BUFFER) { - _yr_compiler_pop_file_name(compiler); - yara_yypop_buffer_state(yyscanner); - - if (!YY_CURRENT_BUFFER) - { - yyterminate(); - } + yyterminate(); } + } YY_BREAK case 44: YY_RULE_SETUP -#line 388 "lexer.l" +#line 281 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1573,7 +1467,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 402 "lexer.l" +#line 295 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1589,7 +1483,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 416 "lexer.l" +#line 309 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1606,7 +1500,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 431 "lexer.l" +#line 324 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1623,7 +1517,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 446 "lexer.l" +#line 339 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1640,7 +1534,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 461 "lexer.l" +#line 354 "lexer.l" { char* text = yytext; @@ -1681,7 +1575,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 500 "lexer.l" +#line 393 "lexer.l" { if (strlen(yytext) > 128) @@ -1702,7 +1596,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 519 "lexer.l" +#line 412 "lexer.l" { #ifdef _MSC_VER @@ -1724,7 +1618,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 538 "lexer.l" +#line 431 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1732,7 +1626,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 543 "lexer.l" +#line 436 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1740,7 +1634,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 548 "lexer.l" +#line 441 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1748,7 +1642,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 554 "lexer.l" +#line 447 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1764,7 +1658,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 568 "lexer.l" +#line 461 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1774,7 +1668,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 576 "lexer.l" +#line 469 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1784,7 +1678,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 584 "lexer.l" +#line 477 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1794,7 +1688,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 592 "lexer.l" +#line 485 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1804,7 +1698,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 600 "lexer.l" +#line 493 "lexer.l" { int result; @@ -1817,13 +1711,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 611 "lexer.l" +#line 504 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 614 "lexer.l" +#line 507 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1833,7 +1727,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 620 "lexer.l" +#line 513 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1842,7 +1736,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 627 "lexer.l" +#line 520 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1871,7 +1765,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 654 "lexer.l" +#line 547 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1881,7 +1775,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 662 "lexer.l" +#line 555 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1899,13 +1793,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 678 "lexer.l" +#line 571 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 681 "lexer.l" +#line 574 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1914,7 +1808,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 688 "lexer.l" +#line 581 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1924,7 +1818,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 696 "lexer.l" +#line 589 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1935,7 +1829,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 704 "lexer.l" +#line 597 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1951,12 +1845,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 717 "lexer.l" +#line 610 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 719 "lexer.l" +#line 612 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1972,10 +1866,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 732 "lexer.l" +#line 625 "lexer.l" ECHO; YY_BREAK -#line 1979 "lexer.c" +#line 1873 "lexer.c" case YY_END_OF_BUFFER: { @@ -3124,7 +3018,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 732 "lexer.l" +#line 625 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index 84830f7453..7913c4a847 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -187,159 +187,71 @@ include[ \t]+\" { \" { - char buffer[1024]; - char *current_file_name; - char *s = NULL; - #ifdef _WIN32 - char *b = NULL; - #endif - char *f; - FILE* fh; - if (compiler->allow_includes) { *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path // move path of current source file into buffer - current_file_name = yr_compiler_get_current_file_name(compiler); + char* current_file_name = yr_compiler_get_current_file_name( + compiler); - if (current_file_name != NULL) - { - strlcpy(buffer, current_file_name, sizeof(buffer)); - } - else - { - buffer[0] = '\0'; - } + const char* res = compiler->include_callback( + yyextra->lex_buf, + current_file_name, + compiler->current_namespace->name, + compiler->incl_clbk_user_data); - if (compiler->include_callback == NULL) + if (res != NULL) { - // make included file path relative to current source file - s = strrchr(buffer, '/'); - - #ifdef _WIN32 - b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted - #endif - - #ifdef _WIN32 - if (s != NULL || b != NULL) - #else - if (s != NULL) - #endif - { - #ifdef _WIN32 - f = (b > s)? (b + 1): (s + 1); - #else - f = s + 1; - #endif - - strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer)); - - f = buffer; - // SECURITY: Potential for directory traversal here. - fh = fopen(buffer, "r"); + int error_code = _yr_compiler_push_file_name( compiler, + yyextra->lex_buf); - // if include file was not found relative to current source file, - // try to open it with path as specified by user (maybe user wrote - // a full path) - - if (fh == NULL) + if (error_code != ERROR_SUCCESS) + { + if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) { - f = yyextra->lex_buf; - - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); + yyerror(yyscanner, compiler, "includes circular reference"); } - } - else - { - f = yyextra->lex_buf; - - // SECURITY: Potential for directory traversal here. - fh = fopen(yyextra->lex_buf, "r"); - } - - if (fh != NULL) - { - int error_code = _yr_compiler_push_file_name(compiler, f); - - if (error_code != ERROR_SUCCESS) + else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) - { - yyerror(yyscanner, compiler, "includes depth exceeded"); - } - - yyterminate(); + yyerror(yyscanner, compiler, "includes depth exceeded"); } - - _yr_compiler_push_file(compiler, fh); - yypush_buffer_state( - yy_create_buffer(fh, YY_BUF_SIZE, yyscanner), yyscanner); + if(compiler->include_free != NULL) + { + compiler->include_free(res, compiler->incl_clbk_user_data); + } + yyterminate(); } - else + + // Workaround for flex issue: https://github.com/westes/flex/issues/58 + yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); + yy_scan_string(res, yyscanner); + if(compiler->include_free != NULL) { - snprintf(buffer, sizeof(buffer), - "can't open include file: %s", yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + compiler->include_free(res, compiler->incl_clbk_user_data); } - } else { - const char* res = compiler->include_callback( - yyextra->lex_buf, - current_file_name, - compiler->current_namespace->name, - compiler->incl_clbk_user_data); - - if (res != NULL) + char* base_err_msg = NULL; + if(compiler->include_callback == _yr_compiler_default_include_callback) { - const char* res_dup = yr_strdup(res); - yr_free((void*) res); - res = NULL; - - int error_code = _yr_compiler_push_file_name( compiler, - yyextra->lex_buf); - - if (error_code != ERROR_SUCCESS) - { - if (error_code == ERROR_INCLUDES_CIRCULAR_REFERENCE) - { - yyerror(yyscanner, compiler, "includes circular reference"); - } - else if (error_code == ERROR_INCLUDE_DEPTH_EXCEEDED) - { - yyerror(yyscanner, compiler, "includes depth exceeded"); - } - - yr_free((void*) res_dup); - res_dup = NULL; - yyterminate(); - } - - // Workaround for flex issue: https://github.com/westes/flex/issues/58 - yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); - yy_scan_string(res_dup, yyscanner); - - yr_free((void*) res_dup); - res_dup = NULL; + base_err_msg = "can't open include file: %s"; } else { - snprintf( buffer, - sizeof(buffer), - "'include_callback' failed to return rules contained in '%s'", - yyextra->lex_buf); - yyerror(yyscanner, compiler, buffer); + base_err_msg = "callback failed to provide include resource: %s"; } - + size_t err_buff_len = sizeof(base_err_msg) + sizeof(yyextra->lex_buf); + char* error_buffer = yr_malloc(err_buff_len); + snprintf( error_buffer, + err_buff_len, + base_err_msg, + yyextra->lex_buf); + yyerror(yyscanner, compiler, error_buffer); } + } else // not allowing includes { @@ -355,33 +267,14 @@ include[ \t]+\" { YR_COMPILER* compiler = yyget_extra(yyscanner); - if (compiler->include_callback == NULL) - { - FILE* file = _yr_compiler_pop_file(compiler); + _yr_compiler_pop_file_name(compiler); + yypop_buffer_state(yyscanner); - if (file != NULL) - { - fclose(file); - } - - _yr_compiler_pop_file_name(compiler); - yypop_buffer_state(yyscanner); - - if (!YY_CURRENT_BUFFER) - { - yyterminate(); - } - } - else + if (!YY_CURRENT_BUFFER) { - _yr_compiler_pop_file_name(compiler); - yypop_buffer_state(yyscanner); - - if (!YY_CURRENT_BUFFER) - { - yyterminate(); - } + yyterminate(); } + } diff --git a/libyara/mem.c b/libyara/mem.c index 55b0d8acca..5878b1ef88 100644 --- a/libyara/mem.c +++ b/libyara/mem.c @@ -58,31 +58,31 @@ int yr_heap_free(void) } -YR_API void* yr_calloc(size_t count, size_t size) +void* yr_calloc(size_t count, size_t size) { return (void*) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, count * size); } -YR_API void* yr_malloc(size_t size) +void* yr_malloc(size_t size) { return (void*) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size); } -YR_API void* yr_realloc(void* ptr, size_t size) +void* yr_realloc(void* ptr, size_t size) { return (void*) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, ptr, size); } -YR_API void yr_free(void* ptr) +void yr_free(void* ptr) { HeapFree(hHeap, 0, ptr); } -YR_API char* yr_strdup(const char *str) +char* yr_strdup(const char *str) { size_t len = strlen(str); char *dup = (char*) yr_malloc(len + 1); @@ -97,7 +97,7 @@ YR_API char* yr_strdup(const char *str) } -YR_API char* yr_strndup(const char *str, size_t n) +char* yr_strndup(const char *str, size_t n) { size_t len = strnlen(str, n); char *dup = (char*) yr_malloc(len + 1); @@ -133,37 +133,37 @@ int yr_heap_free(void) } -YR_API void* yr_calloc(size_t count, size_t size) +void* yr_calloc(size_t count, size_t size) { return calloc(count, size); } -YR_API void* yr_malloc(size_t size) +void* yr_malloc(size_t size) { return malloc(size); } -YR_API void* yr_realloc(void* ptr, size_t size) +void* yr_realloc(void* ptr, size_t size) { return realloc(ptr, size); } -YR_API void yr_free(void *ptr) +void yr_free(void *ptr) { free(ptr); } -YR_API char* yr_strdup(const char *str) +char* yr_strdup(const char *str) { return strdup(str); } -YR_API char* yr_strndup(const char *str, size_t n) +char* yr_strndup(const char *str, size_t n) { return strndup(str, n); } From aeaf59ac76e743947f7062966e7ccb891a99c535 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Tue, 5 Sep 2017 16:12:58 +0200 Subject: [PATCH 09/13] fixing missing pointer cast --- libyara/lexer.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyara/lexer.l b/libyara/lexer.l index 7913c4a847..d0338f873d 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -244,7 +244,7 @@ include[ \t]+\" { base_err_msg = "callback failed to provide include resource: %s"; } size_t err_buff_len = sizeof(base_err_msg) + sizeof(yyextra->lex_buf); - char* error_buffer = yr_malloc(err_buff_len); + char* error_buffer = (char*) yr_malloc(err_buff_len); snprintf( error_buffer, err_buff_len, base_err_msg, From 3fd143451b5e9923420e90bb5a30a9f7ec4d78ca Mon Sep 17 00:00:00 2001 From: edhoedt Date: Tue, 5 Sep 2017 16:47:13 +0200 Subject: [PATCH 10/13] re-generating lexer.c --- libyara/lexer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyara/lexer.c b/libyara/lexer.c index d0017d7680..d12a876b6c 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1411,7 +1411,7 @@ YY_RULE_SETUP base_err_msg = "callback failed to provide include resource: %s"; } size_t err_buff_len = sizeof(base_err_msg) + sizeof(yyextra->lex_buf); - char* error_buffer = yr_malloc(err_buff_len); + char* error_buffer = (char*) yr_malloc(err_buff_len); snprintf( error_buffer, err_buff_len, base_err_msg, From b8fe3478a8117c9898ffbb7dc5faeace2dd5ae8f Mon Sep 17 00:00:00 2001 From: edhoedt Date: Wed, 6 Sep 2017 10:35:04 +0200 Subject: [PATCH 11/13] removing imports ununsed since commit 92877db48e408126ce0631b85c03d47899ea5623 --- libyara/include/yara.h | 1 - libyara/include/yara/mem.h | 1 - libyara/mem.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libyara/include/yara.h b/libyara/include/yara.h index a627e90bf9..3a35518663 100644 --- a/libyara/include/yara.h +++ b/libyara/include/yara.h @@ -39,6 +39,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "yara/error.h" #include "yara/stream.h" #include "yara/hash.h" -#include "yara/mem.h" #endif diff --git a/libyara/include/yara/mem.h b/libyara/include/yara/mem.h index b18d2a68a5..ff7dc3ec7e 100644 --- a/libyara/include/yara/mem.h +++ b/libyara/include/yara/mem.h @@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define YR_MEM_H #include -#include #ifdef DMALLOC diff --git a/libyara/mem.c b/libyara/mem.c index 5878b1ef88..53a151fe69 100644 --- a/libyara/mem.c +++ b/libyara/mem.c @@ -27,7 +27,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include + #if defined(_WIN32) || defined(__CYGWIN__) From d084696555423d2b6cad126072cd38aa26e32db3 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Thu, 7 Sep 2017 16:12:32 +0200 Subject: [PATCH 12/13] fixing default file read callback --- libyara/compiler.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libyara/compiler.c b/libyara/compiler.c index 179cb48574..c32ba687ac 100644 --- a/libyara/compiler.c +++ b/libyara/compiler.c @@ -190,7 +190,6 @@ const char* _yr_compiler_default_include_callback( void* user_data) { char* buffer; - //char buffer[1024]; char* s = NULL; #ifdef _WIN32 char* b = NULL; @@ -203,14 +202,12 @@ const char* _yr_compiler_default_include_callback( if(calling_rule_filename != NULL) { buffer = (char*) calling_rule_filename; - //strlcpy(buffer, calling_rule_filename, sizeof(buffer)); } else { buffer = "\0"; - //buffer[0] = '\0'; } - // make included file path relative to current source file + s = strrchr(buffer, '/'); #ifdef _WIN32 @@ -230,7 +227,7 @@ const char* _yr_compiler_default_include_callback( strlcpy(f, include_name, sizeof(buffer) - (f - buffer)); f = buffer; // SECURITY: Potential for directory traversal here. - fh = fopen(buffer, "r"); + fh = fopen(buffer, "rb"); // if include file was not found relative to current source file, // try to open it with path as specified by user (maybe user wrote // a full path) @@ -238,14 +235,14 @@ const char* _yr_compiler_default_include_callback( { f = (char*) include_name; // SECURITY: Potential for directory traversal here. - fh = fopen(include_name, "r"); + fh = fopen(include_name, "rb"); } } else { f = (char*) include_name; // SECURITY: Potential for directory traversal here. - fh = fopen(include_name, "r"); + fh = fopen(include_name, "rb"); } if (fh != NULL) { @@ -255,18 +252,24 @@ const char* _yr_compiler_default_include_callback( fseek(fh, 0, SEEK_END); file_length = ftell(fh); fseek(fh, 0, SEEK_SET); - file_buffer = (char*) yr_malloc((file_length+1)*sizeof(char)); + file_buffer = (char*) yr_malloc(file_length+1); if(file_buffer) { - if(file_length != fread(file_buffer, sizeof(char), file_length, fh)) + if(file_length != fread(file_buffer, 1, file_length, fh)) { return NULL; } + else + { + file_buffer[file_length]='\0'; + } } fclose(fh); return file_buffer; } - else return NULL; + else{ + return NULL; + } } From 0b864647cceb1406353e7049d018593ba48dcf93 Mon Sep 17 00:00:00 2001 From: edhoedt Date: Mon, 11 Sep 2017 10:10:11 +0200 Subject: [PATCH 13/13] Fixing line numbers in errors --- libyara/lexer.c | 69 +++++++++++++++++++++++++------------------------ libyara/lexer.l | 1 + 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/libyara/lexer.c b/libyara/lexer.c index d12a876b6c..ae7388d7f9 100644 --- a/libyara/lexer.c +++ b/libyara/lexer.c @@ -1394,6 +1394,7 @@ YY_RULE_SETUP // Workaround for flex issue: https://github.com/westes/flex/issues/58 yara_yypush_buffer_state(YY_CURRENT_BUFFER,yyscanner); yara_yy_scan_string(res,yyscanner); + yara_yyset_lineno(1,yyscanner); if(compiler->include_free != NULL) { compiler->include_free(res, compiler->incl_clbk_user_data); @@ -1434,7 +1435,7 @@ case YY_STATE_EOF(str): case YY_STATE_EOF(regexp): case YY_STATE_EOF(include): case YY_STATE_EOF(comment): -#line 266 "lexer.l" +#line 267 "lexer.l" { YR_COMPILER* compiler = yara_yyget_extra(yyscanner); @@ -1451,7 +1452,7 @@ case YY_STATE_EOF(comment): YY_BREAK case 44: YY_RULE_SETUP -#line 281 "lexer.l" +#line 282 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1467,7 +1468,7 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 295 "lexer.l" +#line 296 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1483,7 +1484,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 309 "lexer.l" +#line 310 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1500,7 +1501,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 324 "lexer.l" +#line 325 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1517,7 +1518,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 339 "lexer.l" +#line 340 "lexer.l" { yylval->c_string = yr_strdup(yytext); @@ -1534,7 +1535,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 354 "lexer.l" +#line 355 "lexer.l" { char* text = yytext; @@ -1575,7 +1576,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 393 "lexer.l" +#line 394 "lexer.l" { if (strlen(yytext) > 128) @@ -1596,7 +1597,7 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 412 "lexer.l" +#line 413 "lexer.l" { #ifdef _MSC_VER @@ -1618,7 +1619,7 @@ YY_RULE_SETUP YY_BREAK case 52: YY_RULE_SETUP -#line 431 "lexer.l" +#line 432 "lexer.l" { yylval->double_ = atof(yytext); return _DOUBLE_; @@ -1626,7 +1627,7 @@ YY_RULE_SETUP YY_BREAK case 53: YY_RULE_SETUP -#line 436 "lexer.l" +#line 437 "lexer.l" { yylval->integer = xtoi(yytext + 2); return _NUMBER_; @@ -1634,7 +1635,7 @@ YY_RULE_SETUP YY_BREAK case 54: YY_RULE_SETUP -#line 441 "lexer.l" +#line 442 "lexer.l" { yylval->integer = otoi(yytext + 2); return _NUMBER_; @@ -1642,7 +1643,7 @@ YY_RULE_SETUP YY_BREAK case 55: YY_RULE_SETUP -#line 447 "lexer.l" +#line 448 "lexer.l" { /* saw closing quote - all done */ ALLOC_SIZED_STRING(s, yyextra->lex_buf_len); @@ -1658,7 +1659,7 @@ YY_RULE_SETUP YY_BREAK case 56: YY_RULE_SETUP -#line 461 "lexer.l" +#line 462 "lexer.l" { LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1668,7 +1669,7 @@ YY_RULE_SETUP YY_BREAK case 57: YY_RULE_SETUP -#line 469 "lexer.l" +#line 470 "lexer.l" { LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1678,7 +1679,7 @@ YY_RULE_SETUP YY_BREAK case 58: YY_RULE_SETUP -#line 477 "lexer.l" +#line 478 "lexer.l" { LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1688,7 +1689,7 @@ YY_RULE_SETUP YY_BREAK case 59: YY_RULE_SETUP -#line 485 "lexer.l" +#line 486 "lexer.l" { LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1698,7 +1699,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 493 "lexer.l" +#line 494 "lexer.l" { int result; @@ -1711,13 +1712,13 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 504 "lexer.l" +#line 505 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -#line 507 "lexer.l" +#line 508 "lexer.l" { yyerror(yyscanner, compiler, "unterminated string"); @@ -1727,7 +1728,7 @@ YY_RULE_SETUP case 63: /* rule 63 can match eol */ YY_RULE_SETUP -#line 513 "lexer.l" +#line 514 "lexer.l" { yyerror(yyscanner, compiler, "illegal escape sequence"); @@ -1736,7 +1737,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 520 "lexer.l" +#line 521 "lexer.l" { if (yyextra->lex_buf_len > 0) @@ -1765,7 +1766,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 547 "lexer.l" +#line 548 "lexer.l" { LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1775,7 +1776,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 555 "lexer.l" +#line 556 "lexer.l" { LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); @@ -1793,13 +1794,13 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 571 "lexer.l" +#line 572 "lexer.l" { YYTEXT_TO_BUFFER; } YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -#line 574 "lexer.l" +#line 575 "lexer.l" { yyerror(yyscanner, compiler, "unterminated regular expression"); @@ -1808,7 +1809,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 581 "lexer.l" +#line 582 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1818,7 +1819,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 589 "lexer.l" +#line 590 "lexer.l" { yyextra->lex_buf_ptr = yyextra->lex_buf; @@ -1829,7 +1830,7 @@ YY_RULE_SETUP case 71: /* rule 71 can match eol */ YY_RULE_SETUP -#line 597 "lexer.l" +#line 598 "lexer.l" { // Match hex-digits with whitespace or comments. The latter are stripped // out by hex_lexer.l @@ -1845,12 +1846,12 @@ YY_RULE_SETUP case 72: /* rule 72 can match eol */ YY_RULE_SETUP -#line 610 "lexer.l" +#line 611 "lexer.l" /* skip whitespace */ YY_BREAK case 73: YY_RULE_SETUP -#line 612 "lexer.l" +#line 613 "lexer.l" { if (yytext[0] >= 32 && yytext[0] < 127) @@ -1866,10 +1867,10 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 625 "lexer.l" +#line 626 "lexer.l" ECHO; YY_BREAK -#line 1873 "lexer.c" +#line 1874 "lexer.c" case YY_END_OF_BUFFER: { @@ -3018,7 +3019,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 625 "lexer.l" +#line 626 "lexer.l" diff --git a/libyara/lexer.l b/libyara/lexer.l index d0338f873d..6a8a5baa57 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -227,6 +227,7 @@ include[ \t]+\" { // Workaround for flex issue: https://github.com/westes/flex/issues/58 yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); yy_scan_string(res, yyscanner); + yyset_lineno(1, yyscanner); if(compiler->include_free != NULL) { compiler->include_free(res, compiler->incl_clbk_user_data);