Author: araujo
Date: Mon May 16 02:44:22 2016
New Revision: 299887
URL: https://svnweb.freebsd.org/changeset/base/299887

Log:
  Simplify overengineered and buggy code that looked like as if it did
  some kind of UTF-8 validation, but actually didn't, but instead, for
  malformed UTF-8 input, caused buffer overruns in some cases and caused
  skipping of valid ASCII characters in other cases.
  
  Obtained from:        OpenBSD (cvs 1.32)

Modified:
  head/usr.sbin/ypldap/aldap.c

Modified: head/usr.sbin/ypldap/aldap.c
==============================================================================
--- head/usr.sbin/ypldap/aldap.c        Mon May 16 02:42:53 2016        
(r299886)
+++ head/usr.sbin/ypldap/aldap.c        Mon May 16 02:44:22 2016        
(r299887)
@@ -1,6 +1,6 @@
-/*     $Id: aldap.c,v 1.30 2012/04/30 21:40:03 jmatthew Exp $ */
-/*     $OpenBSD: aldap.c,v 1.30 2012/04/30 21:40:03 jmatthew Exp $ */
 /*     $FreeBSD$ */
+/*     $Id: aldap.c,v 1.32 2016/04/27 10:53:27 schwarze Exp $ */
+/*     $OpenBSD: aldap.c,v 1.32 2016/04/27 10:53:27 schwarze Exp $ */
 
 /*
  * Copyright (c) 2008 Alexander Schrijver <aschrij...@openbsd.org>
@@ -19,6 +19,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <ctype.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <string.h>
@@ -38,6 +39,7 @@ static struct ber_element     *ldap_do_parse
                                    struct ber_element *, char **);
 char                           **aldap_get_stringset(struct ber_element *);
 char                           *utoa(char *);
+static int                      isu8cont(unsigned char);
 char                           *parseval(char *, size_t);
 int                            aldap_create_page_control(struct ber_element *,
                                    int, struct aldap_page_control *);
@@ -1161,7 +1163,7 @@ ldap_debug_elements(struct ber_element *
 #endif
 
 /*
- * Convert UTF-8 to ASCII.
+ * Strip UTF-8 down to ASCII without validation.
  * notes:
  *     non-ASCII characters are displayed as '?'
  *     the argument u should be a NULL terminated sequence of UTF-8 bytes.
@@ -1173,41 +1175,27 @@ utoa(char *u)
        char    *str;
 
        /* calculate the length to allocate */
-       for (len = 0, i = 0; u[i] != '\0'; ) {
-               if ((u[i] & 0xF0) == 0xF0)
-                       i += 4;
-               else if ((u[i] & 0xE0) == 0xE0)
-                       i += 3;
-               else if ((u[i] & 0xC0) == 0xC0)
-                       i += 2;
-               else
-                       i += 1;
-               len++;
-       }
+       for (len = 0, i = 0; u[i] != '\0'; i++)
+               if (!isu8cont(u[i]))
+                       len++;
 
        if ((str = calloc(len + 1, sizeof(char))) == NULL)
                return NULL;
 
        /* copy the ASCII characters to the newly allocated string */
-       for (i = 0, j = 0; u[i] != '\0'; j++) {
-               if ((u[i] & 0xF0) == 0xF0) {
-                       str[j] = '?';
-                       i += 4;
-               } else if ((u[i] & 0xE0) == 0xE0) {
-                       str[j] = '?';
-                       i += 3;
-               } else if ((u[i] & 0xC0) == 0xC0) {
-                       str[j] = '?';
-                       i += 2;
-               } else {
-                       str[j] =  u[i];
-                       i += 1;
-               }
-       }
+       for (i = 0, j = 0; u[i] != '\0'; i++)
+               if (!isu8cont(u[i]))
+                       str[j++] = isascii((unsigned char)u[i]) ? u[i] : '?';
 
        return str;
 }
 
+static int
+isu8cont(unsigned char c)
+{
+       return (c & (0x80 | 0x40)) == 0x80;
+}
+
 /*
  * Parse a LDAP value
  * notes:
@@ -1270,3 +1258,4 @@ aldap_get_errno(struct aldap *a, const c
        }
        return (a->err);
 }
+
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to