I am not sure either is right.
The string may begin with an arbitrary amount of whitespace (as
determined by isspace(3)) followed by a single optional `+' or `-' sign.
What about the '+' sign case?
Klemens Nanni <[email protected]> wrote:
> strtonum(3) is simpler than checking three cases for `q' and gives nicer
> error messages. While here, use `v6mask' as maximum netmask instead of
> hardcoding it.
>
> OK?
>
> Index: pfctl_parser.c
> ===================================================================
> RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
> retrieving revision 1.321
> diff -u -p -r1.321 pfctl_parser.c
> --- pfctl_parser.c 10 Jul 2018 09:30:49 -0000 1.321
> +++ pfctl_parser.c 21 Jul 2018 18:44:57 -0000
> @@ -1635,7 +1635,8 @@ host(const char *s, int opts)
> {
> struct node_host *h = NULL, *n;
> int mask = -1, v4mask = 32, v6mask = 128, cont = 1;
> - char *p, *q, *r, *ps, *if_name;
> + char *p, *r, *ps, *if_name;
> + const char *errstr;
>
> if ((ps = strdup(s)) == NULL)
> err(1, "host: strdup");
> @@ -1648,9 +1649,9 @@ host(const char *s, int opts)
> if ((p = strrchr(ps, '/')) != NULL) {
> if ((r = strdup(ps)) == NULL)
> err(1, "host: strdup");
> - mask = strtol(p+1, &q, 0);
> - if (!q || *q || mask > 128 || q == (p+1)) {
> - fprintf(stderr, "invalid netmask '%s'\n", p);
> + mask = strtonum(p+1, 0, v6mask, &errstr);
> + if (errstr) {
> + fprintf(stderr, "netmask is %s: %s\n", errstr, p);
> free(r);
> free(ps);
> return (NULL);
> Index: pfail40.ok
> ===================================================================
> RCS file: /cvs/src/regress/sbin/pfctl/pfail40.ok,v
> retrieving revision 1.3
> diff -u -p -r1.3 pfail40.ok
> --- pfail40.ok 1 Oct 2004 04:33:27 -0000 1.3
> +++ pfail40.ok 21 Jul 2018 18:45:45 -0000
> @@ -1,4 +1,4 @@
> -invalid netmask '/161'
> +netmask is too large: /161
> stdin:2: could not parse host specification
> -invalid netmask '/161'
> +netmask is too large: /161
> stdin:3: could not parse host specification
>