lib: Fix OOB range parses, variable matches

Variables now allow strings beginning with numbers
to match, ranges and numbers are now long long to
fix OOB parses resulting in integer wraparounds.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2016-08-01 18:36:30 +00:00
parent 1a8c390d4a
commit e648e61a74
6 changed files with 21 additions and 11 deletions

View File

@ -193,7 +193,7 @@ dump_node (struct graph_node *node)
fprintf(stderr, "\t->value: %ld\n", node->value);
fprintf(stderr, "\t->is_start: %d\n", node->is_start);
fprintf(stderr, "\t->element: %p\n", node->element);
fprintf(stderr, "\t->min: %ld\n->max: %ld\n", node->min, node->max);
fprintf(stderr, "\t->min: %lld\n->max: %lld\n", node->min, node->max);
fprintf(stderr, "\t->arg: %s\n", node->arg);
fprintf(stderr, "\t->refs: %d\n", node->refs);
fprintf(stderr, "\tnum children: %d\n", vector_active(node->children));

View File

@ -29,7 +29,7 @@ struct graph_node
char* text; // for WORD_GN and VARIABLE_GN
long value; // for NUMBER_GN
long min, max; // for RANGE_GN
signed long long min, max;// for RANGE_GN
/* cmd_element struct pointer, only valid for END_GN */
struct cmd_element *element;

View File

@ -28,7 +28,11 @@ RANGE \({NUMBER}\-{NUMBER}\)
{IPV6} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6;}
{IPV6_PREFIX} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6_PREFIX;}
{VARIABLE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return VARIABLE;}
{NUMBER} {yylval.integer = atoi(yytext); return NUMBER;}
{NUMBER} {
char *endptr;
yylval.integer = strtoll(yytext, &endptr, 10);
return NUMBER;
}
{RANGE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return RANGE;}
. {return yytext[0];}
%%

View File

@ -604,7 +604,7 @@ static enum match_type
match_range (struct graph_node *rangenode, const char *str)
{
char *endptr = NULL;
signed long val;
signed long long val;
if (str == NULL)
return 1;
@ -653,11 +653,11 @@ match_number(struct graph_node *numnode, const char *word)
return num == numnode->value ? exact_match : no_match;
}
#define VARIABLE_ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
#define VARIABLE_ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890:"
static enum match_type
match_variable(struct graph_node *varnode, const char *word)
{
return strlen(word) == strspn(word, VARIABLE_ALPHABET) && isalpha(word[0]) ?
return strlen(word) == strspn(word, VARIABLE_ALPHABET) ?
exact_match : no_match;
}

View File

@ -30,7 +30,7 @@ extern void yyerror(const char *);
/* valid types for tokens */
%union{
int integer;
signed long long integer;
char *string;
struct graph_node *node;
}
@ -91,7 +91,7 @@ start: sentence_root
yyerror("Duplicate command.");
YYABORT;
}
fprintf(stderr, "Added END_GN with active children: %d\n", vector_active(end->children));
fprintf(stderr, "Parsed full command successfully.\n");
}
sentence_root: WORD
@ -179,8 +179,9 @@ placeholder_token:
// get the numbers out
strsep(&yylval.string, "(-)");
$$->min = atoi( strsep(&yylval.string, "(-)") );
$$->max = atoi( strsep(&yylval.string, "(-)") );
char *endptr;
$$->min = strtoll( strsep(&yylval.string, "(-)"), &endptr, 10 );
$$->max = strtoll( strsep(&yylval.string, "(-)"), &endptr, 10 );
free ($1);
}
@ -313,7 +314,7 @@ void yyerror(char const *message) {
fprintf(stderr, "Token on error: ");
if (yylval.string) fprintf(stderr, "%s\n", yylval.string);
else if (yylval.node) fprintf(stderr, "%s\n", yylval.node->text);
else fprintf(stderr, "%d\n", yylval.integer);
else fprintf(stderr, "%lld\n", yylval.integer);
}

View File

@ -17,6 +17,8 @@ DEFUN (grammar_test,
char* command = argv_concat(argv, argc, 0);
struct cmd_element *cmd = malloc(sizeof(struct cmd_element));
cmd->string = command;
cmd->doc = NULL;
cmd->func = NULL;
parse_command_format(nodegraph, cmd);
return CMD_SUCCESS;
}
@ -59,6 +61,9 @@ DEFUN (grammar_test_complete,
fprintf(stderr, "<cr> %p\n", cnode->element->func);
else
fprintf(stderr, "%s\n", describe_node(cnode, desc, 50));
if (cnode->type == RANGE_GN)
fprintf(stderr, "%lld - %lld\n", cnode->min, cnode->max);
}
free(desc);
}