if (fgets(buf, sizeof(buf), config_file) == NULL)
break;
- if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i]) < 0 ){
+ if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i],
+ sizeof(peer_eth_addrs[i])) < 0) {
printf("Bad MAC address format on line %d\n", i+1);
fclose(config_file);
return -1;
"eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
n, RTE_MAX_ETHPORTS);
- if (cmdline_parse_etheraddr(NULL, port_end, &peer_addr) < 0 )
+ if (cmdline_parse_etheraddr(NULL, port_end,
+ &peer_addr, sizeof(peer_addr)) < 0)
rte_exit(EXIT_FAILURE,
"Invalid ethernet address: %s\n",
port_end);
int ret = 0;
/* try all null */
- ret = cmdline_parse_etheraddr(NULL, NULL, NULL);
+ ret = cmdline_parse_etheraddr(NULL, NULL, NULL, 0);
if (ret != -1) {
printf("Error: parser accepted null parameters!\n");
return -1;
}
/* try null buf */
- ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result);
+ ret = cmdline_parse_etheraddr(NULL, NULL, (void*)&result,
+ sizeof(result));
if (ret != -1) {
printf("Error: parser accepted null string!\n");
return -1;
snprintf(buf, sizeof(buf), "%s",
ether_addr_valid_strs[0].str);
- ret = cmdline_parse_etheraddr(NULL, buf, NULL);
+ ret = cmdline_parse_etheraddr(NULL, buf, NULL, 0);
if (ret == -1) {
printf("Error: parser rejected null result!\n");
return -1;
memset(&result, 0, sizeof(struct ether_addr));
ret = cmdline_parse_etheraddr(NULL, ether_addr_invalid_strs[i],
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret != -1) {
printf("Error: parsing %s succeeded!\n",
ether_addr_invalid_strs[i]);
memset(&result, 0, sizeof(struct ether_addr));
ret = cmdline_parse_etheraddr(NULL, ether_addr_valid_strs[i].str,
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret < 0) {
printf("Error: parsing %s failed!\n",
ether_addr_valid_strs[i].str);
memset(&result, 0, sizeof(struct ether_addr));
ret = cmdline_parse_etheraddr(NULL, ether_addr_garbage_strs[i],
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret < 0) {
printf("Error: parsing %s failed!\n",
ether_addr_garbage_strs[i]);
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_valid_strs[i].str, (void*)&result);
+ ipaddr_valid_strs[i].str, (void*)&result,
+ sizeof(result));
/* if should have passed, or should have failed */
if ((ret < 0) ==
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_garbage_addr4_strs[i], (void*)&result);
+ ipaddr_garbage_addr4_strs[i], (void*)&result,
+ sizeof(result));
/* if should have passed, or should have failed */
if ((ret < 0) ==
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_garbage_addr6_strs[i], (void*)&result);
+ ipaddr_garbage_addr6_strs[i], (void*)&result,
+ sizeof(result));
/* if should have passed, or should have failed */
if ((ret < 0) ==
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_garbage_network4_strs[i], (void*)&result);
+ ipaddr_garbage_network4_strs[i], (void*)&result,
+ sizeof(result));
/* if should have passed, or should have failed */
if ((ret < 0) ==
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_garbage_network6_strs[i], (void*)&result);
+ ipaddr_garbage_network6_strs[i], (void*)&result,
+ sizeof(result));
/* if should have passed, or should have failed */
if ((ret < 0) ==
buf, sizeof(buf));
ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- ipaddr_invalid_strs[i], (void*)&result);
+ ipaddr_invalid_strs[i], (void*)&result,
+ sizeof(result));
if (ret != -1) {
printf("Error: parsing %s as %s succeeded!\n",
token.ipaddr_data.flags = CMDLINE_IPADDR_V4;
/* null token */
- if (cmdline_parse_ipaddr(NULL, buf, (void*)&result) != -1) {
+ if (cmdline_parse_ipaddr(NULL, buf, (void*)&result,
+ sizeof(result)) != -1) {
printf("Error: parser accepted invalid parameters!\n");
return -1;
}
/* null buffer */
if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- NULL, (void*)&result) != -1) {
+ NULL, (void*)&result, sizeof(result)) != -1) {
printf("Error: parser accepted invalid parameters!\n");
return -1;
}
/* empty buffer */
if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- "", (void*)&result) != -1) {
+ "", (void*)&result, sizeof(result)) != -1) {
printf("Error: parser accepted invalid parameters!\n");
return -1;
}
/* null result */
if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
- buf, NULL) == -1) {
+ buf, NULL, 0) == -1) {
printf("Error: parser rejected null result!\n");
return -1;
}
num_valid_positive_strs[0].str);
/* try all null */
- ret = cmdline_parse_num(NULL, NULL, NULL);
+ ret = cmdline_parse_num(NULL, NULL, NULL, 0);
if (ret != -1) {
printf("Error: parser accepted null parameters!\n");
return -1;
}
/* try null token */
- ret = cmdline_parse_num(NULL, buf, (void*)&result);
+ ret = cmdline_parse_num(NULL, buf, (void*)&result, sizeof(result));
if (ret != -1) {
printf("Error: parser accepted null token!\n");
return -1;
/* try null buf */
ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, NULL,
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret != -1) {
printf("Error: parser accepted null string!\n");
return -1;
}
/* try null result */
- ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, buf, NULL);
+ ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, buf,
+ NULL, 0);
if (ret == -1) {
printf("Error: parser rejected null result!\n");
return -1;
memset(&buf, 0, sizeof(buf));
ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token,
- num_invalid_strs[i], (void*)&result);
+ num_invalid_strs[i], (void*)&result, sizeof(result));
if (ret != -1) {
/* get some info about what we are trying to parse */
cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
buf, sizeof(buf));
- ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, num_valid_positive_strs[i].str,
- (void*)&result);
+ ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
+ num_valid_positive_strs[i].str,
+ (void*)&result, sizeof(result));
/* if it should have passed but didn't, or if it should have failed but didn't */
if ((ret < 0) == (can_parse_unsigned(num_valid_positive_strs[i].result, type) > 0)) {
cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
buf, sizeof(buf));
- ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, num_valid_negative_strs[i].str,
- (void*)&result);
+ ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
+ num_valid_negative_strs[i].str,
+ (void*)&result, sizeof(result));
/* if it should have passed but didn't, or if it should have failed but didn't */
if ((ret < 0) == (can_parse_signed(num_valid_negative_strs[i].result, type) > 0)) {
cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
buf, sizeof(buf));
- ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, num_garbage_positive_strs[i].str,
- (void*)&result);
+ ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
+ num_garbage_positive_strs[i].str,
+ (void*)&result, sizeof(result));
/* if it should have passed but didn't, or if it should have failed but didn't */
if ((ret < 0) == (can_parse_unsigned(num_garbage_positive_strs[i].result, type) > 0)) {
cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
buf, sizeof(buf));
- ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token, num_garbage_negative_strs[i].str,
- (void*)&result);
+ ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
+ num_garbage_negative_strs[i].str,
+ (void*)&result, sizeof(result));
/* if it should have passed but didn't, or if it should have failed but didn't */
if ((ret < 0) == (can_parse_signed(num_garbage_negative_strs[i].result, type) > 0)) {
memset(&result, 0, sizeof(cmdline_portlist_t));
/* try all null */
- ret = cmdline_parse_portlist(NULL, NULL, NULL);
+ ret = cmdline_parse_portlist(NULL, NULL, NULL, 0);
if (ret != -1) {
printf("Error: parser accepted null parameters!\n");
return -1;
}
/* try null buf */
- ret = cmdline_parse_portlist(NULL, NULL, (void*)&result);
+ ret = cmdline_parse_portlist(NULL, NULL, (void*)&result,
+ sizeof(result));
if (ret != -1) {
printf("Error: parser accepted null string!\n");
return -1;
}
/* try null result */
- ret = cmdline_parse_portlist(NULL, portlist_valid_strs[0].str, NULL);
+ ret = cmdline_parse_portlist(NULL, portlist_valid_strs[0].str, NULL, 0);
if (ret == -1) {
printf("Error: parser rejected null result!\n");
return -1;
memset(&result, 0, sizeof(cmdline_portlist_t));
ret = cmdline_parse_portlist(NULL, portlist_invalid_strs[i],
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret != -1) {
printf("Error: parsing %s succeeded!\n",
portlist_invalid_strs[i]);
memset(&result, 0, sizeof(cmdline_portlist_t));
ret = cmdline_parse_portlist(NULL, portlist_valid_strs[i].str,
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret < 0) {
printf("Error: parsing %s failed!\n",
portlist_valid_strs[i].str);
memset(&result, 0, sizeof(cmdline_portlist_t));
ret = cmdline_parse_portlist(NULL, portlist_garbage_strs[i],
- (void*)&result);
+ (void*)&result, sizeof(result));
if (ret < 0) {
printf("Error: parsing %s failed!\n",
portlist_garbage_strs[i]);
printf("Error: function accepted null token!\n");
return -1;
}
- if (cmdline_parse_string(NULL, buf, NULL) != -1) {
+ if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) {
printf("Error: function accepted null token!\n");
return -1;
}
return -1;
}
if (cmdline_parse_string(
- (cmdline_parse_token_hdr_t*)&token, NULL, (void*)&result) != -1) {
+ (cmdline_parse_token_hdr_t*)&token, NULL,
+ (void*)&result, sizeof(result)) != -1) {
printf("Error: function accepted null buffer!\n");
return -1;
}
}
/* test null result */
if (cmdline_parse_string(
- (cmdline_parse_token_hdr_t*)&token, buf, NULL) == -1) {
+ (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) {
printf("Error: function rejected null result!\n");
return -1;
}
token.string_data.str = string_invalid_strs[i].fixed_str;
if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
- string_invalid_strs[i].str, (void*)buf) != -1) {
+ string_invalid_strs[i].str, (void*)buf,
+ sizeof(buf)) != -1) {
memset(help_str, 0, sizeof(help_str));
memset(&help_token, 0, sizeof(help_token));
token.string_data.str = string_parse_strs[i].fixed_str;
if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
- string_parse_strs[i].str, (void*)buf) < 0) {
+ string_parse_strs[i].str, (void*)buf,
+ sizeof(buf)) < 0) {
/* clean help data */
memset(&help_token, 0, sizeof(help_token));
};
int
-parse_obj_list(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
+parse_obj_list(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
+ unsigned ressize)
{
struct token_obj_list *tk2 = (struct token_obj_list *)tk;
struct token_obj_list_data *tkd = &tk2->obj_list_data;
if (*buf == 0)
return -1;
+ if (res && ressize < sizeof(struct object *))
+ return -1;
+
while(!cmdline_isendoftoken(buf[token_len]))
token_len++;
extern struct cmdline_token_ops token_obj_list_ops;
-int parse_obj_list(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res);
+int parse_obj_list(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res,
+ unsigned ressize);
int complete_get_nb_obj_list(cmdline_parse_token_hdr_t *tk);
int complete_get_elt_obj_list(cmdline_parse_token_hdr_t *tk, int idx,
char *dstbuf, unsigned int size);
} __attribute__((packed));
int cmdline_parse_etheraddr(void *tk, const char *srcbuf,
- void *res);
+ void *res, unsigned ressize);
/* Map grant ref refid at addr_ori*/
static void *
if ((buf = xen_read_node(path, &len)) == NULL)
goto out;
- if (cmdline_parse_etheraddr(NULL, buf, &vring->addr) < 0)
+ if (cmdline_parse_etheraddr(NULL, buf, &vring->addr,
+ sizeof(vring->addr)) < 0)
goto out;
ret = 0;
out:
*/
static int
match_inst(cmdline_parse_inst_t *inst, const char *buf,
- unsigned int nb_match_token, void * result_buf)
+ unsigned int nb_match_token, void *resbuf, unsigned resbuf_size)
{
unsigned int token_num=0;
cmdline_parse_token_hdr_t * token_p;
if ( isendofline(*buf) || iscomment(*buf) )
break;
- if (result_buf)
- n = token_hdr.ops->parse(token_p, buf,
- (char *)result_buf +
- token_hdr.offset);
- else
- n = token_hdr.ops->parse(token_p, buf, NULL);
+ if (resbuf == NULL) {
+ n = token_hdr.ops->parse(token_p, buf, NULL, 0);
+ } else {
+ unsigned rb_sz;
+
+ if (token_hdr.offset > resbuf_size) {
+ printf("Parse error(%s:%d): Token offset(%u) "
+ "exceeds maximum size(%u)\n",
+ __FILE__, __LINE__,
+ token_hdr.offset, resbuf_size);
+ return -ENOBUFS;
+ }
+ rb_sz = resbuf_size - token_hdr.offset;
+
+ n = token_hdr.ops->parse(token_p, buf, (char *)resbuf +
+ token_hdr.offset, rb_sz);
+ }
if (n < 0)
break;
unsigned int inst_num=0;
cmdline_parse_inst_t *inst;
const char *curbuf;
- char result_buf[BUFSIZ];
+ char result_buf[CMDLINE_PARSE_RESULT_BUFSIZE];
void (*f)(void *, struct cmdline *, void *) = NULL;
void *data = NULL;
int comment = 0;
debug_printf("INST %d\n", inst_num);
/* fully parsed */
- tok = match_inst(inst, buf, 0, result_buf);
+ tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf));
if (tok > 0) /* we matched at least one token */
err = CMDLINE_PARSE_BAD_ARGS;
inst = ctx[inst_num];
while (inst) {
/* parse the first tokens of the inst */
- if (nb_token && match_inst(inst, buf, nb_token, NULL))
+ if (nb_token && match_inst(inst, buf, nb_token, NULL, 0))
goto next;
- debug_printf("instruction match \n");
+ debug_printf("instruction match\n");
token_p = inst->tokens[nb_token];
if (token_p)
memcpy(&token_hdr, token_p, sizeof(token_hdr));
/* we need to redo it */
inst = ctx[inst_num];
- if (nb_token && match_inst(inst, buf, nb_token, NULL))
+ if (nb_token && match_inst(inst, buf, nb_token, NULL, 0))
goto next2;
token_p = inst->tokens[nb_token];
#define CMDLINE_PARSE_COMPLETE_AGAIN 1
#define CMDLINE_PARSE_COMPLETED_BUFFER 2
+/* maximum buffer size for parsed result */
+#define CMDLINE_PARSE_RESULT_BUFSIZE 8192
+
/**
* Stores a pointer to the ops struct, and the offset: the place to
* write the parsed result in the destination structure.
* -1 on error and 0 on success.
*/
struct cmdline_token_ops {
- /** parse(token ptr, buf, res pts) */
- int (*parse)(cmdline_parse_token_hdr_t *, const char *, void *);
+ /** parse(token ptr, buf, res pts, buf len) */
+ int (*parse)(cmdline_parse_token_hdr_t *, const char *, void *,
+ unsigned int);
/** return the num of possible choices for this token */
int (*complete_get_nb)(cmdline_parse_token_hdr_t *);
/** return the elt x for this token (token, idx, dstbuf, size) */
- int (*complete_get_elt)(cmdline_parse_token_hdr_t *, int, char *, unsigned int);
+ int (*complete_get_elt)(cmdline_parse_token_hdr_t *, int, char *,
+ unsigned int);
/** get help for this token (token, dstbuf, size) */
int (*get_help)(cmdline_parse_token_hdr_t *, char *, unsigned int);
};
int
cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
- const char *buf, void *res)
+ const char *buf, void *res, unsigned ressize)
{
unsigned int token_len = 0;
char ether_str[ETHER_ADDRSTRLENLONG+1];
struct ether_addr *tmp;
+ if (res && ressize < sizeof(struct ether_addr))
+ return -1;
+
if (!buf || ! *buf)
return -1;
extern struct cmdline_token_ops cmdline_token_etheraddr_ops;
int cmdline_parse_etheraddr(cmdline_parse_token_hdr_t *tk, const char *srcbuf,
- void *res);
+ void *res, unsigned ressize);
int cmdline_get_help_etheraddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
- unsigned int size);
+ unsigned int size);
#define TOKEN_ETHERADDR_INITIALIZER(structure, field) \
{ \
}
int
-cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
+cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
+ unsigned ressize)
{
struct cmdline_token_ipaddr *tk2;
unsigned int token_len = 0;
char *prefix, *prefix_end;
long prefixlen = 0;
+ if (res && ressize < sizeof(cmdline_ipaddr_t))
+ return -1;
+
if (!buf || !tk || ! *buf)
return -1;
extern struct cmdline_token_ops cmdline_token_ipaddr_ops;
int cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *srcbuf,
- void *res);
+ void *res, unsigned ressize);
int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
- unsigned int size);
+ unsigned int size);
#define TOKEN_IPADDR_INITIALIZER(structure, field) \
{ \
return 0;
}
+static int
+check_res_size(struct cmdline_token_num_data *nd, unsigned ressize)
+{
+ switch (nd->type) {
+ case INT8:
+ case UINT8:
+ if (ressize < sizeof(int8_t))
+ return -1;
+ break;
+ case INT16:
+ case UINT16:
+ if (ressize < sizeof(int16_t))
+ return -1;
+ break;
+ case INT32:
+ case UINT32:
+ if (ressize < sizeof(int32_t))
+ return -1;
+ break;
+ case INT64:
+ case UINT64:
+ if (ressize < sizeof(int64_t))
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
/* parse an int */
int
-cmdline_parse_num(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res)
+cmdline_parse_num(cmdline_parse_token_hdr_t *tk, const char *srcbuf, void *res,
+ unsigned ressize)
{
struct cmdline_token_num_data nd;
enum num_parse_state_t st = START;
memcpy(&nd, &((struct cmdline_token_num *)tk)->num_data, sizeof(nd));
+ /* check that we have enough room in res */
+ if (res) {
+ if (check_res_size(&nd, ressize) < 0)
+ return -1;
+ }
+
while ( st != ERROR && c && ! cmdline_isendoftoken(c) ) {
debug_printf("%c %x -> ", c, c);
switch (st) {
extern struct cmdline_token_ops cmdline_token_num_ops;
int cmdline_parse_num(cmdline_parse_token_hdr_t *tk,
- const char *srcbuf, void *res);
+ const char *srcbuf, void *res, unsigned ressize);
int cmdline_get_help_num(cmdline_parse_token_hdr_t *tk,
- char *dstbuf, unsigned int size);
+ char *dstbuf, unsigned int size);
#define TOKEN_NUM_INITIALIZER(structure, field, numtype) \
{ \
int
cmdline_parse_portlist(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
- const char *buf, void *res)
+ const char *buf, void *res, unsigned ressize)
{
unsigned int token_len = 0;
char portlist_str[PORTLIST_TOKEN_SIZE+1];
if (!buf || ! *buf)
return (-1);
+ if (res && ressize < PORTLIST_TOKEN_SIZE)
+ return -1;
+
pl = res;
while (!cmdline_isendoftoken(buf[token_len]) &&
extern struct cmdline_token_ops cmdline_token_portlist_ops;
int cmdline_parse_portlist(cmdline_parse_token_hdr_t *tk,
- const char *srcbuf, void *res);
+ const char *srcbuf, void *res, unsigned ressize);
int cmdline_get_help_portlist(cmdline_parse_token_hdr_t *tk,
- char *dstbuf, unsigned int size);
+ char *dstbuf, unsigned int size);
#define TOKEN_PORTLIST_INITIALIZER(structure, field) \
{ \
}
int
-cmdline_parse_string(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
+cmdline_parse_string(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
+ unsigned ressize)
{
struct cmdline_token_string *tk2;
struct cmdline_token_string_data *sd;
unsigned int token_len;
const char *str;
+ if (res && ressize < STR_TOKEN_SIZE)
+ return -1;
+
if (!tk || !buf || ! *buf)
return -1;
extern struct cmdline_token_ops cmdline_token_string_ops;
int cmdline_parse_string(cmdline_parse_token_hdr_t *tk, const char *srcbuf,
- void *res);
+ void *res, unsigned ressize);
int cmdline_complete_get_nb_string(cmdline_parse_token_hdr_t *tk);
int cmdline_complete_get_elt_string(cmdline_parse_token_hdr_t *tk, int idx,
char *dstbuf, unsigned int size);
return -1;
/* Parse MAC */
- return cmdline_parse_etheraddr(NULL, value, extra_args);
+ return cmdline_parse_etheraddr(NULL, value, extra_args,
+ sizeof(struct ether_addr));
}
int