1 /* 2 __ __ _ 3 ___\ \/ /_ __ __ _| |_ 4 / _ \\ /| '_ \ / _` | __| 5 | __// \| |_) | (_| | |_ 6 \___/_/\_\ .__/ \__,_|\__| 7 |_| XML parser 8 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> 13 Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 14 Copyright (c) 2005-2009 Steven Solie <steven@solie.ca> 15 Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org> 16 Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> 17 Copyright (c) 2016 Don Lewis <truckman@apache.org> 18 Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> 19 Copyright (c) 2017 Alexander Bluhm <alexander.bluhm@gmx.net> 20 Copyright (c) 2017 Benbuck Nason <bnason@netflix.com> 21 Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> 22 Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 23 Copyright (c) 2021 Donghee Na <donghee.na@python.org> 24 Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com> 25 Copyright (c) 2022 Sean McBride <sean@rogue-research.com> 26 Copyright (c) 2023 Hanno Böck <hanno@gentoo.org> 27 Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com> 28 Copyright (c) 2026 Nick Begg <nick@stunttruck.net> 29 Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com> 30 Copyright (c) 2026 Afonso Januário <afonso-januario@hotmail.com> 31 Licensed under the MIT license: 32 33 Permission is hereby granted, free of charge, to any person obtaining 34 a copy of this software and associated documentation files (the 35 "Software"), to deal in the Software without restriction, including 36 without limitation the rights to use, copy, modify, merge, publish, 37 distribute, sublicense, and/or sell copies of the Software, and to permit 38 persons to whom the Software is furnished to do so, subject to the 39 following conditions: 40 41 The above copyright notice and this permission notice shall be included 42 in all copies or substantial portions of the Software. 43 44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 45 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 46 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 47 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 48 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 49 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 50 USE OR OTHER DEALINGS IN THE SOFTWARE. 51 52 SPDX-License-Identifier: MIT 53 */ 54 55 #include "expat_config.h" 56 57 #include <stddef.h> 58 #include <string.h> /* memcpy */ 59 #include <stdbool.h> 60 61 #ifdef _WIN32 62 # include "winconfig.h" 63 #endif 64 65 #include "internal.h" 66 #include "fallthrough.h" 67 #include "xmltok.h" 68 #include "nametab.h" 69 70 #ifdef XML_DTD 71 # define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) 72 #else 73 # define IGNORE_SECTION_TOK_VTABLE /* as nothing */ 74 #endif 75 76 #define VTABLE1 \ 77 {PREFIX(prologTok), PREFIX(contentTok), \ 78 PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ 79 {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \ 80 PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \ 81 PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \ 82 PREFIX(updatePosition), PREFIX(isPublicId) 83 84 #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) 85 86 #define UCS2_GET_NAMING(pages, hi, lo) \ 87 (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) 88 89 /* A 2 byte UTF-8 representation splits the characters 11 bits between 90 the bottom 5 and 6 bits of the bytes. We need 8 bits to index into 91 pages, 3 bits to add to that index and 5 bits to generate the mask. 92 */ 93 #define UTF8_GET_NAMING2(pages, byte) \ 94 (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ 95 + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ 96 & (1u << (((byte)[1]) & 0x1F))) 97 98 /* A 3 byte UTF-8 representation splits the characters 16 bits between 99 the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index 100 into pages, 3 bits to add to that index and 5 bits to generate the 101 mask. 102 */ 103 #define UTF8_GET_NAMING3(pages, byte) \ 104 (namingBitmap \ 105 [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ 106 << 3) \ 107 + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ 108 & (1u << (((byte)[2]) & 0x1F))) 109 110 /* Detection of invalid UTF-8 sequences is based on Table 3.1B 111 of Unicode 3.2: https://www.unicode.org/unicode/reports/tr28/ 112 with the additional restriction of not allowing the Unicode 113 code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). 114 Implementation details: 115 (A & 0x80) == 0 means A < 0x80 116 and 117 (A & 0xC0) == 0xC0 means A > 0xBF 118 */ 119 120 #define UTF8_INVALID2(p) \ 121 ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) 122 123 #define UTF8_INVALID3(p) \ 124 (((p)[2] & 0x80) == 0 \ 125 || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ 126 : ((p)[2] & 0xC0) == 0xC0) \ 127 || ((*p) == 0xE0 \ 128 ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ 129 : ((p)[1] & 0x80) == 0 \ 130 || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) 131 132 #define UTF8_INVALID4(p) \ 133 (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ 134 || ((p)[2] & 0xC0) == 0xC0 \ 135 || ((*p) == 0xF0 \ 136 ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ 137 : ((p)[1] & 0x80) == 0 \ 138 || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) 139 140 static int 141 isNever(const ENCODING *enc, const char *p) { 142 UNUSED_P(enc); 143 UNUSED_P(p); 144 return 0; 145 } 146 147 static int 148 utf8_isName2(const ENCODING *enc, const char *p) { 149 UNUSED_P(enc); 150 return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); 151 } 152 153 static int 154 utf8_isName3(const ENCODING *enc, const char *p) { 155 UNUSED_P(enc); 156 return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); 157 } 158 159 #define utf8_isName4 isNever 160 161 static int 162 utf8_isNmstrt2(const ENCODING *enc, const char *p) { 163 UNUSED_P(enc); 164 return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); 165 } 166 167 static int 168 utf8_isNmstrt3(const ENCODING *enc, const char *p) { 169 UNUSED_P(enc); 170 return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); 171 } 172 173 #define utf8_isNmstrt4 isNever 174 175 static int 176 utf8_isInvalid2(const ENCODING *enc, const char *p) { 177 UNUSED_P(enc); 178 return UTF8_INVALID2((const unsigned char *)p); 179 } 180 181 static int 182 utf8_isInvalid3(const ENCODING *enc, const char *p) { 183 UNUSED_P(enc); 184 return UTF8_INVALID3((const unsigned char *)p); 185 } 186 187 static int 188 utf8_isInvalid4(const ENCODING *enc, const char *p) { 189 UNUSED_P(enc); 190 return UTF8_INVALID4((const unsigned char *)p); 191 } 192 193 struct normal_encoding { 194 ENCODING enc; 195 unsigned char type[256]; 196 int (*isName2)(const ENCODING *, const char *); 197 int (*isName3)(const ENCODING *, const char *); 198 int (*isName4)(const ENCODING *, const char *); 199 int (*isNmstrt2)(const ENCODING *, const char *); 200 int (*isNmstrt3)(const ENCODING *, const char *); 201 int (*isNmstrt4)(const ENCODING *, const char *); 202 int (*isInvalid2)(const ENCODING *, const char *); 203 int (*isInvalid3)(const ENCODING *, const char *); 204 int (*isInvalid4)(const ENCODING *, const char *); 205 }; 206 207 #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) 208 209 #define STANDARD_VTABLE(E) /* as nothing */ 210 211 #define NORMAL_VTABLE(E) \ 212 E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ 213 E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 214 215 #define NULL_VTABLE \ 216 /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ 217 /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ 218 /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL 219 220 #define UTF16_NULL_VTABLE(E) NULL_VTABLE 221 222 static int checkCharRefNumber(int result); 223 224 #include "xmltok_impl.h" 225 #include "ascii.h" 226 227 /* minimum bytes per character */ 228 #define MINBPC(enc) 1 229 230 #define SB_BYTE_TYPE(enc, p) \ 231 (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) 232 233 #define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) 234 235 #define BYTE_TO_ASCII(enc, p) (*(p)) 236 237 #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) 238 #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) 239 #define IS_INVALID_CHAR(enc, p, n) \ 240 (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 241 242 #define IS_NAME_CHAR_MINBPC(enc, p) (0) 243 #define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) 244 245 /* c is an ASCII character */ 246 #define CHAR_MATCHES(enc, p, c) (*(p) == (c)) 247 248 #define PREFIX(ident) normal_##ident 249 #define XML_TOK_IMPL_C 250 #include "xmltok_impl.c" 251 #undef XML_TOK_IMPL_C 252 253 #undef MINBPC 254 #undef BYTE_TYPE 255 #undef BYTE_TO_ASCII 256 #undef CHAR_MATCHES 257 #undef IS_NAME_CHAR 258 #undef IS_NAME_CHAR_MINBPC 259 #undef IS_NMSTRT_CHAR 260 #undef IS_NMSTRT_CHAR_MINBPC 261 #undef IS_INVALID_CHAR 262 263 enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ 264 UTF8_cval1 = 0x00, 265 UTF8_cval2 = 0xc0, 266 UTF8_cval3 = 0xe0, 267 UTF8_cval4 = 0xf0 268 }; 269 270 void 271 _INTERNAL_trim_to_complete_utf8_characters(const char *from, 272 const char **fromLimRef) { 273 const char *fromLim = *fromLimRef; 274 size_t walked = 0; 275 for (; fromLim > from; fromLim--, walked++) { 276 const unsigned char prev = (unsigned char)fromLim[-1]; 277 if ((prev & 0xf8u) 278 == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ 279 if (walked + 1 >= 4) { 280 fromLim += 4 - 1; 281 break; 282 } else { 283 walked = 0; 284 } 285 } else if ((prev & 0xf0u) 286 == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ 287 if (walked + 1 >= 3) { 288 fromLim += 3 - 1; 289 break; 290 } else { 291 walked = 0; 292 } 293 } else if ((prev & 0xe0u) 294 == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ 295 if (walked + 1 >= 2) { 296 fromLim += 2 - 1; 297 break; 298 } else { 299 walked = 0; 300 } 301 } else if ((prev & 0x80u) 302 == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ 303 break; 304 } 305 } 306 *fromLimRef = fromLim; 307 } 308 309 static enum XML_Convert_Result 310 utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 311 char **toP, const char *toLim) { 312 bool input_incomplete = false; 313 bool output_exhausted = false; 314 315 /* Avoid copying partial characters (due to limited space). */ 316 const ptrdiff_t bytesAvailable = fromLim - *fromP; 317 const ptrdiff_t bytesStorable = toLim - *toP; 318 UNUSED_P(enc); 319 if (bytesAvailable > bytesStorable) { 320 fromLim = *fromP + bytesStorable; 321 output_exhausted = true; 322 } 323 324 /* Avoid copying partial characters (from incomplete input). */ 325 { 326 const char *const fromLimBefore = fromLim; 327 _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); 328 if (fromLim < fromLimBefore) { 329 input_incomplete = true; 330 } 331 } 332 333 { 334 const ptrdiff_t bytesToCopy = fromLim - *fromP; 335 memcpy(*toP, *fromP, bytesToCopy); 336 *fromP += bytesToCopy; 337 *toP += bytesToCopy; 338 } 339 340 if (output_exhausted) /* needs to go first */ 341 return XML_CONVERT_OUTPUT_EXHAUSTED; 342 else if (input_incomplete) 343 return XML_CONVERT_INPUT_INCOMPLETE; 344 else 345 return XML_CONVERT_COMPLETED; 346 } 347 348 static enum XML_Convert_Result 349 utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 350 unsigned short **toP, const unsigned short *toLim) { 351 enum XML_Convert_Result res = XML_CONVERT_COMPLETED; 352 unsigned short *to = *toP; 353 const char *from = *fromP; 354 while (from < fromLim && to < toLim) { 355 switch (SB_BYTE_TYPE(enc, from)) { 356 case BT_LEAD2: 357 if (fromLim - from < 2) { 358 res = XML_CONVERT_INPUT_INCOMPLETE; 359 goto after; 360 } 361 *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); 362 from += 2; 363 break; 364 case BT_LEAD3: 365 if (fromLim - from < 3) { 366 res = XML_CONVERT_INPUT_INCOMPLETE; 367 goto after; 368 } 369 *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) 370 | (from[2] & 0x3f)); 371 from += 3; 372 break; 373 case BT_LEAD4: { 374 unsigned long n; 375 if (toLim - to < 2) { 376 res = XML_CONVERT_OUTPUT_EXHAUSTED; 377 goto after; 378 } 379 if (fromLim - from < 4) { 380 res = XML_CONVERT_INPUT_INCOMPLETE; 381 goto after; 382 } 383 n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) 384 | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); 385 n -= 0x10000; 386 to[0] = (unsigned short)((n >> 10) | 0xD800); 387 to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); 388 to += 2; 389 from += 4; 390 } break; 391 default: 392 *to++ = *from++; 393 break; 394 } 395 } 396 if (from < fromLim) 397 res = XML_CONVERT_OUTPUT_EXHAUSTED; 398 after: 399 *fromP = from; 400 *toP = to; 401 return res; 402 } 403 404 #ifdef XML_NS 405 static const struct normal_encoding utf8_encoding_ns 406 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 407 { 408 # include "asciitab.h" 409 # include "utf8tab.h" 410 }, 411 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 412 #endif 413 414 static const struct normal_encoding utf8_encoding 415 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 416 { 417 #define BT_COLON BT_NMSTRT 418 #include "asciitab.h" 419 #undef BT_COLON 420 #include "utf8tab.h" 421 }, 422 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 423 424 #ifdef XML_NS 425 426 static const struct normal_encoding internal_utf8_encoding_ns 427 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 428 { 429 # include "iasciitab.h" 430 # include "utf8tab.h" 431 }, 432 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 433 434 #endif 435 436 static const struct normal_encoding internal_utf8_encoding 437 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 438 { 439 #define BT_COLON BT_NMSTRT 440 #include "iasciitab.h" 441 #undef BT_COLON 442 #include "utf8tab.h" 443 }, 444 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 445 446 static enum XML_Convert_Result 447 latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 448 char **toP, const char *toLim) { 449 UNUSED_P(enc); 450 for (;;) { 451 unsigned char c; 452 if (*fromP == fromLim) 453 return XML_CONVERT_COMPLETED; 454 c = (unsigned char)**fromP; 455 if (c & 0x80) { 456 if (toLim - *toP < 2) 457 return XML_CONVERT_OUTPUT_EXHAUSTED; 458 *(*toP)++ = (char)((c >> 6) | UTF8_cval2); 459 *(*toP)++ = (char)((c & 0x3f) | 0x80); 460 (*fromP)++; 461 } else { 462 if (*toP == toLim) 463 return XML_CONVERT_OUTPUT_EXHAUSTED; 464 *(*toP)++ = *(*fromP)++; 465 } 466 } 467 } 468 469 static enum XML_Convert_Result 470 latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 471 unsigned short **toP, const unsigned short *toLim) { 472 UNUSED_P(enc); 473 while (*fromP < fromLim && *toP < toLim) 474 *(*toP)++ = (unsigned char)*(*fromP)++; 475 476 if ((*toP == toLim) && (*fromP < fromLim)) 477 return XML_CONVERT_OUTPUT_EXHAUSTED; 478 else 479 return XML_CONVERT_COMPLETED; 480 } 481 482 #ifdef XML_NS 483 484 static const struct normal_encoding latin1_encoding_ns 485 = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, 486 { 487 # include "asciitab.h" 488 # include "latin1tab.h" 489 }, 490 STANDARD_VTABLE(sb_) NULL_VTABLE}; 491 492 #endif 493 494 static const struct normal_encoding latin1_encoding 495 = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, 496 { 497 #define BT_COLON BT_NMSTRT 498 #include "asciitab.h" 499 #undef BT_COLON 500 #include "latin1tab.h" 501 }, 502 STANDARD_VTABLE(sb_) NULL_VTABLE}; 503 504 static enum XML_Convert_Result 505 ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 506 char **toP, const char *toLim) { 507 UNUSED_P(enc); 508 while (*fromP < fromLim && *toP < toLim) 509 *(*toP)++ = *(*fromP)++; 510 511 if ((*toP == toLim) && (*fromP < fromLim)) 512 return XML_CONVERT_OUTPUT_EXHAUSTED; 513 else 514 return XML_CONVERT_COMPLETED; 515 } 516 517 #ifdef XML_NS 518 519 static const struct normal_encoding ascii_encoding_ns 520 = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, 521 { 522 # include "asciitab.h" 523 /* BT_NONXML == 0 */ 524 }, 525 STANDARD_VTABLE(sb_) NULL_VTABLE}; 526 527 #endif 528 529 static const struct normal_encoding ascii_encoding 530 = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, 531 { 532 #define BT_COLON BT_NMSTRT 533 #include "asciitab.h" 534 #undef BT_COLON 535 /* BT_NONXML == 0 */ 536 }, 537 STANDARD_VTABLE(sb_) NULL_VTABLE}; 538 539 static int 540 unicode_byte_type(char hi, char lo) { 541 switch ((unsigned char)hi) { 542 /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */ 543 case 0xD8: 544 case 0xD9: 545 case 0xDA: 546 case 0xDB: 547 return BT_LEAD4; 548 /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */ 549 case 0xDC: 550 case 0xDD: 551 case 0xDE: 552 case 0xDF: 553 return BT_TRAIL; 554 case 0xFF: 555 switch ((unsigned char)lo) { 556 case 0xFF: /* noncharacter-FFFF */ 557 case 0xFE: /* noncharacter-FFFE */ 558 return BT_NONXML; 559 } 560 break; 561 } 562 return BT_NONASCII; 563 } 564 565 #define DEFINE_UTF16_TO_UTF8(E) \ 566 static enum XML_Convert_Result E##toUtf8( \ 567 const ENCODING *enc, const char **fromP, const char *fromLim, \ 568 char **toP, const char *toLim) { \ 569 const char *from = *fromP; \ 570 UNUSED_P(enc); \ 571 fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ 572 for (; from < fromLim; from += 2) { \ 573 int plane; \ 574 unsigned char lo2; \ 575 unsigned char lo = GET_LO(from); \ 576 unsigned char hi = GET_HI(from); \ 577 switch (hi) { \ 578 case 0: \ 579 if (lo < 0x80) { \ 580 if (*toP == toLim) { \ 581 *fromP = from; \ 582 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 583 } \ 584 *(*toP)++ = lo; \ 585 break; \ 586 } \ 587 EXPAT_FALLTHROUGH; \ 588 case 0x1: \ 589 case 0x2: \ 590 case 0x3: \ 591 case 0x4: \ 592 case 0x5: \ 593 case 0x6: \ 594 case 0x7: \ 595 if (toLim - *toP < 2) { \ 596 *fromP = from; \ 597 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 598 } \ 599 *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ 600 *(*toP)++ = ((lo & 0x3f) | 0x80); \ 601 break; \ 602 default: \ 603 if (toLim - *toP < 3) { \ 604 *fromP = from; \ 605 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 606 } \ 607 /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ 608 *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ 609 *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ 610 *(*toP)++ = ((lo & 0x3f) | 0x80); \ 611 break; \ 612 case 0xD8: \ 613 case 0xD9: \ 614 case 0xDA: \ 615 case 0xDB: \ 616 if (toLim - *toP < 4) { \ 617 *fromP = from; \ 618 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 619 } \ 620 if (fromLim - from < 4) { \ 621 *fromP = from; \ 622 return XML_CONVERT_INPUT_INCOMPLETE; \ 623 } \ 624 plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ 625 *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ 626 *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ 627 from += 2; \ 628 lo2 = GET_LO(from); \ 629 *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ 630 | (lo2 >> 6) | 0x80); \ 631 *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ 632 break; \ 633 } \ 634 } \ 635 *fromP = from; \ 636 if (from < fromLim) \ 637 return XML_CONVERT_INPUT_INCOMPLETE; \ 638 else \ 639 return XML_CONVERT_COMPLETED; \ 640 } 641 642 #define DEFINE_UTF16_TO_UTF16(E) \ 643 static enum XML_Convert_Result E##toUtf16( \ 644 const ENCODING *enc, const char **fromP, const char *fromLim, \ 645 unsigned short **toP, const unsigned short *toLim) { \ 646 enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ 647 UNUSED_P(enc); \ 648 fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ 649 /* Avoid copying the first half (2 bytes) of surrogate pairs (4 bytes) */ \ 650 if (fromLim - *fromP > ((toLim - *toP) << 1) \ 651 && /* are the last two bytes a high surrogate (0xD800-0xDBFF)? */ \ 652 (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \ 653 fromLim -= 2; \ 654 res = XML_CONVERT_INPUT_INCOMPLETE; \ 655 } \ 656 for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ 657 *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ 658 if ((*toP == toLim) && (*fromP < fromLim)) \ 659 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 660 else \ 661 return res; \ 662 } 663 664 #define GET_LO(ptr) ((unsigned char)(ptr)[0]) 665 #define GET_HI(ptr) ((unsigned char)(ptr)[1]) 666 667 DEFINE_UTF16_TO_UTF8(little2_) 668 DEFINE_UTF16_TO_UTF16(little2_) 669 670 #undef GET_LO 671 #undef GET_HI 672 673 #define GET_LO(ptr) ((unsigned char)(ptr)[1]) 674 #define GET_HI(ptr) ((unsigned char)(ptr)[0]) 675 676 DEFINE_UTF16_TO_UTF8(big2_) 677 DEFINE_UTF16_TO_UTF16(big2_) 678 679 #undef GET_LO 680 #undef GET_HI 681 682 #define LITTLE2_BYTE_TYPE(enc, p) \ 683 ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0])) 684 #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) 685 #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) 686 #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ 687 UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) 688 #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ 689 UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) 690 /* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4 691 for a high surrogate, so the pair is invalid unless the second unit is a low 692 surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */ 693 #define LITTLE2_IS_INVALID_CHAR(p, n) \ 694 ((n) == 4 && ((unsigned char)(p)[3] & 0xFC) != 0xDC) 695 696 #undef PREFIX 697 #define PREFIX(ident) little2_##ident 698 #define MINBPC(enc) 2 699 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ 700 #define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) 701 #define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) 702 #define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) 703 #define IS_NAME_CHAR(enc, p, n) 0 704 #define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) 705 #define IS_NMSTRT_CHAR(enc, p, n) (0) 706 #define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) 707 #define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n) 708 709 #define XML_TOK_IMPL_C 710 #include "xmltok_impl.c" 711 #undef XML_TOK_IMPL_C 712 713 #undef MINBPC 714 #undef BYTE_TYPE 715 #undef BYTE_TO_ASCII 716 #undef CHAR_MATCHES 717 #undef IS_NAME_CHAR 718 #undef IS_NAME_CHAR_MINBPC 719 #undef IS_NMSTRT_CHAR 720 #undef IS_NMSTRT_CHAR_MINBPC 721 #undef IS_INVALID_CHAR 722 723 #ifdef XML_NS 724 725 static const struct normal_encoding little2_encoding_ns 726 = {{VTABLE, 2, 0, 727 # if BYTEORDER == 1234 728 1 729 # else 730 0 731 # endif 732 }, 733 { 734 # include "asciitab.h" 735 # include "latin1tab.h" 736 }, 737 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 738 739 #endif 740 741 static const struct normal_encoding little2_encoding 742 = {{VTABLE, 2, 0, 743 #if BYTEORDER == 1234 744 1 745 #else 746 0 747 #endif 748 }, 749 { 750 #define BT_COLON BT_NMSTRT 751 #include "asciitab.h" 752 #undef BT_COLON 753 #include "latin1tab.h" 754 }, 755 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 756 757 #if BYTEORDER != 4321 758 759 # ifdef XML_NS 760 761 static const struct normal_encoding internal_little2_encoding_ns 762 = {{VTABLE, 2, 0, 1}, 763 { 764 # include "iasciitab.h" 765 # include "latin1tab.h" 766 }, 767 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 768 769 # endif 770 771 static const struct normal_encoding internal_little2_encoding 772 = {{VTABLE, 2, 0, 1}, 773 { 774 # define BT_COLON BT_NMSTRT 775 # include "iasciitab.h" 776 # undef BT_COLON 777 # include "latin1tab.h" 778 }, 779 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 780 781 #endif 782 783 #define BIG2_BYTE_TYPE(enc, p) \ 784 ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1])) 785 #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) 786 #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) 787 #define BIG2_IS_NAME_CHAR_MINBPC(p) \ 788 UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) 789 #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ 790 UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) 791 /* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4 792 for a high surrogate, so the pair is invalid unless the second unit is a low 793 surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */ 794 #define BIG2_IS_INVALID_CHAR(p, n) \ 795 ((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC) 796 797 #undef PREFIX 798 #define PREFIX(ident) big2_##ident 799 #define MINBPC(enc) 2 800 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ 801 #define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) 802 #define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) 803 #define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) 804 #define IS_NAME_CHAR(enc, p, n) 0 805 #define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) 806 #define IS_NMSTRT_CHAR(enc, p, n) (0) 807 #define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) 808 #define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n) 809 810 #define XML_TOK_IMPL_C 811 #include "xmltok_impl.c" 812 #undef XML_TOK_IMPL_C 813 814 #undef MINBPC 815 #undef BYTE_TYPE 816 #undef BYTE_TO_ASCII 817 #undef CHAR_MATCHES 818 #undef IS_NAME_CHAR 819 #undef IS_NAME_CHAR_MINBPC 820 #undef IS_NMSTRT_CHAR 821 #undef IS_NMSTRT_CHAR_MINBPC 822 #undef IS_INVALID_CHAR 823 824 #ifdef XML_NS 825 826 static const struct normal_encoding big2_encoding_ns 827 = {{VTABLE, 2, 0, 828 # if BYTEORDER == 4321 829 1 830 # else 831 0 832 # endif 833 }, 834 { 835 # include "asciitab.h" 836 # include "latin1tab.h" 837 }, 838 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 839 840 #endif 841 842 static const struct normal_encoding big2_encoding 843 = {{VTABLE, 2, 0, 844 #if BYTEORDER == 4321 845 1 846 #else 847 0 848 #endif 849 }, 850 { 851 #define BT_COLON BT_NMSTRT 852 #include "asciitab.h" 853 #undef BT_COLON 854 #include "latin1tab.h" 855 }, 856 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 857 858 #if BYTEORDER != 1234 859 860 # ifdef XML_NS 861 862 static const struct normal_encoding internal_big2_encoding_ns 863 = {{VTABLE, 2, 0, 1}, 864 { 865 # include "iasciitab.h" 866 # include "latin1tab.h" 867 }, 868 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 869 870 # endif 871 872 static const struct normal_encoding internal_big2_encoding 873 = {{VTABLE, 2, 0, 1}, 874 { 875 # define BT_COLON BT_NMSTRT 876 # include "iasciitab.h" 877 # undef BT_COLON 878 # include "latin1tab.h" 879 }, 880 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 881 882 #endif 883 884 #undef PREFIX 885 886 static int 887 streqci(const char *s1, const char *s2) { 888 for (;;) { 889 char c1 = *s1++; 890 char c2 = *s2++; 891 if (ASCII_a <= c1 && c1 <= ASCII_z) 892 c1 += ASCII_A - ASCII_a; 893 if (ASCII_a <= c2 && c2 <= ASCII_z) 894 /* The following line will never get executed. streqci() is 895 * only called from two places, both of which guarantee to put 896 * upper-case strings into s2. 897 */ 898 c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ 899 if (c1 != c2) 900 return 0; 901 if (! c1) 902 break; 903 } 904 return 1; 905 } 906 907 static void 908 initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, 909 POSITION *pos) { 910 UNUSED_P(enc); 911 normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); 912 } 913 914 static int 915 toAscii(const ENCODING *enc, const char *ptr, const char *end) { 916 char buf[1]; 917 char *p = buf; 918 XmlUtf8Convert(enc, &ptr, end, &p, p + 1); 919 if (p == buf) 920 return -1; 921 else 922 return buf[0]; 923 } 924 925 static int 926 isSpace(int c) { 927 switch (c) { 928 case 0x20: 929 case 0xD: 930 case 0xA: 931 case 0x9: 932 return 1; 933 } 934 return 0; 935 } 936 937 /* Return 1 if there's just optional white space or there's an S 938 followed by name=val. 939 */ 940 static int 941 parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, 942 const char **namePtr, const char **nameEndPtr, 943 const char **valPtr, const char **nextTokPtr) { 944 int c; 945 char open; 946 if (ptr == end) { 947 *namePtr = NULL; 948 return 1; 949 } 950 if (! isSpace(toAscii(enc, ptr, end))) { 951 *nextTokPtr = ptr; 952 return 0; 953 } 954 do { 955 ptr += enc->minBytesPerChar; 956 } while (isSpace(toAscii(enc, ptr, end))); 957 if (ptr == end) { 958 *namePtr = NULL; 959 return 1; 960 } 961 *namePtr = ptr; 962 for (;;) { 963 c = toAscii(enc, ptr, end); 964 if (c == -1) { 965 *nextTokPtr = ptr; 966 return 0; 967 } 968 if (c == ASCII_EQUALS) { 969 *nameEndPtr = ptr; 970 break; 971 } 972 if (isSpace(c)) { 973 *nameEndPtr = ptr; 974 do { 975 ptr += enc->minBytesPerChar; 976 } while (isSpace(c = toAscii(enc, ptr, end))); 977 if (c != ASCII_EQUALS) { 978 *nextTokPtr = ptr; 979 return 0; 980 } 981 break; 982 } 983 ptr += enc->minBytesPerChar; 984 } 985 if (ptr == *namePtr) { 986 *nextTokPtr = ptr; 987 return 0; 988 } 989 ptr += enc->minBytesPerChar; 990 c = toAscii(enc, ptr, end); 991 while (isSpace(c)) { 992 ptr += enc->minBytesPerChar; 993 c = toAscii(enc, ptr, end); 994 } 995 if (c != ASCII_QUOT && c != ASCII_APOS) { 996 *nextTokPtr = ptr; 997 return 0; 998 } 999 open = (char)c; 1000 ptr += enc->minBytesPerChar; 1001 *valPtr = ptr; 1002 for (;; ptr += enc->minBytesPerChar) { 1003 c = toAscii(enc, ptr, end); 1004 if (c == open) 1005 break; 1006 if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) 1007 && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD 1008 && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { 1009 *nextTokPtr = ptr; 1010 return 0; 1011 } 1012 } 1013 *nextTokPtr = ptr + enc->minBytesPerChar; 1014 return 1; 1015 } 1016 1017 static const char KW_version[] 1018 = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; 1019 1020 static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, 1021 ASCII_i, ASCII_n, ASCII_g, '\0'}; 1022 1023 static const char KW_standalone[] 1024 = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, 1025 ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; 1026 1027 static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; 1028 1029 static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; 1030 1031 static const char KW_1_dot[] = {ASCII_1, ASCII_PERIOD, '\0'}; 1032 1033 /* Checks a version pseudo-attribute value against the VersionNum production. 1034 XML 1.0 Fourth Edition only allows the literal "1.0", but the Fifth 1035 Edition relaxed this to "1." followed by one or more digits, since Expat 1036 only implements 1.0 itself but plans to track the Fifth Edition's laxer 1037 grammar here so that "1.1" and similar aren't rejected only to have that 1038 rejection reverted later. Returns true for a value matching "1.[0-9]+". 1039 val/valEnd bound the value itself; valEnd is the upper bound used when 1040 decoding the individual characters between them. */ 1041 static bool 1042 checkXmlDeclVersionNum(const ENCODING *enc, const char *val, 1043 const char *valEnd) { 1044 if (valEnd - val < 2 * enc->minBytesPerChar 1045 || ! XmlNameMatchesAscii(enc, val, val + 2 * enc->minBytesPerChar, 1046 KW_1_dot)) 1047 return false; 1048 val += 2 * enc->minBytesPerChar; 1049 if (val == valEnd) 1050 return false; 1051 for (; val != valEnd; val += enc->minBytesPerChar) { 1052 int c = toAscii(enc, val, valEnd); 1053 if (c < ASCII_0 || c > ASCII_9) 1054 return false; 1055 } 1056 return true; 1057 } 1058 1059 static int 1060 doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, 1061 const char *), 1062 int isGeneralTextEntity, const ENCODING *enc, const char *ptr, 1063 const char *end, const char **badPtr, const char **versionPtr, 1064 const char **versionEndPtr, const char **encodingName, 1065 const ENCODING **encoding, int *standalone) { 1066 const char *val = NULL; 1067 const char *name = NULL; 1068 const char *nameEnd = NULL; 1069 ptr += 5 * enc->minBytesPerChar; 1070 end -= 2 * enc->minBytesPerChar; 1071 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) 1072 || ! name) { 1073 *badPtr = ptr; 1074 return 0; 1075 } 1076 if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { 1077 if (! isGeneralTextEntity) { 1078 *badPtr = name; 1079 return 0; 1080 } 1081 } else { 1082 if (versionPtr) 1083 *versionPtr = val; 1084 if (versionEndPtr) 1085 *versionEndPtr = ptr; 1086 /* The version number must not be empty; VersionNum requires at least 1087 one character. The encoding and standalone pseudo-attributes below 1088 already reject an empty value, so keep version consistent. */ 1089 if (val == ptr - enc->minBytesPerChar) { 1090 *badPtr = val; 1091 return 0; 1092 } 1093 /* Expat implements XML 1.0 only, so any version outside the "1.0"/"1.x" 1094 family is rejected. Following the Fifth Edition's VersionNum 1095 production (rather than the Fourth Edition's exact "1.0") avoids 1096 rejecting "1.1" now only to have to revert that once Expat tracks 1097 the newer edition. */ 1098 if (! checkXmlDeclVersionNum(enc, val, ptr - enc->minBytesPerChar)) { 1099 *badPtr = val; 1100 return 0; 1101 } 1102 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { 1103 *badPtr = ptr; 1104 return 0; 1105 } 1106 if (! name) { 1107 if (isGeneralTextEntity) { 1108 /* a TextDecl must have an EncodingDecl */ 1109 *badPtr = ptr; 1110 return 0; 1111 } 1112 return 1; 1113 } 1114 } 1115 if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { 1116 int c = toAscii(enc, val, end); 1117 if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { 1118 *badPtr = val; 1119 return 0; 1120 } 1121 if (encodingName) 1122 *encodingName = val; 1123 if (encoding) 1124 *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); 1125 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { 1126 *badPtr = ptr; 1127 return 0; 1128 } 1129 if (! name) 1130 return 1; 1131 } 1132 if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) 1133 || isGeneralTextEntity) { 1134 *badPtr = name; 1135 return 0; 1136 } 1137 if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { 1138 if (standalone) 1139 *standalone = 1; 1140 } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { 1141 if (standalone) 1142 *standalone = 0; 1143 } else { 1144 *badPtr = val; 1145 return 0; 1146 } 1147 while (isSpace(toAscii(enc, ptr, end))) 1148 ptr += enc->minBytesPerChar; 1149 if (ptr != end) { 1150 *badPtr = ptr; 1151 return 0; 1152 } 1153 return 1; 1154 } 1155 1156 static int 1157 checkCharRefNumber(int result) { 1158 switch (result >> 8) { 1159 case 0xD8: 1160 case 0xD9: 1161 case 0xDA: 1162 case 0xDB: 1163 case 0xDC: 1164 case 0xDD: 1165 case 0xDE: 1166 case 0xDF: 1167 return -1; 1168 case 0: 1169 if (latin1_encoding.type[result] == BT_NONXML) 1170 return -1; 1171 break; 1172 case 0xFF: 1173 if (result == 0xFFFE || result == 0xFFFF) 1174 return -1; 1175 break; 1176 } 1177 return result; 1178 } 1179 1180 int 1181 XmlUtf8Encode(int c, char *buf) { 1182 enum { 1183 /* minN is minimum legal resulting value for N byte sequence */ 1184 min2 = 0x80, 1185 min3 = 0x800, 1186 min4 = 0x10000 1187 }; 1188 1189 if (c < 0) 1190 return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ 1191 if (c < min2) { 1192 buf[0] = (char)(c | UTF8_cval1); 1193 return 1; 1194 } 1195 if (c < min3) { 1196 buf[0] = (char)((c >> 6) | UTF8_cval2); 1197 buf[1] = (char)((c & 0x3f) | 0x80); 1198 return 2; 1199 } 1200 if (c < min4) { 1201 buf[0] = (char)((c >> 12) | UTF8_cval3); 1202 buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); 1203 buf[2] = (char)((c & 0x3f) | 0x80); 1204 return 3; 1205 } 1206 if (c < 0x110000) { 1207 buf[0] = (char)((c >> 18) | UTF8_cval4); 1208 buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); 1209 buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); 1210 buf[3] = (char)((c & 0x3f) | 0x80); 1211 return 4; 1212 } 1213 return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ 1214 } 1215 1216 int 1217 XmlUtf16Encode(int charNum, unsigned short *buf) { 1218 if (charNum < 0) 1219 return 0; 1220 if (charNum < 0x10000) { 1221 buf[0] = (unsigned short)charNum; 1222 return 1; 1223 } 1224 if (charNum < 0x110000) { 1225 charNum -= 0x10000; 1226 buf[0] = (unsigned short)((charNum >> 10) + 0xD800); 1227 buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); 1228 return 2; 1229 } 1230 return 0; 1231 } 1232 1233 struct unknown_encoding { 1234 struct normal_encoding normal; 1235 CONVERTER convert; 1236 void *userData; 1237 unsigned short utf16[256]; 1238 char utf8[256][4]; 1239 }; 1240 1241 #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) 1242 1243 int 1244 XmlSizeOfUnknownEncoding(void) { 1245 return sizeof(struct unknown_encoding); 1246 } 1247 1248 static int 1249 unknown_isName(const ENCODING *enc, const char *p) { 1250 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1251 int c = uenc->convert(uenc->userData, p); 1252 if (c & ~0xFFFF) 1253 return 0; 1254 return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); 1255 } 1256 1257 static int 1258 unknown_isNmstrt(const ENCODING *enc, const char *p) { 1259 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1260 int c = uenc->convert(uenc->userData, p); 1261 if (c & ~0xFFFF) 1262 return 0; 1263 return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); 1264 } 1265 1266 static int 1267 unknown_isInvalid(const ENCODING *enc, const char *p) { 1268 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1269 int c = uenc->convert(uenc->userData, p); 1270 return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; 1271 } 1272 1273 static enum XML_Convert_Result 1274 unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 1275 char **toP, const char *toLim) { 1276 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1277 char buf[XML_UTF8_ENCODE_MAX]; 1278 for (;;) { 1279 const char *utf8; 1280 int n; 1281 if (*fromP == fromLim) 1282 return XML_CONVERT_COMPLETED; 1283 utf8 = uenc->utf8[(unsigned char)**fromP]; 1284 n = *utf8++; 1285 if (n == 0) { 1286 int c = uenc->convert(uenc->userData, *fromP); 1287 n = XmlUtf8Encode(c, buf); 1288 if (n > toLim - *toP) 1289 return XML_CONVERT_OUTPUT_EXHAUSTED; 1290 utf8 = buf; 1291 *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] 1292 - (BT_LEAD2 - 2)); 1293 } else { 1294 if (n > toLim - *toP) 1295 return XML_CONVERT_OUTPUT_EXHAUSTED; 1296 (*fromP)++; 1297 } 1298 memcpy(*toP, utf8, n); 1299 *toP += n; 1300 } 1301 } 1302 1303 static enum XML_Convert_Result 1304 unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 1305 unsigned short **toP, const unsigned short *toLim) { 1306 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1307 while (*fromP < fromLim && *toP < toLim) { 1308 unsigned short c = uenc->utf16[(unsigned char)**fromP]; 1309 if (c == 0) { 1310 c = (unsigned short)uenc->convert(uenc->userData, *fromP); 1311 *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] 1312 - (BT_LEAD2 - 2)); 1313 } else 1314 (*fromP)++; 1315 *(*toP)++ = c; 1316 } 1317 1318 if ((*toP == toLim) && (*fromP < fromLim)) 1319 return XML_CONVERT_OUTPUT_EXHAUSTED; 1320 else 1321 return XML_CONVERT_COMPLETED; 1322 } 1323 1324 ENCODING * 1325 XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert, 1326 void *userData) { 1327 int i; 1328 struct unknown_encoding *e = (struct unknown_encoding *)mem; 1329 memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); 1330 for (i = 0; i < 128; i++) 1331 if (latin1_encoding.type[i] != BT_OTHER 1332 && latin1_encoding.type[i] != BT_NONXML && table[i] != i) 1333 return 0; 1334 for (i = 0; i < 256; i++) { 1335 int c = table[i]; 1336 if (c == -1) { 1337 e->normal.type[i] = BT_MALFORM; 1338 /* This shouldn't really get used. */ 1339 e->utf16[i] = 0xFFFF; 1340 e->utf8[i][0] = 1; 1341 e->utf8[i][1] = 0; 1342 } else if (c < 0) { 1343 if (c < -4) 1344 return 0; 1345 /* Multi-byte sequences need a converter function */ 1346 if (! convert) 1347 return 0; 1348 e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); 1349 e->utf8[i][0] = 0; 1350 e->utf16[i] = 0; 1351 } else if (c < 0x80) { 1352 if (latin1_encoding.type[c] != BT_OTHER 1353 && latin1_encoding.type[c] != BT_NONXML && c != i) 1354 return 0; 1355 e->normal.type[i] = latin1_encoding.type[c]; 1356 e->utf8[i][0] = 1; 1357 e->utf8[i][1] = (char)c; 1358 e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); 1359 } else if (checkCharRefNumber(c) < 0) { 1360 e->normal.type[i] = BT_NONXML; 1361 /* This shouldn't really get used. */ 1362 e->utf16[i] = 0xFFFF; 1363 e->utf8[i][0] = 1; 1364 e->utf8[i][1] = 0; 1365 } else { 1366 if (c > 0xFFFF) 1367 return 0; 1368 if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) 1369 e->normal.type[i] = BT_NMSTRT; 1370 else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) 1371 e->normal.type[i] = BT_NAME; 1372 else 1373 e->normal.type[i] = BT_OTHER; 1374 e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); 1375 e->utf16[i] = (unsigned short)c; 1376 } 1377 } 1378 e->userData = userData; 1379 e->convert = convert; 1380 if (convert) { 1381 e->normal.isName2 = unknown_isName; 1382 e->normal.isName3 = unknown_isName; 1383 e->normal.isName4 = unknown_isName; 1384 e->normal.isNmstrt2 = unknown_isNmstrt; 1385 e->normal.isNmstrt3 = unknown_isNmstrt; 1386 e->normal.isNmstrt4 = unknown_isNmstrt; 1387 e->normal.isInvalid2 = unknown_isInvalid; 1388 e->normal.isInvalid3 = unknown_isInvalid; 1389 e->normal.isInvalid4 = unknown_isInvalid; 1390 } 1391 e->normal.enc.utf8Convert = unknown_toUtf8; 1392 e->normal.enc.utf16Convert = unknown_toUtf16; 1393 return &(e->normal.enc); 1394 } 1395 1396 /* If this enumeration is changed, getEncodingIndex and encodings 1397 must also be changed. */ 1398 enum { 1399 UNKNOWN_ENC = -1, 1400 ISO_8859_1_ENC = 0, 1401 US_ASCII_ENC, 1402 UTF_8_ENC, 1403 UTF_16_ENC, 1404 UTF_16BE_ENC, 1405 UTF_16LE_ENC, 1406 /* must match encodingNames up to here */ 1407 NO_ENC 1408 }; 1409 1410 static const char KW_ISO_8859_1[] 1411 = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, 1412 ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; 1413 static const char KW_US_ASCII[] 1414 = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, 1415 ASCII_C, ASCII_I, ASCII_I, '\0'}; 1416 static const char KW_UTF_8[] 1417 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; 1418 static const char KW_UTF_16[] 1419 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; 1420 static const char KW_UTF_16BE[] 1421 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, 1422 ASCII_6, ASCII_B, ASCII_E, '\0'}; 1423 static const char KW_UTF_16LE[] 1424 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, 1425 ASCII_6, ASCII_L, ASCII_E, '\0'}; 1426 1427 static int 1428 getEncodingIndex(const char *name) { 1429 static const char *const encodingNames[] = { 1430 KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, 1431 }; 1432 int i; 1433 if (name == NULL) 1434 return NO_ENC; 1435 for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) 1436 if (streqci(name, encodingNames[i])) 1437 return i; 1438 return UNKNOWN_ENC; 1439 } 1440 1441 /* For binary compatibility, we store the index of the encoding 1442 specified at initialization in the isUtf16 member. 1443 */ 1444 1445 #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) 1446 #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) 1447 1448 /* This is what detects the encoding. encodingTable maps from 1449 encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of 1450 the external (protocol) specified encoding; state is 1451 XML_CONTENT_STATE if we're parsing an external text entity, and 1452 XML_PROLOG_STATE otherwise. 1453 */ 1454 1455 static int 1456 initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, 1457 int state, const char *ptr, const char *end, const char **nextTokPtr) { 1458 const ENCODING **encPtr; 1459 1460 if (ptr >= end) 1461 return XML_TOK_NONE; 1462 encPtr = enc->encPtr; 1463 if (ptr + 1 == end) { 1464 /* only a single byte available for auto-detection */ 1465 #ifndef XML_DTD /* FIXME */ 1466 /* a well-formed document entity must have more than one byte */ 1467 if (state != XML_CONTENT_STATE) 1468 return XML_TOK_PARTIAL; 1469 #endif 1470 /* so we're parsing an external text entity... */ 1471 /* if UTF-16 was externally specified, then we need at least 2 bytes */ 1472 switch (INIT_ENC_INDEX(enc)) { 1473 case UTF_16_ENC: 1474 case UTF_16LE_ENC: 1475 case UTF_16BE_ENC: 1476 return XML_TOK_PARTIAL; 1477 } 1478 switch ((unsigned char)*ptr) { 1479 case 0xFE: 1480 case 0xFF: 1481 case 0xEF: /* possibly first byte of UTF-8 BOM */ 1482 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1483 break; 1484 EXPAT_FALLTHROUGH; 1485 case 0x00: 1486 case 0x3C: 1487 return XML_TOK_PARTIAL; 1488 } 1489 } else { 1490 switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { 1491 case 0xFEFF: 1492 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1493 break; 1494 *nextTokPtr = ptr + 2; 1495 *encPtr = encodingTable[UTF_16BE_ENC]; 1496 return XML_TOK_BOM; 1497 /* 00 3C is handled in the default case */ 1498 case 0x3C00: 1499 if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC 1500 || INIT_ENC_INDEX(enc) == UTF_16_ENC) 1501 && state == XML_CONTENT_STATE) 1502 break; 1503 *encPtr = encodingTable[UTF_16LE_ENC]; 1504 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1505 case 0xFFFE: 1506 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1507 break; 1508 *nextTokPtr = ptr + 2; 1509 *encPtr = encodingTable[UTF_16LE_ENC]; 1510 return XML_TOK_BOM; 1511 case 0xEFBB: 1512 /* Maybe a UTF-8 BOM (EF BB BF) */ 1513 /* If there's an explicitly specified (external) encoding 1514 of ISO-8859-1 or some flavour of UTF-16 1515 and this is an external text entity, 1516 don't look for the BOM, 1517 because it might be a legal data. 1518 */ 1519 if (state == XML_CONTENT_STATE) { 1520 int e = INIT_ENC_INDEX(enc); 1521 if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC 1522 || e == UTF_16_ENC) 1523 break; 1524 } 1525 if (ptr + 2 == end) 1526 return XML_TOK_PARTIAL; 1527 if ((unsigned char)ptr[2] == 0xBF) { 1528 *nextTokPtr = ptr + 3; 1529 *encPtr = encodingTable[UTF_8_ENC]; 1530 return XML_TOK_BOM; 1531 } 1532 break; 1533 default: 1534 if (ptr[0] == '\0') { 1535 /* 0 isn't a legal data character. Furthermore a document 1536 entity can only start with ASCII characters. So the only 1537 way this can fail to be big-endian UTF-16 if it it's an 1538 external parsed general entity that's labelled as 1539 UTF-16LE. 1540 */ 1541 if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) 1542 break; 1543 *encPtr = encodingTable[UTF_16BE_ENC]; 1544 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1545 } else if (ptr[1] == '\0') { 1546 /* We could recover here in the case: 1547 - parsing an external entity 1548 - second byte is 0 1549 - no externally specified encoding 1550 - no encoding declaration 1551 by assuming UTF-16LE. But we don't, because this would mean when 1552 presented just with a single byte, we couldn't reliably determine 1553 whether we needed further bytes. 1554 */ 1555 if (state == XML_CONTENT_STATE) 1556 break; 1557 *encPtr = encodingTable[UTF_16LE_ENC]; 1558 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1559 } 1560 break; 1561 } 1562 } 1563 *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; 1564 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1565 } 1566 1567 #define NS(x) x 1568 #define ns(x) x 1569 #define XML_TOK_NS_C 1570 #include "xmltok_ns.c" 1571 #undef XML_TOK_NS_C 1572 #undef NS 1573 #undef ns 1574 1575 #ifdef XML_NS 1576 1577 # define NS(x) x##NS 1578 # define ns(x) x##_ns 1579 1580 # define XML_TOK_NS_C 1581 # include "xmltok_ns.c" 1582 # undef XML_TOK_NS_C 1583 1584 # undef NS 1585 # undef ns 1586 1587 ENCODING * 1588 XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert, 1589 void *userData) { 1590 ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); 1591 if (enc) 1592 ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; 1593 return enc; 1594 } 1595 1596 #endif /* XML_NS */ 1597