Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
apparmor-parser
apparmor-parser-line-numbers
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File apparmor-parser-line-numbers of Package apparmor-parser
From: Jeff Mahoney <jeffm@suse.com> Subject: apparmor-parser: Provide meaningful line numbers in error reports References: bnc#520013 The apparmor profile parser operates in a two-pass sweep. The first pass preprocesses the profile, handling includes and the like. The second pass is actually parsed. The problem is that the resultant preprocessed profile bears little resemblance to the original. Errors like "syntax error at line 213" on a 14 line profile serve only to confuse the user. This patch adds cpp-style #line directives the the preprocessed output, delimiting where files have been included. The result is that not only is the original profile's line numbers reported correctly, but included files are handled as well. --- parser_include.c | 26 ++++++++++++++++---------- parser_lex.l | 37 +++++++++++++++++++++++++++++++++++-- parser_yacc.y | 21 +++++++++++++++++++-- 3 files changed, 70 insertions(+), 14 deletions(-) --- a/parser_include.c +++ b/parser_include.c @@ -84,6 +84,8 @@ static char *basedir; static char *default_basedir = "/etc/apparmor.d"; static char *old_basedir = "/etc/subdomain.d"; +extern char *current_filename; + /* start parsing. */ int do_include_preprocessing(char *profilename) { @@ -101,12 +103,13 @@ int do_include_preprocessing(char *profi profile = stdin; } + current_filename = strdup(profilename ? profilename : "stdin"); + /* Change to the base dir */ chdir(basedir); if (preprocess_only) { - retval = preprocess(profile, profilename ? profilename : "stdin", - stdout, 0); + retval = preprocess(profile, current_filename, stdout, 0); goto out; } @@ -116,8 +119,7 @@ int do_include_preprocessing(char *profi exit(10); } - retval = preprocess(profile, profilename ? profilename : "stdin", - tmp, 0); + retval = preprocess(profile, current_filename, tmp, 0); rewind(tmp); @@ -128,6 +130,11 @@ out: if (profilename) fclose(profile); + if (current_filename) { + free(current_filename); + current_filename = NULL; + } + return retval; } @@ -429,6 +436,8 @@ static int process_include(char *inc, ch err = preprocess(newf, inc + 1, out, nest + 1); if (err) retval = err; + fprintf(out, "\n#line %u \"%s\"\n", + line, name); fclose(newf); } else { retval = errno; @@ -455,18 +464,14 @@ static int preprocess(FILE * f, char *na char *inc = NULL; char *cwd; + fprintf(out, "\n#line 1 \"%s\"\n", name); + if (nest > MAX_NEST_LEVEL) { PERROR(_("Error: Exceeded %d levels of includes. Not processing %s include.\n"), MAX_NEST_LEVEL, name); return 1; } - if (nest == 0) { - fprintf(out, "\n#source %s\n", name); - } else { - fprintf(out, "\n#included %s\n", name); - } - while ((c = fgetc(f)) != EOF) { int err = getincludestr(&inc, c, f, line, name, out); if (err) @@ -476,6 +481,7 @@ static int preprocess(FILE * f, char *na err = process_include(inc, name, line, out, nest); if (err) retval = err; + fprintf(out, "\n#line %u \"%s\"\n", line, name); chdir(cwd); free(cwd); free(inc); --- a/parser_lex.l +++ b/parser_lex.l @@ -42,6 +42,7 @@ #define NPDEBUG(fmt, args...) /* Do nothing */ int current_lineno = 1; +char *current_filename = NULL; %} @@ -81,12 +82,16 @@ ADD_ASSIGN \+= ARROW -> LT_EQUAL <= +COMMENT_START #[a-z]* + %x SUB_NAME %x SUB_NAME2 %x NETWORK_MODE %x FLAGS_MODE %x ASSIGN_MODE %x RLIMIT_MODE +%x FILE_POS_MODE +%x COMMENT_MODE %% @@ -237,10 +242,38 @@ LT_EQUAL <= } } -#.*\n { /* Comment - ignore */ + +<FILE_POS_MODE>{ + {WS}+ { } + {NUMBER} { + yylval = (YYSTYPE) strdup(yytext); + return TOK_VALUE; + } + {QUOTED_ID} { + yylval = (YYSTYPE) processquoted(yytext, yyleng); + return TOK_ID; + } + + \r?\n { + BEGIN(INITIAL); + } +} + +<COMMENT_MODE>{ + .*\n { + BEGIN(INITIAL); current_lineno++; - PDEBUG("Line no++: %d\n", current_lineno); } +} + +{COMMENT_START} { + if (!strcmp(yytext, "#line")) { + BEGIN(FILE_POS_MODE); + return TOK_FILE_POS; + } + BEGIN(COMMENT_MODE); + } + {END_OF_RULE} { return TOK_END_OF_RULE; } --- a/parser_yacc.y +++ b/parser_yacc.y @@ -58,8 +58,8 @@ static struct flagval force_complain_flags = {0, 1, 0}; /* from lex_config, for nice error messages */ -/* extern char *current_file; */ extern int current_lineno; +extern char *current_filename; struct value_list { char *value; @@ -139,6 +139,9 @@ struct codomain *do_local_profile(struct %token TOK_FLAG_SEP %token TOK_FLAG_ID +%token TOK_FILE_POS +%token TOK_COMMENT + %union { char *id; char *flag_id; @@ -208,6 +211,8 @@ opt_profile_flag: { /* nothing */ $$ = 0 | TOK_PROFILE { $$ = 1; } | hat_start { $$ = 2; } +profile: file_position + profile: opt_profile_flag TOK_ID flags TOK_OPEN rules TOK_CLOSE { struct codomain *cod = $5; @@ -263,6 +268,7 @@ profile: opt_profile_flag TOK_COLON TOK_ preamble: { /* nothing */ } | preamble alias { /* nothing */ }; | preamble varassign { /* nothing */ }; + | preamble file_position { }; alias: TOK_ALIAS TOK_ID TOK_ARROW TOK_ID TOK_END_OF_RULE { @@ -712,6 +718,8 @@ rules: rules TOK_SET TOK_RLIMIT TOK_ID T $$ = $1; }; +rules: rules file_position + cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE { @@ -1059,6 +1067,15 @@ caps: TOK_ID $$ = CAP_TO_MASK(cap); }; +file_position: TOK_FILE_POS TOK_VALUE TOK_ID + { + if (current_filename) + free(current_filename); + current_filename = $3; + current_lineno = atoi($2); + free($2); + }; + %% #define MAXBUFSIZE 4096 @@ -1073,7 +1090,7 @@ void yyerror(char *msg, ...) if (profilename) { PERROR(_("AppArmor parser error in %s at line %d: %s\n"), - profilename, current_lineno, buf); + current_filename, current_lineno, buf); } else { PERROR(_("AppArmor parser error, line %d: %s\n"), current_lineno, buf);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor