mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-27 16:11:03 +00:00
MINOR: arg: improve error reporting on invalid arguments
It's important to report the faulty argument position and to distinguish between empty arguments and wrong ones. Integers were not properly tested either, now their parsing has been improved to report use of incorrect characters.
This commit is contained in:
parent
b7451bb660
commit
4e6336fdfd
61
src/arg.c
61
src/arg.c
@ -97,12 +97,15 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
switch (arg->type) {
|
||||
case ARGT_SINT:
|
||||
if (in == beg) // empty number
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
else if (*beg < '0' || *beg > '9') {
|
||||
arg->data.sint = strl2uic(beg + 1, in - beg - 1);
|
||||
if (*beg == '-')
|
||||
beg++;
|
||||
arg->data.sint = read_uint(&beg, in);
|
||||
if (beg < in)
|
||||
goto parse_err;
|
||||
if (*word == '-')
|
||||
arg->data.sint = -arg->data.sint;
|
||||
else if (*beg != '+') // invalid first character
|
||||
else if (*word != '+') // invalid first character
|
||||
goto parse_err;
|
||||
break;
|
||||
}
|
||||
@ -112,9 +115,11 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
case ARGT_UINT:
|
||||
if (in == beg) // empty number
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
arg->data.uint = strl2uic(beg, in - beg);
|
||||
arg->data.uint = read_uint(&beg, in);
|
||||
if (beg < in)
|
||||
goto parse_err;
|
||||
break;
|
||||
|
||||
case ARGT_FE:
|
||||
@ -135,7 +140,7 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
case ARGT_IPV4:
|
||||
if (in == beg) // empty address
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
if (inet_pton(AF_INET, word, &arg->data.ipv4) <= 0)
|
||||
goto parse_err;
|
||||
@ -143,7 +148,7 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
case ARGT_MSK4:
|
||||
if (in == beg) // empty mask
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
if (!str2mask(word, &arg->data.ipv4))
|
||||
goto parse_err;
|
||||
@ -153,18 +158,18 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
case ARGT_IPV6:
|
||||
if (in == beg) // empty address
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
if (inet_pton(AF_INET6, word, &arg->data.ipv6) <= 0)
|
||||
goto parse_err;
|
||||
break;
|
||||
|
||||
case ARGT_MSK6: /* not yet implemented */
|
||||
goto parse_err;
|
||||
goto not_impl;
|
||||
|
||||
case ARGT_TIME:
|
||||
if (in == beg) // empty time
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
ptr_err = parse_time_err(word, &arg->data.uint, TIME_UNIT_MS);
|
||||
if (ptr_err)
|
||||
@ -175,7 +180,7 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
case ARGT_SIZE:
|
||||
if (in == beg) // empty size
|
||||
goto parse_err;
|
||||
goto empty_err;
|
||||
|
||||
ptr_err = parse_size_err(word, &arg->data.uint);
|
||||
if (ptr_err)
|
||||
@ -186,7 +191,7 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
|
||||
/* FIXME: other types need to be implemented here */
|
||||
default:
|
||||
goto parse_err;
|
||||
goto not_impl;
|
||||
}
|
||||
|
||||
pos++;
|
||||
@ -217,7 +222,8 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
if (err_msg) {
|
||||
/* the caller is responsible for freeing this message */
|
||||
word = my_strndup(in, len);
|
||||
memprintf(err_msg, "End of arguments expected at '%s'", word);
|
||||
memprintf(err_msg, "end of arguments expected at position %d, but got '%s'",
|
||||
pos + 1, word);
|
||||
free(word); word = NULL;
|
||||
}
|
||||
goto err;
|
||||
@ -234,12 +240,6 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
*err_ptr = in;
|
||||
return pos;
|
||||
|
||||
parse_err:
|
||||
if (err_msg) {
|
||||
memprintf(err_msg, "Failed to parse '%s' as type '%s'",
|
||||
word, arg_type_names[(mask >> (pos * 4)) & 15]);
|
||||
}
|
||||
|
||||
err:
|
||||
free(word);
|
||||
free(arg_list);
|
||||
@ -248,4 +248,25 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
|
||||
if (err_ptr)
|
||||
*err_ptr = in;
|
||||
return -1;
|
||||
|
||||
empty_err:
|
||||
if (err_msg) {
|
||||
memprintf(err_msg, "expected type '%s' at position %d, but got nothing",
|
||||
arg_type_names[(mask >> (pos * 4)) & 15], pos + 1);
|
||||
}
|
||||
goto err;
|
||||
|
||||
parse_err:
|
||||
if (err_msg) {
|
||||
memprintf(err_msg, "failed to parse '%s' as type '%s' at position %d",
|
||||
word, arg_type_names[(mask >> (pos * 4)) & 15], pos + 1);
|
||||
}
|
||||
goto err;
|
||||
|
||||
not_impl:
|
||||
if (err_msg) {
|
||||
memprintf(err_msg, "parsing for type '%s' was not implemented, please report this bug",
|
||||
arg_type_names[(mask >> (pos * 4)) & 15]);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user