diff --git a/lib/scanner.c b/lib/scanner.c index 9dc3813..a2011da 100644 --- a/lib/scanner.c +++ b/lib/scanner.c @@ -928,9 +928,9 @@ static const flex_int32_t yy_rule_can_match_eol[49] = #include "grammar.h" #include "wincompat.h" #include "util.h" - +static int libconfig_yyread(char *buf, int max_size, FILE *input); #define YY_NO_INPUT /* Suppress generation of useless input() function */ - +#define YY_INPUT(buf, result, max_size) ((result) = libconfig_yyread((buf), (max_size), yyin)) #line 935 "scanner.c" #line 937 "scanner.c" @@ -1634,6 +1634,15 @@ case YY_STATE_EOF(INCLUDE): const char *error = NULL; FILE *fp; + if(yyin && ferror(yyin)) + { + yyextra->config->error_text = "input in flex scanner failed"; + yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra); + yyextra->config->error_line = libconfig_yyget_lineno(yyscanner); + clearerr(yyin); + return TOK_ERROR; + } + fp = libconfig_scanctx_next_include_file(yyextra, &error); if(fp) { @@ -2797,9 +2806,26 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 265 "scanner.l" +#line 276 "scanner.l" + +static int libconfig_yyread(char *buf, int max_size, FILE *input) +{ + int result; + errno = 0; + while((result = (int)fread(buf, 1, (size_t)max_size, input)) == 0 + && ferror(input)) + { + if(errno != EINTR) + break; + errno = 0; + clearerr(input); + } + + return(result); +} +#line 293 "scanner.l" void *libconfig_yyalloc(size_t bytes, void *yyscanner) { return(libconfig_malloc(bytes)); diff --git a/lib/scanner.l b/lib/scanner.l index 1baccd6..6c81a6f 100644 --- a/lib/scanner.l +++ b/lib/scanner.l @@ -50,9 +50,9 @@ #include "grammar.h" #include "wincompat.h" #include "util.h" - +static int libconfig_yyread(char *buf, int max_size, FILE *input); #define YY_NO_INPUT /* Suppress generation of useless input() function */ - +#define YY_INPUT(buf, result, max_size) ((result) = libconfig_yyread((buf), (max_size), yyin)) %} true [Tt][Rr][Uu][Ee] @@ -233,6 +233,15 @@ include_open ^[ \t]*@include[ \t]+\" const char *error = NULL; FILE *fp; + if(yyin && ferror(yyin)) + { + yyextra->config->error_text = "input in flex scanner failed"; + yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra); + yyextra->config->error_line = libconfig_yyget_lineno(yyscanner); + clearerr(yyin); + return TOK_ERROR; + } + fp = libconfig_scanctx_next_include_file(yyextra, &error); if(fp) { @@ -264,6 +273,23 @@ include_open ^[ \t]*@include[ \t]+\" %% +static int libconfig_yyread(char *buf, int max_size, FILE *input) +{ + int result; + + errno = 0; + while((result = (int)fread(buf, 1, (size_t)max_size, input)) == 0 + && ferror(input)) + { + if(errno != EINTR) + break; + errno = 0; + clearerr(input); + } + + return(result); +} + void *libconfig_yyalloc(size_t bytes, void *yyscanner) { return(libconfig_malloc(bytes)); diff --git a/tests/tests.c b/tests/tests.c index eba7eae..99c8029 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -644,6 +644,18 @@ TT_TEST(SettingLookups) /* ------------------------------------------------------------------------- */ +TT_TEST(IncludeReadError) +{ + config_t cfg; + + config_init(&cfg); + TT_ASSERT_FALSE(config_read_string(&cfg, "@include \".\"")); + TT_ASSERT_PTR_NOTNULL(config_error_text(&cfg)); + config_destroy(&cfg); +} + +/* ------------------------------------------------------------------------- */ + TT_TEST(ReadStream) { config_t cfg; @@ -767,6 +779,7 @@ int main(int argc, char **argv) TT_SUITE_TEST(LibConfigTests, EscapedStrings); TT_SUITE_TEST(LibConfigTests, OverrideSetting); TT_SUITE_TEST(LibConfigTests, SettingLookups); + TT_SUITE_TEST(LibConfigTests, IncludeReadError); TT_SUITE_TEST(LibConfigTests, ReadStream); TT_SUITE_TEST(LibConfigTests, BinaryAndHex); TT_SUITE_RUN(LibConfigTests);