security/sandbox/chromium/base/third_party/icu/icu_utf.cc

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /*
     2 ******************************************************************************
     3 *
     4 *   Copyright (C) 1999-2006, International Business Machines
     5 *   Corporation and others.  All Rights Reserved.
     6 *
     7 ******************************************************************************
     8 *   file name:  utf_impl.c
     9 *   encoding:   US-ASCII
    10 *   tab size:   8 (not used)
    11 *   indentation:4
    12 *
    13 *   created on: 1999sep13
    14 *   created by: Markus W. Scherer
    15 *
    16 *   This file provides implementation functions for macros in the utfXX.h
    17 *   that would otherwise be too long as macros.
    18 */
    20 #include "base/third_party/icu/icu_utf.h"
    22 namespace base_icu {
    24 /**
    25  * UTF8_ERROR_VALUE_1 and UTF8_ERROR_VALUE_2 are special error values for UTF-8,
    26  * which need 1 or 2 bytes in UTF-8:
    27  * \code
    28  * U+0015 = NAK = Negative Acknowledge, C0 control character
    29  * U+009f = highest C1 control character
    30  * \endcode
    31  *
    32  * These are used by UTF8_..._SAFE macros so that they can return an error value
    33  * that needs the same number of code units (bytes) as were seen by
    34  * a macro. They should be tested with UTF_IS_ERROR() or UTF_IS_VALID().
    35  *
    36  * @deprecated ICU 2.4. Obsolete, see utf_old.h.
    37  */
    38 #define CBUTF8_ERROR_VALUE_1 0x15
    40 /**
    41  * See documentation on UTF8_ERROR_VALUE_1 for details.
    42  *
    43  * @deprecated ICU 2.4. Obsolete, see utf_old.h.
    44  */
    45 #define CBUTF8_ERROR_VALUE_2 0x9f
    48 /**
    49  * Error value for all UTFs. This code point value will be set by macros with e>
    50  * checking if an error is detected.
    51  *
    52  * @deprecated ICU 2.4. Obsolete, see utf_old.h.
    53  */
    54 #define CBUTF_ERROR_VALUE 0xffff
    56 /*
    57  * This table could be replaced on many machines by
    58  * a few lines of assembler code using an
    59  * "index of first 0-bit from msb" instruction and
    60  * one or two more integer instructions.
    61  *
    62  * For example, on an i386, do something like
    63  * - MOV AL, leadByte
    64  * - NOT AL         (8-bit, leave b15..b8==0..0, reverse only b7..b0)
    65  * - MOV AH, 0
    66  * - BSR BX, AX     (16-bit)
    67  * - MOV AX, 6      (result)
    68  * - JZ finish      (ZF==1 if leadByte==0xff)
    69  * - SUB AX, BX (result)
    70  * -finish:
    71  * (BSR: Bit Scan Reverse, scans for a 1-bit, starting from the MSB)
    72  *
    73  * In Unicode, all UTF-8 byte sequences with more than 4 bytes are illegal;
    74  * lead bytes above 0xf4 are illegal.
    75  * We keep them in this table for skipping long ISO 10646-UTF-8 sequences.
    76  */
    77 const uint8
    78 utf8_countTrailBytes[256]={
    79     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    80     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    81     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    82     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    84     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    85     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    86     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    87     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    89     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    90     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    91     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    92     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    94     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    95     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    97     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    98     3, 3, 3, 3, 3,
    99     3, 3, 3,    /* illegal in Unicode */
   100     4, 4, 4, 4, /* illegal in Unicode */
   101     5, 5,       /* illegal in Unicode */
   102     0, 0        /* illegal bytes 0xfe and 0xff */
   103 };
   105 static const UChar32
   106 utf8_minLegal[4]={ 0, 0x80, 0x800, 0x10000 };
   108 static const UChar32
   109 utf8_errorValue[6]={
   110     CBUTF8_ERROR_VALUE_1, CBUTF8_ERROR_VALUE_2, CBUTF_ERROR_VALUE, 0x10ffff,
   111     0x3ffffff, 0x7fffffff
   112 };
   114 /*
   115  * Handle the non-inline part of the U8_NEXT() macro and its obsolete sibling
   116  * UTF8_NEXT_CHAR_SAFE().
   117  *
   118  * The "strict" parameter controls the error behavior:
   119  * <0  "Safe" behavior of U8_NEXT(): All illegal byte sequences yield a negative
   120  *     code point result.
   121  *  0  Obsolete "safe" behavior of UTF8_NEXT_CHAR_SAFE(..., FALSE):
   122  *     All illegal byte sequences yield a positive code point such that this
   123  *     result code point would be encoded with the same number of bytes as
   124  *     the illegal sequence.
   125  * >0  Obsolete "strict" behavior of UTF8_NEXT_CHAR_SAFE(..., TRUE):
   126  *     Same as the obsolete "safe" behavior, but non-characters are also treated
   127  *     like illegal sequences.
   128  *
   129  * The special negative (<0) value -2 is used for lenient treatment of surrogate
   130  * code points as legal. Some implementations use this for roundtripping of
   131  * Unicode 16-bit strings that are not well-formed UTF-16, that is, they
   132  * contain unpaired surrogates.
   133  *
   134  * Note that a UBool is the same as an int8_t.
   135  */
   136 UChar32
   137 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c, UBool strict) {
   138     int32 i=*pi;
   139     uint8 count=CBU8_COUNT_TRAIL_BYTES(c);
   140     if((i)+count<=(length)) {
   141         uint8 trail, illegal=0;
   143         CBU8_MASK_LEAD_BYTE((c), count);
   144         /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
   145         switch(count) {
   146         /* each branch falls through to the next one */
   147         case 5:
   148         case 4:
   149             /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */
   150             illegal=1;
   151             break;
   152         case 3:
   153             trail=s[(i)++];
   154             (c)=((c)<<6)|(trail&0x3f);
   155             if(c<0x110) {
   156                 illegal|=(trail&0xc0)^0x80;
   157             } else {
   158                 /* code point>0x10ffff, outside Unicode */
   159                 illegal=1;
   160                 break;
   161             }
   162         case 2:
   163             trail=s[(i)++];
   164             (c)=((c)<<6)|(trail&0x3f);
   165             illegal|=(trail&0xc0)^0x80;
   166         case 1:
   167             trail=s[(i)++];
   168             (c)=((c)<<6)|(trail&0x3f);
   169             illegal|=(trail&0xc0)^0x80;
   170             break;
   171         case 0:
   172             if(strict>=0) {
   173                 return CBUTF8_ERROR_VALUE_1;
   174             } else {
   175                 return CBU_SENTINEL;
   176             }
   177         /* no default branch to optimize switch()  - all values are covered */
   178         }
   180         /*
   181          * All the error handling should return a value
   182          * that needs count bytes so that UTF8_GET_CHAR_SAFE() works right.
   183          *
   184          * Starting with Unicode 3.0.1, non-shortest forms are illegal.
   185          * Starting with Unicode 3.2, surrogate code points must not be
   186          * encoded in UTF-8, and there are no irregular sequences any more.
   187          *
   188          * U8_ macros (new in ICU 2.4) return negative values for error conditions.
   189          */
   191         /* correct sequence - all trail bytes have (b7..b6)==(10)? */
   192         /* illegal is also set if count>=4 */
   193         if(illegal || (c)<utf8_minLegal[count] || (CBU_IS_SURROGATE(c) && strict!=-2)) {
   194             /* error handling */
   195             uint8 errorCount=count;
   196             /* don't go beyond this sequence */
   197             i=*pi;
   198             while(count>0 && CBU8_IS_TRAIL(s[i])) {
   199                 ++(i);
   200                 --count;
   201             }
   202             if(strict>=0) {
   203                 c=utf8_errorValue[errorCount-count];
   204             } else {
   205                 c=CBU_SENTINEL;
   206             }
   207         } else if((strict)>0 && CBU_IS_UNICODE_NONCHAR(c)) {
   208             /* strict: forbid non-characters like U+fffe */
   209             c=utf8_errorValue[count];
   210         }
   211     } else /* too few bytes left */ {
   212         /* error handling */
   213         int32 i0=i;
   214         /* don't just set (i)=(length) in case there is an illegal sequence */
   215         while((i)<(length) && CBU8_IS_TRAIL(s[i])) {
   216             ++(i);
   217         }
   218         if(strict>=0) {
   219             c=utf8_errorValue[i-i0];
   220         } else {
   221             c=CBU_SENTINEL;
   222         }
   223     }
   224     *pi=i;
   225     return c;
   226 }
   228 }  // namespace base_icu

mercurial