Fix handling of a command spec without a newline at the end.

For include files, we may need to inject a newline token now that
the grammar requires lines to end with a newline or EOF.  There is
no END (EOF) token processed after popping off an include file since
everything is just treated as one big file.
This commit is contained in:
Todd C. Miller
2020-09-27 10:05:35 -06:00
parent 0276a565e6
commit 9bb91cb64b
2 changed files with 45 additions and 21 deletions

View File

@@ -2760,9 +2760,9 @@ char *sudoerstext;
#endif #endif
int sudolineno; /* current sudoers line number. */ int sudolineno; /* current sudoers line number. */
int last_token; /* last token that was parsed. */
char *sudoers; /* sudoers file being parsed. */ char *sudoers; /* sudoers file being parsed. */
struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */ struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */
extern int sudoerschar; /* last token that was parsed. */
/* Default sudoers path, mode and owner (may be set via sudo.conf) */ /* Default sudoers path, mode and owner (may be set via sudo.conf) */
const char *sudoers_file = _PATH_SUDOERS; const char *sudoers_file = _PATH_SUDOERS;
@@ -4031,25 +4031,37 @@ case YY_STATE_EOF(GOTINC):
case YY_STATE_EOF(EXPECTPATH): case YY_STATE_EOF(EXPECTPATH):
#line 806 "toke.l" #line 806 "toke.l"
{ {
if (YY_START != INITIAL) { int state = YY_START;
if (YY_START == INSTR)
sudoerserror(N_("unterminated string")); BEGIN INITIAL;
else
sudoerserror(N_("unexpected state at end of file")); switch (state) {
BEGIN INITIAL; case GOTCMND:
/* missing newline after command/args */
return COMMAND;
case INSTR:
sudoerserror(N_("unterminated string"));
LEXTRACE("ERROR "); LEXTRACE("ERROR ");
return ERROR; return ERROR;
default:
if (!pop_include())
yyterminate();
/* force a newline at EOF */
if (sudoerschar != '\n') {
LEXTRACE("\n");
return '\n';
}
break;
} }
if (!pop_include())
yyterminate();
} }
YY_BREAK YY_BREAK
case 81: case 81:
YY_RULE_SETUP YY_RULE_SETUP
#line 820 "toke.l" #line 832 "toke.l"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 4047 "toke.c" #line 4059 "toke.c"
case YY_END_OF_BUFFER: case YY_END_OF_BUFFER:
{ {
@@ -5010,7 +5022,7 @@ void sudoersfree (void * ptr )
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#line 820 "toke.l" #line 832 "toke.l"
struct path_list { struct path_list {

View File

@@ -51,9 +51,9 @@
#endif #endif
int sudolineno; /* current sudoers line number. */ int sudolineno; /* current sudoers line number. */
int last_token; /* last token that was parsed. */
char *sudoers; /* sudoers file being parsed. */ char *sudoers; /* sudoers file being parsed. */
struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */ struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */
extern int sudoerschar; /* last token that was parsed. */
/* Default sudoers path, mode and owner (may be set via sudo.conf) */ /* Default sudoers path, mode and owner (may be set via sudo.conf) */
const char *sudoers_file = _PATH_SUDOERS; const char *sudoers_file = _PATH_SUDOERS;
@@ -804,17 +804,29 @@ sudoedit {
} /* parse error, no matching token */ } /* parse error, no matching token */
<*><<EOF>> { <*><<EOF>> {
if (YY_START != INITIAL) { int state = YY_START;
if (YY_START == INSTR)
sudoerserror(N_("unterminated string")); BEGIN INITIAL;
else
sudoerserror(N_("unexpected state at end of file")); switch (state) {
BEGIN INITIAL; case GOTCMND:
/* missing newline after command/args */
return COMMAND;
case INSTR:
sudoerserror(N_("unterminated string"));
LEXTRACE("ERROR "); LEXTRACE("ERROR ");
return ERROR; return ERROR;
default:
if (!pop_include())
yyterminate();
/* force a newline at EOF */
if (sudoerschar != '\n') {
LEXTRACE("\n");
return '\n';
}
break;
} }
if (!pop_include())
yyterminate();
} }
%% %%