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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial