On Sat, 10 Oct 2015, Michael McConville wrote:
...
> FWIW, this is a perfect use case for Coccinelle. Below is what I dredged
> up in src/usr.sbin (diff not yet carefully audited, but apparently
> sane).

I'm replying to this multiple times, cc'ing in the particular maintainers 
as appropriate.


> --- httpd/httpd.c
> +++ /tmp/cocci-output-27324-3d6efb-httpd.c
> @@ -602,7 +602,7 @@ url_decode(char *url)
>               switch (*p) {
>               case '%':
>                       /* Encoding character is followed by two hex chars */
> -                     if (!(isxdigit(p[1]) && isxdigit(p[2])))
> +                     if (!(isxdigit((unsigned char)p[1]) && 
> isxdigit((unsigned char)p[2])))

Needs line wrapping, and I think it reads better if De Morgan's law is
applied to make it:
                        if (!isxdigit((unsigned char)p[1]) ||
                            !isxdigit((unsigned char)p[2]))

(also indents nicer that way...)


> --- httpd/server_http.c
> +++ /tmp/cocci-output-27324-ad673b-server_http.c
> @@ -918,7 +918,7 @@ server_expand_http(struct client *clt, c
>       /* Find previously matched substrings by index */
>       for (p = val; clt->clt_srv_match.sm_nmatch &&
>           (p = strstr(p, "%")) != NULL; p++) {
> -             if (!isdigit(*(p + 1)))
> +             if (!isdigit((unsigned char)*(p + 1)))

I think that should be changed to use array indexing:
                if (!isdigit((unsigned char)p[1]))

oks?


Philip


Index: usr.sbin/httpd/httpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.c,v
retrieving revision 1.39
diff -u -p -r1.39 httpd.c
--- usr.sbin/httpd/httpd.c      20 Aug 2015 13:00:23 -0000      1.39
+++ usr.sbin/httpd/httpd.c      11 Oct 2015 02:29:33 -0000
@@ -602,7 +602,8 @@ url_decode(char *url)
                switch (*p) {
                case '%':
                        /* Encoding character is followed by two hex chars */
-                       if (!(isxdigit(p[1]) && isxdigit(p[2])))
+                       if (!isxdigit((unsigned char)p[1]) ||
+                           !isxdigit((unsigned char)p[2]))
                                return (NULL);
 
                        hex[0] = p[1];
Index: usr.sbin/httpd/server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.99
diff -u -p -r1.99 server_http.c
--- usr.sbin/httpd/server_http.c        7 Sep 2015 14:46:24 -0000       1.99
+++ usr.sbin/httpd/server_http.c        11 Oct 2015 02:29:33 -0000
@@ -918,7 +918,7 @@ server_expand_http(struct client *clt, c
        /* Find previously matched substrings by index */
        for (p = val; clt->clt_srv_match.sm_nmatch &&
            (p = strstr(p, "%")) != NULL; p++) {
-               if (!isdigit(*(p + 1)))
+               if (!isdigit((unsigned char)p[1]))
                        continue;
 
                /* Copy number, leading '%' char and add trailing \0 */

Reply via email to