]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/vfs/vfs_utfconv.c
xnu-517.9.5.tar.gz
[apple/xnu.git] / bsd / vfs / vfs_utfconv.c
index 7d2e88396d9c7142363d790f656a2bc86c902d43..7c2f193f40cbd0e27b87ebec85e8737fa3a2ae8b 100644 (file)
@@ -3,22 +3,19 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -317,8 +314,8 @@ utf8_decodestr(const u_int8_t* utf8p, size_t utf8len, u_int16_t* ucsp,
 {
        u_int16_t* bufstart;
        u_int16_t* bufend;
-       u_int16_t ucs_ch;
-       u_int8_t byte;
+       unsigned int ucs_ch;
+       unsigned int byte;
        int result = 0;
        int decompose, precompose, swapbytes;
 
@@ -335,7 +332,7 @@ utf8_decodestr(const u_int8_t* utf8p, size_t utf8len, u_int16_t* ucsp,
 
                /* check for ascii */
                if (byte < 0x80) {
-                       ucs_ch = byte;                          /* 1st byte */
+                       ucs_ch = byte;                 /* 1st byte */
                } else {
                        u_int32_t ch;
                        int extrabytes = utf_extrabytes[byte >> 3];
@@ -345,44 +342,66 @@ utf8_decodestr(const u_int8_t* utf8p, size_t utf8len, u_int16_t* ucsp,
                        utf8len -= extrabytes;
 
                        switch (extrabytes) {
-                       case 1: ch = byte;                      /* 1st byte */
-                                       ch <<= 6;
-                               ch += *utf8p++;         /* 2nd byte */
-                                       ch -= 0x00003080UL;
-                                       if (ch < 0x0080)
-                                               goto invalid;
-                                       ucs_ch = ch;
+                       case 1:
+                               ch = byte; ch <<= 6;   /* 1st byte */
+                               byte = *utf8p++;       /* 2nd byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte;
+                               ch -= 0x00003080UL;
+                               if (ch < 0x0080)
+                                       goto invalid;
+                               ucs_ch = ch;
                                break;
-
-                       case 2: ch = byte;                      /* 1st byte */
-                                       ch <<= 6;
-                                       ch += *utf8p++;         /* 2nd byte */
-                                       ch <<= 6;
-                                       ch += *utf8p++;         /* 3rd byte */
-                                       ch -= 0x000E2080UL;
-                                       if (ch < 0x0800)
+                       case 2:
+                               ch = byte; ch <<= 6;   /* 1st byte */
+                               byte = *utf8p++;       /* 2nd byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte; ch <<= 6;
+                               byte = *utf8p++;       /* 3rd byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte;
+                               ch -= 0x000E2080UL;
+                               if (ch < 0x0800)
+                                       goto invalid;
+                               if (ch >= 0xD800) {
+                                       if (ch <= 0xDFFF)
+                                               goto invalid;
+                                       if (ch == 0xFFFE || ch == 0xFFFF)
                                                goto invalid;
-                                       ucs_ch = ch;
-                                       break;
-
-                       case 3: ch = byte;                      /* 1st byte */
-                                       ch <<= 6;
-                                       ch += *utf8p++;         /* 2nd byte */
-                                       ch <<= 6;
-                                       ch += *utf8p++;         /* 3rd byte */
-                                       ch <<= 6;
-                               ch += *utf8p++;         /* 4th byte */
-                                       ch -= 0x03C82080UL + SP_HALF_BASE;
-                                       ucs_ch = (ch >> SP_HALF_SHIFT) + SP_HIGH_FIRST;
-                                       *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
-                                       if (ucsp >= bufend)
-                                               goto toolong;
-                                       ucs_ch = (ch & SP_HALF_MASK) + SP_LOW_FIRST;
-                                       *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
+                               }
+                               ucs_ch = ch;
+                               break;
+                       case 3:
+                               ch = byte; ch <<= 6;   /* 1st byte */
+                               byte = *utf8p++;       /* 2nd byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte; ch <<= 6;
+                               byte = *utf8p++;       /* 3rd byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte; ch <<= 6;
+                               byte = *utf8p++;       /* 4th byte */
+                               if ((byte >> 6) != 2)
+                                       goto invalid;
+                               ch += byte;
+                               ch -= 0x03C82080UL + SP_HALF_BASE;
+                               ucs_ch = (ch >> SP_HALF_SHIFT) + SP_HIGH_FIRST;
+                               if (ucs_ch < SP_HIGH_FIRST || ucs_ch > SP_HIGH_LAST)
+                                       goto invalid;
+                               *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
+                               if (ucsp >= bufend)
+                                       goto toolong;
+                               ucs_ch = (ch & SP_HALF_MASK) + SP_LOW_FIRST;
+                               if (ucs_ch < SP_LOW_FIRST || ucs_ch > SP_LOW_LAST)
+                                       goto invalid;
+                               *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
                                continue;
-
                        default:
-                                       goto invalid;
+                               goto invalid;
                        }
                        if (decompose) {
                                if (unicode_decomposeable(ucs_ch)) {