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 #ifdef XML_MIN_SIZE 197 int (*byteType)(const ENCODING *, const char *); 198 int (*isNameMin)(const ENCODING *, const char *); 199 int (*isNmstrtMin)(const ENCODING *, const char *); 200 int (*byteToAscii)(const ENCODING *, const char *); 201 int (*charMatches)(const ENCODING *, const char *, int); 202 #endif /* XML_MIN_SIZE */ 203 int (*isName2)(const ENCODING *, const char *); 204 int (*isName3)(const ENCODING *, const char *); 205 int (*isName4)(const ENCODING *, const char *); 206 int (*isNmstrt2)(const ENCODING *, const char *); 207 int (*isNmstrt3)(const ENCODING *, const char *); 208 int (*isNmstrt4)(const ENCODING *, const char *); 209 int (*isInvalid2)(const ENCODING *, const char *); 210 int (*isInvalid3)(const ENCODING *, const char *); 211 int (*isInvalid4)(const ENCODING *, const char *); 212 }; 213 214 #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) 215 216 #ifdef XML_MIN_SIZE 217 218 # define STANDARD_VTABLE(E) \ 219 E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, 220 221 #else 222 223 # define STANDARD_VTABLE(E) /* as nothing */ 224 225 #endif 226 227 #define NORMAL_VTABLE(E) \ 228 E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ 229 E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 230 231 #define NULL_VTABLE \ 232 /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ 233 /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ 234 /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL 235 236 /* Like NULL_VTABLE but with a real isInvalid4 so the UTF-16 encodings reject a 237 high surrogate that is not followed by a low surrogate. Only needed for the 238 XML_MIN_SIZE build, where the shared tokenizer dispatches through the vtable; 239 the regular build inlines the same check via IS_INVALID_CHAR. */ 240 #ifdef XML_MIN_SIZE 241 # define UTF16_NULL_VTABLE(E) \ 242 /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ 243 /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ 244 /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, E##isInvalid4 245 #else 246 # define UTF16_NULL_VTABLE(E) NULL_VTABLE 247 #endif 248 249 static int checkCharRefNumber(int result); 250 251 #include "xmltok_impl.h" 252 #include "ascii.h" 253 254 #ifdef XML_MIN_SIZE 255 # define sb_isNameMin isNever 256 # define sb_isNmstrtMin isNever 257 #endif 258 259 #ifdef XML_MIN_SIZE 260 # define MINBPC(enc) ((enc)->minBytesPerChar) 261 #else 262 /* minimum bytes per character */ 263 # define MINBPC(enc) 1 264 #endif 265 266 #define SB_BYTE_TYPE(enc, p) \ 267 (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) 268 269 #ifdef XML_MIN_SIZE 270 static int 271 sb_byteType(const ENCODING *enc, const char *p) { 272 return SB_BYTE_TYPE(enc, p); 273 } 274 # define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) 275 #else 276 # define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) 277 #endif 278 279 #ifdef XML_MIN_SIZE 280 # define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) 281 static int 282 sb_byteToAscii(const ENCODING *enc, const char *p) { 283 UNUSED_P(enc); 284 return *p; 285 } 286 #else 287 # define BYTE_TO_ASCII(enc, p) (*(p)) 288 #endif 289 290 #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) 291 #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) 292 #ifdef XML_MIN_SIZE 293 # define IS_INVALID_CHAR(enc, p, n) \ 294 (AS_NORMAL_ENCODING(enc)->isInvalid##n \ 295 && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 296 #else 297 # define IS_INVALID_CHAR(enc, p, n) \ 298 (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) 299 #endif 300 301 #ifdef XML_MIN_SIZE 302 # define IS_NAME_CHAR_MINBPC(enc, p) \ 303 (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) 304 # define IS_NMSTRT_CHAR_MINBPC(enc, p) \ 305 (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) 306 #else 307 # define IS_NAME_CHAR_MINBPC(enc, p) (0) 308 # define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) 309 #endif 310 311 #ifdef XML_MIN_SIZE 312 # define CHAR_MATCHES(enc, p, c) \ 313 (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) 314 static int 315 sb_charMatches(const ENCODING *enc, const char *p, int c) { 316 UNUSED_P(enc); 317 return *p == c; 318 } 319 #else 320 /* c is an ASCII character */ 321 # define CHAR_MATCHES(enc, p, c) (*(p) == (c)) 322 #endif 323 324 #define PREFIX(ident) normal_##ident 325 #define XML_TOK_IMPL_C 326 #include "xmltok_impl.c" 327 #undef XML_TOK_IMPL_C 328 329 #undef MINBPC 330 #undef BYTE_TYPE 331 #undef BYTE_TO_ASCII 332 #undef CHAR_MATCHES 333 #undef IS_NAME_CHAR 334 #undef IS_NAME_CHAR_MINBPC 335 #undef IS_NMSTRT_CHAR 336 #undef IS_NMSTRT_CHAR_MINBPC 337 #undef IS_INVALID_CHAR 338 339 enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ 340 UTF8_cval1 = 0x00, 341 UTF8_cval2 = 0xc0, 342 UTF8_cval3 = 0xe0, 343 UTF8_cval4 = 0xf0 344 }; 345 346 void 347 _INTERNAL_trim_to_complete_utf8_characters(const char *from, 348 const char **fromLimRef) { 349 const char *fromLim = *fromLimRef; 350 size_t walked = 0; 351 for (; fromLim > from; fromLim--, walked++) { 352 const unsigned char prev = (unsigned char)fromLim[-1]; 353 if ((prev & 0xf8u) 354 == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ 355 if (walked + 1 >= 4) { 356 fromLim += 4 - 1; 357 break; 358 } else { 359 walked = 0; 360 } 361 } else if ((prev & 0xf0u) 362 == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ 363 if (walked + 1 >= 3) { 364 fromLim += 3 - 1; 365 break; 366 } else { 367 walked = 0; 368 } 369 } else if ((prev & 0xe0u) 370 == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ 371 if (walked + 1 >= 2) { 372 fromLim += 2 - 1; 373 break; 374 } else { 375 walked = 0; 376 } 377 } else if ((prev & 0x80u) 378 == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ 379 break; 380 } 381 } 382 *fromLimRef = fromLim; 383 } 384 385 static enum XML_Convert_Result 386 utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 387 char **toP, const char *toLim) { 388 bool input_incomplete = false; 389 bool output_exhausted = false; 390 391 /* Avoid copying partial characters (due to limited space). */ 392 const ptrdiff_t bytesAvailable = fromLim - *fromP; 393 const ptrdiff_t bytesStorable = toLim - *toP; 394 UNUSED_P(enc); 395 if (bytesAvailable > bytesStorable) { 396 fromLim = *fromP + bytesStorable; 397 output_exhausted = true; 398 } 399 400 /* Avoid copying partial characters (from incomplete input). */ 401 { 402 const char *const fromLimBefore = fromLim; 403 _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); 404 if (fromLim < fromLimBefore) { 405 input_incomplete = true; 406 } 407 } 408 409 { 410 const ptrdiff_t bytesToCopy = fromLim - *fromP; 411 memcpy(*toP, *fromP, bytesToCopy); 412 *fromP += bytesToCopy; 413 *toP += bytesToCopy; 414 } 415 416 if (output_exhausted) /* needs to go first */ 417 return XML_CONVERT_OUTPUT_EXHAUSTED; 418 else if (input_incomplete) 419 return XML_CONVERT_INPUT_INCOMPLETE; 420 else 421 return XML_CONVERT_COMPLETED; 422 } 423 424 static enum XML_Convert_Result 425 utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 426 unsigned short **toP, const unsigned short *toLim) { 427 enum XML_Convert_Result res = XML_CONVERT_COMPLETED; 428 unsigned short *to = *toP; 429 const char *from = *fromP; 430 while (from < fromLim && to < toLim) { 431 switch (SB_BYTE_TYPE(enc, from)) { 432 case BT_LEAD2: 433 if (fromLim - from < 2) { 434 res = XML_CONVERT_INPUT_INCOMPLETE; 435 goto after; 436 } 437 *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); 438 from += 2; 439 break; 440 case BT_LEAD3: 441 if (fromLim - from < 3) { 442 res = XML_CONVERT_INPUT_INCOMPLETE; 443 goto after; 444 } 445 *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) 446 | (from[2] & 0x3f)); 447 from += 3; 448 break; 449 case BT_LEAD4: { 450 unsigned long n; 451 if (toLim - to < 2) { 452 res = XML_CONVERT_OUTPUT_EXHAUSTED; 453 goto after; 454 } 455 if (fromLim - from < 4) { 456 res = XML_CONVERT_INPUT_INCOMPLETE; 457 goto after; 458 } 459 n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) 460 | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); 461 n -= 0x10000; 462 to[0] = (unsigned short)((n >> 10) | 0xD800); 463 to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); 464 to += 2; 465 from += 4; 466 } break; 467 default: 468 *to++ = *from++; 469 break; 470 } 471 } 472 if (from < fromLim) 473 res = XML_CONVERT_OUTPUT_EXHAUSTED; 474 after: 475 *fromP = from; 476 *toP = to; 477 return res; 478 } 479 480 #ifdef XML_NS 481 static const struct normal_encoding utf8_encoding_ns 482 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 483 { 484 # include "asciitab.h" 485 # include "utf8tab.h" 486 }, 487 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 488 #endif 489 490 static const struct normal_encoding utf8_encoding 491 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 492 { 493 #define BT_COLON BT_NMSTRT 494 #include "asciitab.h" 495 #undef BT_COLON 496 #include "utf8tab.h" 497 }, 498 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 499 500 #ifdef XML_NS 501 502 static const struct normal_encoding internal_utf8_encoding_ns 503 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 504 { 505 # include "iasciitab.h" 506 # include "utf8tab.h" 507 }, 508 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 509 510 #endif 511 512 static const struct normal_encoding internal_utf8_encoding 513 = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, 514 { 515 #define BT_COLON BT_NMSTRT 516 #include "iasciitab.h" 517 #undef BT_COLON 518 #include "utf8tab.h" 519 }, 520 STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; 521 522 static enum XML_Convert_Result 523 latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 524 char **toP, const char *toLim) { 525 UNUSED_P(enc); 526 for (;;) { 527 unsigned char c; 528 if (*fromP == fromLim) 529 return XML_CONVERT_COMPLETED; 530 c = (unsigned char)**fromP; 531 if (c & 0x80) { 532 if (toLim - *toP < 2) 533 return XML_CONVERT_OUTPUT_EXHAUSTED; 534 *(*toP)++ = (char)((c >> 6) | UTF8_cval2); 535 *(*toP)++ = (char)((c & 0x3f) | 0x80); 536 (*fromP)++; 537 } else { 538 if (*toP == toLim) 539 return XML_CONVERT_OUTPUT_EXHAUSTED; 540 *(*toP)++ = *(*fromP)++; 541 } 542 } 543 } 544 545 static enum XML_Convert_Result 546 latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 547 unsigned short **toP, const unsigned short *toLim) { 548 UNUSED_P(enc); 549 while (*fromP < fromLim && *toP < toLim) 550 *(*toP)++ = (unsigned char)*(*fromP)++; 551 552 if ((*toP == toLim) && (*fromP < fromLim)) 553 return XML_CONVERT_OUTPUT_EXHAUSTED; 554 else 555 return XML_CONVERT_COMPLETED; 556 } 557 558 #ifdef XML_NS 559 560 static const struct normal_encoding latin1_encoding_ns 561 = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, 562 { 563 # include "asciitab.h" 564 # include "latin1tab.h" 565 }, 566 STANDARD_VTABLE(sb_) NULL_VTABLE}; 567 568 #endif 569 570 static const struct normal_encoding latin1_encoding 571 = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, 572 { 573 #define BT_COLON BT_NMSTRT 574 #include "asciitab.h" 575 #undef BT_COLON 576 #include "latin1tab.h" 577 }, 578 STANDARD_VTABLE(sb_) NULL_VTABLE}; 579 580 static enum XML_Convert_Result 581 ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 582 char **toP, const char *toLim) { 583 UNUSED_P(enc); 584 while (*fromP < fromLim && *toP < toLim) 585 *(*toP)++ = *(*fromP)++; 586 587 if ((*toP == toLim) && (*fromP < fromLim)) 588 return XML_CONVERT_OUTPUT_EXHAUSTED; 589 else 590 return XML_CONVERT_COMPLETED; 591 } 592 593 #ifdef XML_NS 594 595 static const struct normal_encoding ascii_encoding_ns 596 = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, 597 { 598 # include "asciitab.h" 599 /* BT_NONXML == 0 */ 600 }, 601 STANDARD_VTABLE(sb_) NULL_VTABLE}; 602 603 #endif 604 605 static const struct normal_encoding ascii_encoding 606 = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, 607 { 608 #define BT_COLON BT_NMSTRT 609 #include "asciitab.h" 610 #undef BT_COLON 611 /* BT_NONXML == 0 */ 612 }, 613 STANDARD_VTABLE(sb_) NULL_VTABLE}; 614 615 static int 616 unicode_byte_type(char hi, char lo) { 617 switch ((unsigned char)hi) { 618 /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */ 619 case 0xD8: 620 case 0xD9: 621 case 0xDA: 622 case 0xDB: 623 return BT_LEAD4; 624 /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */ 625 case 0xDC: 626 case 0xDD: 627 case 0xDE: 628 case 0xDF: 629 return BT_TRAIL; 630 case 0xFF: 631 switch ((unsigned char)lo) { 632 case 0xFF: /* noncharacter-FFFF */ 633 case 0xFE: /* noncharacter-FFFE */ 634 return BT_NONXML; 635 } 636 break; 637 } 638 return BT_NONASCII; 639 } 640 641 #define DEFINE_UTF16_TO_UTF8(E) \ 642 static enum XML_Convert_Result E##toUtf8( \ 643 const ENCODING *enc, const char **fromP, const char *fromLim, \ 644 char **toP, const char *toLim) { \ 645 const char *from = *fromP; \ 646 UNUSED_P(enc); \ 647 fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ 648 for (; from < fromLim; from += 2) { \ 649 int plane; \ 650 unsigned char lo2; \ 651 unsigned char lo = GET_LO(from); \ 652 unsigned char hi = GET_HI(from); \ 653 switch (hi) { \ 654 case 0: \ 655 if (lo < 0x80) { \ 656 if (*toP == toLim) { \ 657 *fromP = from; \ 658 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 659 } \ 660 *(*toP)++ = lo; \ 661 break; \ 662 } \ 663 EXPAT_FALLTHROUGH; \ 664 case 0x1: \ 665 case 0x2: \ 666 case 0x3: \ 667 case 0x4: \ 668 case 0x5: \ 669 case 0x6: \ 670 case 0x7: \ 671 if (toLim - *toP < 2) { \ 672 *fromP = from; \ 673 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 674 } \ 675 *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ 676 *(*toP)++ = ((lo & 0x3f) | 0x80); \ 677 break; \ 678 default: \ 679 if (toLim - *toP < 3) { \ 680 *fromP = from; \ 681 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 682 } \ 683 /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ 684 *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ 685 *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ 686 *(*toP)++ = ((lo & 0x3f) | 0x80); \ 687 break; \ 688 case 0xD8: \ 689 case 0xD9: \ 690 case 0xDA: \ 691 case 0xDB: \ 692 if (toLim - *toP < 4) { \ 693 *fromP = from; \ 694 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 695 } \ 696 if (fromLim - from < 4) { \ 697 *fromP = from; \ 698 return XML_CONVERT_INPUT_INCOMPLETE; \ 699 } \ 700 plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ 701 *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ 702 *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ 703 from += 2; \ 704 lo2 = GET_LO(from); \ 705 *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ 706 | (lo2 >> 6) | 0x80); \ 707 *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ 708 break; \ 709 } \ 710 } \ 711 *fromP = from; \ 712 if (from < fromLim) \ 713 return XML_CONVERT_INPUT_INCOMPLETE; \ 714 else \ 715 return XML_CONVERT_COMPLETED; \ 716 } 717 718 #define DEFINE_UTF16_TO_UTF16(E) \ 719 static enum XML_Convert_Result E##toUtf16( \ 720 const ENCODING *enc, const char **fromP, const char *fromLim, \ 721 unsigned short **toP, const unsigned short *toLim) { \ 722 enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ 723 UNUSED_P(enc); \ 724 fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ 725 /* Avoid copying the first half (2 bytes) of surrogate pairs (4 bytes) */ \ 726 if (fromLim - *fromP > ((toLim - *toP) << 1) \ 727 && /* are the last two bytes a high surrogate (0xD800-0xDBFF)? */ \ 728 (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \ 729 fromLim -= 2; \ 730 res = XML_CONVERT_INPUT_INCOMPLETE; \ 731 } \ 732 for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ 733 *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ 734 if ((*toP == toLim) && (*fromP < fromLim)) \ 735 return XML_CONVERT_OUTPUT_EXHAUSTED; \ 736 else \ 737 return res; \ 738 } 739 740 #define GET_LO(ptr) ((unsigned char)(ptr)[0]) 741 #define GET_HI(ptr) ((unsigned char)(ptr)[1]) 742 743 DEFINE_UTF16_TO_UTF8(little2_) 744 DEFINE_UTF16_TO_UTF16(little2_) 745 746 #undef GET_LO 747 #undef GET_HI 748 749 #define GET_LO(ptr) ((unsigned char)(ptr)[1]) 750 #define GET_HI(ptr) ((unsigned char)(ptr)[0]) 751 752 DEFINE_UTF16_TO_UTF8(big2_) 753 DEFINE_UTF16_TO_UTF16(big2_) 754 755 #undef GET_LO 756 #undef GET_HI 757 758 #define LITTLE2_BYTE_TYPE(enc, p) \ 759 ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0])) 760 #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) 761 #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) 762 #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ 763 UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) 764 #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ 765 UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) 766 /* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4 767 for a high surrogate, so the pair is invalid unless the second unit is a low 768 surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */ 769 #define LITTLE2_IS_INVALID_CHAR(p, n) \ 770 ((n) == 4 && ((unsigned char)(p)[3] & 0xFC) != 0xDC) 771 772 #ifdef XML_MIN_SIZE 773 774 static int 775 little2_byteType(const ENCODING *enc, const char *p) { 776 return LITTLE2_BYTE_TYPE(enc, p); 777 } 778 779 static int 780 little2_byteToAscii(const ENCODING *enc, const char *p) { 781 UNUSED_P(enc); 782 return LITTLE2_BYTE_TO_ASCII(p); 783 } 784 785 static int 786 little2_charMatches(const ENCODING *enc, const char *p, int c) { 787 UNUSED_P(enc); 788 return LITTLE2_CHAR_MATCHES(p, c); 789 } 790 791 static int 792 little2_isNameMin(const ENCODING *enc, const char *p) { 793 UNUSED_P(enc); 794 return LITTLE2_IS_NAME_CHAR_MINBPC(p); 795 } 796 797 static int 798 little2_isNmstrtMin(const ENCODING *enc, const char *p) { 799 UNUSED_P(enc); 800 return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); 801 } 802 803 static int 804 little2_isInvalid4(const ENCODING *enc, const char *p) { 805 UNUSED_P(enc); 806 return LITTLE2_IS_INVALID_CHAR(p, 4); 807 } 808 809 # undef VTABLE 810 # define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 811 812 #else /* not XML_MIN_SIZE */ 813 814 # undef PREFIX 815 # define PREFIX(ident) little2_##ident 816 # define MINBPC(enc) 2 817 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ 818 # define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) 819 # define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) 820 # define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) 821 # define IS_NAME_CHAR(enc, p, n) 0 822 # define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) 823 # define IS_NMSTRT_CHAR(enc, p, n) (0) 824 # define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) 825 # define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n) 826 827 # define XML_TOK_IMPL_C 828 # include "xmltok_impl.c" 829 # undef XML_TOK_IMPL_C 830 831 # undef MINBPC 832 # undef BYTE_TYPE 833 # undef BYTE_TO_ASCII 834 # undef CHAR_MATCHES 835 # undef IS_NAME_CHAR 836 # undef IS_NAME_CHAR_MINBPC 837 # undef IS_NMSTRT_CHAR 838 # undef IS_NMSTRT_CHAR_MINBPC 839 # undef IS_INVALID_CHAR 840 841 #endif /* not XML_MIN_SIZE */ 842 843 #ifdef XML_NS 844 845 static const struct normal_encoding little2_encoding_ns 846 = {{VTABLE, 2, 0, 847 # if BYTEORDER == 1234 848 1 849 # else 850 0 851 # endif 852 }, 853 { 854 # include "asciitab.h" 855 # include "latin1tab.h" 856 }, 857 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 858 859 #endif 860 861 static const struct normal_encoding little2_encoding 862 = {{VTABLE, 2, 0, 863 #if BYTEORDER == 1234 864 1 865 #else 866 0 867 #endif 868 }, 869 { 870 #define BT_COLON BT_NMSTRT 871 #include "asciitab.h" 872 #undef BT_COLON 873 #include "latin1tab.h" 874 }, 875 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 876 877 #if BYTEORDER != 4321 878 879 # ifdef XML_NS 880 881 static const struct normal_encoding internal_little2_encoding_ns 882 = {{VTABLE, 2, 0, 1}, 883 { 884 # include "iasciitab.h" 885 # include "latin1tab.h" 886 }, 887 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 888 889 # endif 890 891 static const struct normal_encoding internal_little2_encoding 892 = {{VTABLE, 2, 0, 1}, 893 { 894 # define BT_COLON BT_NMSTRT 895 # include "iasciitab.h" 896 # undef BT_COLON 897 # include "latin1tab.h" 898 }, 899 STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)}; 900 901 #endif 902 903 #define BIG2_BYTE_TYPE(enc, p) \ 904 ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1])) 905 #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) 906 #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) 907 #define BIG2_IS_NAME_CHAR_MINBPC(p) \ 908 UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) 909 #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ 910 UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) 911 /* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4 912 for a high surrogate, so the pair is invalid unless the second unit is a low 913 surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */ 914 #define BIG2_IS_INVALID_CHAR(p, n) \ 915 ((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC) 916 917 #ifdef XML_MIN_SIZE 918 919 static int 920 big2_byteType(const ENCODING *enc, const char *p) { 921 return BIG2_BYTE_TYPE(enc, p); 922 } 923 924 static int 925 big2_byteToAscii(const ENCODING *enc, const char *p) { 926 UNUSED_P(enc); 927 return BIG2_BYTE_TO_ASCII(p); 928 } 929 930 static int 931 big2_charMatches(const ENCODING *enc, const char *p, int c) { 932 UNUSED_P(enc); 933 return BIG2_CHAR_MATCHES(p, c); 934 } 935 936 static int 937 big2_isNameMin(const ENCODING *enc, const char *p) { 938 UNUSED_P(enc); 939 return BIG2_IS_NAME_CHAR_MINBPC(p); 940 } 941 942 static int 943 big2_isNmstrtMin(const ENCODING *enc, const char *p) { 944 UNUSED_P(enc); 945 return BIG2_IS_NMSTRT_CHAR_MINBPC(p); 946 } 947 948 static int 949 big2_isInvalid4(const ENCODING *enc, const char *p) { 950 UNUSED_P(enc); 951 return BIG2_IS_INVALID_CHAR(p, 4); 952 } 953 954 # undef VTABLE 955 # define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 956 957 #else /* not XML_MIN_SIZE */ 958 959 # undef PREFIX 960 # define PREFIX(ident) big2_##ident 961 # define MINBPC(enc) 2 962 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ 963 # define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) 964 # define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) 965 # define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) 966 # define IS_NAME_CHAR(enc, p, n) 0 967 # define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) 968 # define IS_NMSTRT_CHAR(enc, p, n) (0) 969 # define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) 970 # define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n) 971 972 # define XML_TOK_IMPL_C 973 # include "xmltok_impl.c" 974 # undef XML_TOK_IMPL_C 975 976 # undef MINBPC 977 # undef BYTE_TYPE 978 # undef BYTE_TO_ASCII 979 # undef CHAR_MATCHES 980 # undef IS_NAME_CHAR 981 # undef IS_NAME_CHAR_MINBPC 982 # undef IS_NMSTRT_CHAR 983 # undef IS_NMSTRT_CHAR_MINBPC 984 # undef IS_INVALID_CHAR 985 986 #endif /* not XML_MIN_SIZE */ 987 988 #ifdef XML_NS 989 990 static const struct normal_encoding big2_encoding_ns 991 = {{VTABLE, 2, 0, 992 # if BYTEORDER == 4321 993 1 994 # else 995 0 996 # endif 997 }, 998 { 999 # include "asciitab.h" 1000 # include "latin1tab.h" 1001 }, 1002 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 1003 1004 #endif 1005 1006 static const struct normal_encoding big2_encoding 1007 = {{VTABLE, 2, 0, 1008 #if BYTEORDER == 4321 1009 1 1010 #else 1011 0 1012 #endif 1013 }, 1014 { 1015 #define BT_COLON BT_NMSTRT 1016 #include "asciitab.h" 1017 #undef BT_COLON 1018 #include "latin1tab.h" 1019 }, 1020 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 1021 1022 #if BYTEORDER != 1234 1023 1024 # ifdef XML_NS 1025 1026 static const struct normal_encoding internal_big2_encoding_ns 1027 = {{VTABLE, 2, 0, 1}, 1028 { 1029 # include "iasciitab.h" 1030 # include "latin1tab.h" 1031 }, 1032 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 1033 1034 # endif 1035 1036 static const struct normal_encoding internal_big2_encoding 1037 = {{VTABLE, 2, 0, 1}, 1038 { 1039 # define BT_COLON BT_NMSTRT 1040 # include "iasciitab.h" 1041 # undef BT_COLON 1042 # include "latin1tab.h" 1043 }, 1044 STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)}; 1045 1046 #endif 1047 1048 #undef PREFIX 1049 1050 static int 1051 streqci(const char *s1, const char *s2) { 1052 for (;;) { 1053 char c1 = *s1++; 1054 char c2 = *s2++; 1055 if (ASCII_a <= c1 && c1 <= ASCII_z) 1056 c1 += ASCII_A - ASCII_a; 1057 if (ASCII_a <= c2 && c2 <= ASCII_z) 1058 /* The following line will never get executed. streqci() is 1059 * only called from two places, both of which guarantee to put 1060 * upper-case strings into s2. 1061 */ 1062 c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ 1063 if (c1 != c2) 1064 return 0; 1065 if (! c1) 1066 break; 1067 } 1068 return 1; 1069 } 1070 1071 static void 1072 initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, 1073 POSITION *pos) { 1074 UNUSED_P(enc); 1075 normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); 1076 } 1077 1078 static int 1079 toAscii(const ENCODING *enc, const char *ptr, const char *end) { 1080 char buf[1]; 1081 char *p = buf; 1082 XmlUtf8Convert(enc, &ptr, end, &p, p + 1); 1083 if (p == buf) 1084 return -1; 1085 else 1086 return buf[0]; 1087 } 1088 1089 static int 1090 isSpace(int c) { 1091 switch (c) { 1092 case 0x20: 1093 case 0xD: 1094 case 0xA: 1095 case 0x9: 1096 return 1; 1097 } 1098 return 0; 1099 } 1100 1101 /* Return 1 if there's just optional white space or there's an S 1102 followed by name=val. 1103 */ 1104 static int 1105 parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, 1106 const char **namePtr, const char **nameEndPtr, 1107 const char **valPtr, const char **nextTokPtr) { 1108 int c; 1109 char open; 1110 if (ptr == end) { 1111 *namePtr = NULL; 1112 return 1; 1113 } 1114 if (! isSpace(toAscii(enc, ptr, end))) { 1115 *nextTokPtr = ptr; 1116 return 0; 1117 } 1118 do { 1119 ptr += enc->minBytesPerChar; 1120 } while (isSpace(toAscii(enc, ptr, end))); 1121 if (ptr == end) { 1122 *namePtr = NULL; 1123 return 1; 1124 } 1125 *namePtr = ptr; 1126 for (;;) { 1127 c = toAscii(enc, ptr, end); 1128 if (c == -1) { 1129 *nextTokPtr = ptr; 1130 return 0; 1131 } 1132 if (c == ASCII_EQUALS) { 1133 *nameEndPtr = ptr; 1134 break; 1135 } 1136 if (isSpace(c)) { 1137 *nameEndPtr = ptr; 1138 do { 1139 ptr += enc->minBytesPerChar; 1140 } while (isSpace(c = toAscii(enc, ptr, end))); 1141 if (c != ASCII_EQUALS) { 1142 *nextTokPtr = ptr; 1143 return 0; 1144 } 1145 break; 1146 } 1147 ptr += enc->minBytesPerChar; 1148 } 1149 if (ptr == *namePtr) { 1150 *nextTokPtr = ptr; 1151 return 0; 1152 } 1153 ptr += enc->minBytesPerChar; 1154 c = toAscii(enc, ptr, end); 1155 while (isSpace(c)) { 1156 ptr += enc->minBytesPerChar; 1157 c = toAscii(enc, ptr, end); 1158 } 1159 if (c != ASCII_QUOT && c != ASCII_APOS) { 1160 *nextTokPtr = ptr; 1161 return 0; 1162 } 1163 open = (char)c; 1164 ptr += enc->minBytesPerChar; 1165 *valPtr = ptr; 1166 for (;; ptr += enc->minBytesPerChar) { 1167 c = toAscii(enc, ptr, end); 1168 if (c == open) 1169 break; 1170 if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) 1171 && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD 1172 && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { 1173 *nextTokPtr = ptr; 1174 return 0; 1175 } 1176 } 1177 *nextTokPtr = ptr + enc->minBytesPerChar; 1178 return 1; 1179 } 1180 1181 static const char KW_version[] 1182 = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; 1183 1184 static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, 1185 ASCII_i, ASCII_n, ASCII_g, '\0'}; 1186 1187 static const char KW_standalone[] 1188 = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, 1189 ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; 1190 1191 static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; 1192 1193 static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; 1194 1195 static const char KW_1_dot[] = {ASCII_1, ASCII_PERIOD, '\0'}; 1196 1197 /* Checks a version pseudo-attribute value against the VersionNum production. 1198 XML 1.0 Fourth Edition only allows the literal "1.0", but the Fifth 1199 Edition relaxed this to "1." followed by one or more digits, since Expat 1200 only implements 1.0 itself but plans to track the Fifth Edition's laxer 1201 grammar here so that "1.1" and similar aren't rejected only to have that 1202 rejection reverted later. Returns true for a value matching "1.[0-9]+". 1203 val/valEnd bound the value itself; valEnd is the upper bound used when 1204 decoding the individual characters between them. */ 1205 static bool 1206 checkXmlDeclVersionNum(const ENCODING *enc, const char *val, 1207 const char *valEnd) { 1208 if (valEnd - val < 2 * enc->minBytesPerChar 1209 || ! XmlNameMatchesAscii(enc, val, val + 2 * enc->minBytesPerChar, 1210 KW_1_dot)) 1211 return false; 1212 val += 2 * enc->minBytesPerChar; 1213 if (val == valEnd) 1214 return false; 1215 for (; val != valEnd; val += enc->minBytesPerChar) { 1216 int c = toAscii(enc, val, valEnd); 1217 if (c < ASCII_0 || c > ASCII_9) 1218 return false; 1219 } 1220 return true; 1221 } 1222 1223 static int 1224 doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, 1225 const char *), 1226 int isGeneralTextEntity, const ENCODING *enc, const char *ptr, 1227 const char *end, const char **badPtr, const char **versionPtr, 1228 const char **versionEndPtr, const char **encodingName, 1229 const ENCODING **encoding, int *standalone) { 1230 const char *val = NULL; 1231 const char *name = NULL; 1232 const char *nameEnd = NULL; 1233 ptr += 5 * enc->minBytesPerChar; 1234 end -= 2 * enc->minBytesPerChar; 1235 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) 1236 || ! name) { 1237 *badPtr = ptr; 1238 return 0; 1239 } 1240 if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { 1241 if (! isGeneralTextEntity) { 1242 *badPtr = name; 1243 return 0; 1244 } 1245 } else { 1246 if (versionPtr) 1247 *versionPtr = val; 1248 if (versionEndPtr) 1249 *versionEndPtr = ptr; 1250 /* The version number must not be empty; VersionNum requires at least 1251 one character. The encoding and standalone pseudo-attributes below 1252 already reject an empty value, so keep version consistent. */ 1253 if (val == ptr - enc->minBytesPerChar) { 1254 *badPtr = val; 1255 return 0; 1256 } 1257 /* Expat implements XML 1.0 only, so any version outside the "1.0"/"1.x" 1258 family is rejected. Following the Fifth Edition's VersionNum 1259 production (rather than the Fourth Edition's exact "1.0") avoids 1260 rejecting "1.1" now only to have to revert that once Expat tracks 1261 the newer edition. */ 1262 if (! checkXmlDeclVersionNum(enc, val, ptr - enc->minBytesPerChar)) { 1263 *badPtr = val; 1264 return 0; 1265 } 1266 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { 1267 *badPtr = ptr; 1268 return 0; 1269 } 1270 if (! name) { 1271 if (isGeneralTextEntity) { 1272 /* a TextDecl must have an EncodingDecl */ 1273 *badPtr = ptr; 1274 return 0; 1275 } 1276 return 1; 1277 } 1278 } 1279 if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { 1280 int c = toAscii(enc, val, end); 1281 if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { 1282 *badPtr = val; 1283 return 0; 1284 } 1285 if (encodingName) 1286 *encodingName = val; 1287 if (encoding) 1288 *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); 1289 if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { 1290 *badPtr = ptr; 1291 return 0; 1292 } 1293 if (! name) 1294 return 1; 1295 } 1296 if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) 1297 || isGeneralTextEntity) { 1298 *badPtr = name; 1299 return 0; 1300 } 1301 if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { 1302 if (standalone) 1303 *standalone = 1; 1304 } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { 1305 if (standalone) 1306 *standalone = 0; 1307 } else { 1308 *badPtr = val; 1309 return 0; 1310 } 1311 while (isSpace(toAscii(enc, ptr, end))) 1312 ptr += enc->minBytesPerChar; 1313 if (ptr != end) { 1314 *badPtr = ptr; 1315 return 0; 1316 } 1317 return 1; 1318 } 1319 1320 static int 1321 checkCharRefNumber(int result) { 1322 switch (result >> 8) { 1323 case 0xD8: 1324 case 0xD9: 1325 case 0xDA: 1326 case 0xDB: 1327 case 0xDC: 1328 case 0xDD: 1329 case 0xDE: 1330 case 0xDF: 1331 return -1; 1332 case 0: 1333 if (latin1_encoding.type[result] == BT_NONXML) 1334 return -1; 1335 break; 1336 case 0xFF: 1337 if (result == 0xFFFE || result == 0xFFFF) 1338 return -1; 1339 break; 1340 } 1341 return result; 1342 } 1343 1344 int 1345 XmlUtf8Encode(int c, char *buf) { 1346 enum { 1347 /* minN is minimum legal resulting value for N byte sequence */ 1348 min2 = 0x80, 1349 min3 = 0x800, 1350 min4 = 0x10000 1351 }; 1352 1353 if (c < 0) 1354 return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ 1355 if (c < min2) { 1356 buf[0] = (char)(c | UTF8_cval1); 1357 return 1; 1358 } 1359 if (c < min3) { 1360 buf[0] = (char)((c >> 6) | UTF8_cval2); 1361 buf[1] = (char)((c & 0x3f) | 0x80); 1362 return 2; 1363 } 1364 if (c < min4) { 1365 buf[0] = (char)((c >> 12) | UTF8_cval3); 1366 buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); 1367 buf[2] = (char)((c & 0x3f) | 0x80); 1368 return 3; 1369 } 1370 if (c < 0x110000) { 1371 buf[0] = (char)((c >> 18) | UTF8_cval4); 1372 buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); 1373 buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); 1374 buf[3] = (char)((c & 0x3f) | 0x80); 1375 return 4; 1376 } 1377 return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ 1378 } 1379 1380 int 1381 XmlUtf16Encode(int charNum, unsigned short *buf) { 1382 if (charNum < 0) 1383 return 0; 1384 if (charNum < 0x10000) { 1385 buf[0] = (unsigned short)charNum; 1386 return 1; 1387 } 1388 if (charNum < 0x110000) { 1389 charNum -= 0x10000; 1390 buf[0] = (unsigned short)((charNum >> 10) + 0xD800); 1391 buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); 1392 return 2; 1393 } 1394 return 0; 1395 } 1396 1397 struct unknown_encoding { 1398 struct normal_encoding normal; 1399 CONVERTER convert; 1400 void *userData; 1401 unsigned short utf16[256]; 1402 char utf8[256][4]; 1403 }; 1404 1405 #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) 1406 1407 int 1408 XmlSizeOfUnknownEncoding(void) { 1409 return sizeof(struct unknown_encoding); 1410 } 1411 1412 static int 1413 unknown_isName(const ENCODING *enc, const char *p) { 1414 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1415 int c = uenc->convert(uenc->userData, p); 1416 if (c & ~0xFFFF) 1417 return 0; 1418 return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); 1419 } 1420 1421 static int 1422 unknown_isNmstrt(const ENCODING *enc, const char *p) { 1423 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1424 int c = uenc->convert(uenc->userData, p); 1425 if (c & ~0xFFFF) 1426 return 0; 1427 return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); 1428 } 1429 1430 static int 1431 unknown_isInvalid(const ENCODING *enc, const char *p) { 1432 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1433 int c = uenc->convert(uenc->userData, p); 1434 return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; 1435 } 1436 1437 static enum XML_Convert_Result 1438 unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, 1439 char **toP, const char *toLim) { 1440 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1441 char buf[XML_UTF8_ENCODE_MAX]; 1442 for (;;) { 1443 const char *utf8; 1444 int n; 1445 if (*fromP == fromLim) 1446 return XML_CONVERT_COMPLETED; 1447 utf8 = uenc->utf8[(unsigned char)**fromP]; 1448 n = *utf8++; 1449 if (n == 0) { 1450 int c = uenc->convert(uenc->userData, *fromP); 1451 n = XmlUtf8Encode(c, buf); 1452 if (n > toLim - *toP) 1453 return XML_CONVERT_OUTPUT_EXHAUSTED; 1454 utf8 = buf; 1455 *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] 1456 - (BT_LEAD2 - 2)); 1457 } else { 1458 if (n > toLim - *toP) 1459 return XML_CONVERT_OUTPUT_EXHAUSTED; 1460 (*fromP)++; 1461 } 1462 memcpy(*toP, utf8, n); 1463 *toP += n; 1464 } 1465 } 1466 1467 static enum XML_Convert_Result 1468 unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, 1469 unsigned short **toP, const unsigned short *toLim) { 1470 const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); 1471 while (*fromP < fromLim && *toP < toLim) { 1472 unsigned short c = uenc->utf16[(unsigned char)**fromP]; 1473 if (c == 0) { 1474 c = (unsigned short)uenc->convert(uenc->userData, *fromP); 1475 *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] 1476 - (BT_LEAD2 - 2)); 1477 } else 1478 (*fromP)++; 1479 *(*toP)++ = c; 1480 } 1481 1482 if ((*toP == toLim) && (*fromP < fromLim)) 1483 return XML_CONVERT_OUTPUT_EXHAUSTED; 1484 else 1485 return XML_CONVERT_COMPLETED; 1486 } 1487 1488 ENCODING * 1489 XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert, 1490 void *userData) { 1491 int i; 1492 struct unknown_encoding *e = (struct unknown_encoding *)mem; 1493 memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); 1494 for (i = 0; i < 128; i++) 1495 if (latin1_encoding.type[i] != BT_OTHER 1496 && latin1_encoding.type[i] != BT_NONXML && table[i] != i) 1497 return 0; 1498 for (i = 0; i < 256; i++) { 1499 int c = table[i]; 1500 if (c == -1) { 1501 e->normal.type[i] = BT_MALFORM; 1502 /* This shouldn't really get used. */ 1503 e->utf16[i] = 0xFFFF; 1504 e->utf8[i][0] = 1; 1505 e->utf8[i][1] = 0; 1506 } else if (c < 0) { 1507 if (c < -4) 1508 return 0; 1509 /* Multi-byte sequences need a converter function */ 1510 if (! convert) 1511 return 0; 1512 e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); 1513 e->utf8[i][0] = 0; 1514 e->utf16[i] = 0; 1515 } else if (c < 0x80) { 1516 if (latin1_encoding.type[c] != BT_OTHER 1517 && latin1_encoding.type[c] != BT_NONXML && c != i) 1518 return 0; 1519 e->normal.type[i] = latin1_encoding.type[c]; 1520 e->utf8[i][0] = 1; 1521 e->utf8[i][1] = (char)c; 1522 e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); 1523 } else if (checkCharRefNumber(c) < 0) { 1524 e->normal.type[i] = BT_NONXML; 1525 /* This shouldn't really get used. */ 1526 e->utf16[i] = 0xFFFF; 1527 e->utf8[i][0] = 1; 1528 e->utf8[i][1] = 0; 1529 } else { 1530 if (c > 0xFFFF) 1531 return 0; 1532 if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) 1533 e->normal.type[i] = BT_NMSTRT; 1534 else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) 1535 e->normal.type[i] = BT_NAME; 1536 else 1537 e->normal.type[i] = BT_OTHER; 1538 e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); 1539 e->utf16[i] = (unsigned short)c; 1540 } 1541 } 1542 e->userData = userData; 1543 e->convert = convert; 1544 if (convert) { 1545 e->normal.isName2 = unknown_isName; 1546 e->normal.isName3 = unknown_isName; 1547 e->normal.isName4 = unknown_isName; 1548 e->normal.isNmstrt2 = unknown_isNmstrt; 1549 e->normal.isNmstrt3 = unknown_isNmstrt; 1550 e->normal.isNmstrt4 = unknown_isNmstrt; 1551 e->normal.isInvalid2 = unknown_isInvalid; 1552 e->normal.isInvalid3 = unknown_isInvalid; 1553 e->normal.isInvalid4 = unknown_isInvalid; 1554 } 1555 e->normal.enc.utf8Convert = unknown_toUtf8; 1556 e->normal.enc.utf16Convert = unknown_toUtf16; 1557 return &(e->normal.enc); 1558 } 1559 1560 /* If this enumeration is changed, getEncodingIndex and encodings 1561 must also be changed. */ 1562 enum { 1563 UNKNOWN_ENC = -1, 1564 ISO_8859_1_ENC = 0, 1565 US_ASCII_ENC, 1566 UTF_8_ENC, 1567 UTF_16_ENC, 1568 UTF_16BE_ENC, 1569 UTF_16LE_ENC, 1570 /* must match encodingNames up to here */ 1571 NO_ENC 1572 }; 1573 1574 static const char KW_ISO_8859_1[] 1575 = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, 1576 ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; 1577 static const char KW_US_ASCII[] 1578 = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, 1579 ASCII_C, ASCII_I, ASCII_I, '\0'}; 1580 static const char KW_UTF_8[] 1581 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; 1582 static const char KW_UTF_16[] 1583 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; 1584 static const char KW_UTF_16BE[] 1585 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, 1586 ASCII_6, ASCII_B, ASCII_E, '\0'}; 1587 static const char KW_UTF_16LE[] 1588 = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, 1589 ASCII_6, ASCII_L, ASCII_E, '\0'}; 1590 1591 static int 1592 getEncodingIndex(const char *name) { 1593 static const char *const encodingNames[] = { 1594 KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, 1595 }; 1596 int i; 1597 if (name == NULL) 1598 return NO_ENC; 1599 for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) 1600 if (streqci(name, encodingNames[i])) 1601 return i; 1602 return UNKNOWN_ENC; 1603 } 1604 1605 /* For binary compatibility, we store the index of the encoding 1606 specified at initialization in the isUtf16 member. 1607 */ 1608 1609 #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) 1610 #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) 1611 1612 /* This is what detects the encoding. encodingTable maps from 1613 encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of 1614 the external (protocol) specified encoding; state is 1615 XML_CONTENT_STATE if we're parsing an external text entity, and 1616 XML_PROLOG_STATE otherwise. 1617 */ 1618 1619 static int 1620 initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, 1621 int state, const char *ptr, const char *end, const char **nextTokPtr) { 1622 const ENCODING **encPtr; 1623 1624 if (ptr >= end) 1625 return XML_TOK_NONE; 1626 encPtr = enc->encPtr; 1627 if (ptr + 1 == end) { 1628 /* only a single byte available for auto-detection */ 1629 #ifndef XML_DTD /* FIXME */ 1630 /* a well-formed document entity must have more than one byte */ 1631 if (state != XML_CONTENT_STATE) 1632 return XML_TOK_PARTIAL; 1633 #endif 1634 /* so we're parsing an external text entity... */ 1635 /* if UTF-16 was externally specified, then we need at least 2 bytes */ 1636 switch (INIT_ENC_INDEX(enc)) { 1637 case UTF_16_ENC: 1638 case UTF_16LE_ENC: 1639 case UTF_16BE_ENC: 1640 return XML_TOK_PARTIAL; 1641 } 1642 switch ((unsigned char)*ptr) { 1643 case 0xFE: 1644 case 0xFF: 1645 case 0xEF: /* possibly first byte of UTF-8 BOM */ 1646 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1647 break; 1648 EXPAT_FALLTHROUGH; 1649 case 0x00: 1650 case 0x3C: 1651 return XML_TOK_PARTIAL; 1652 } 1653 } else { 1654 switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { 1655 case 0xFEFF: 1656 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1657 break; 1658 *nextTokPtr = ptr + 2; 1659 *encPtr = encodingTable[UTF_16BE_ENC]; 1660 return XML_TOK_BOM; 1661 /* 00 3C is handled in the default case */ 1662 case 0x3C00: 1663 if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC 1664 || INIT_ENC_INDEX(enc) == UTF_16_ENC) 1665 && state == XML_CONTENT_STATE) 1666 break; 1667 *encPtr = encodingTable[UTF_16LE_ENC]; 1668 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1669 case 0xFFFE: 1670 if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) 1671 break; 1672 *nextTokPtr = ptr + 2; 1673 *encPtr = encodingTable[UTF_16LE_ENC]; 1674 return XML_TOK_BOM; 1675 case 0xEFBB: 1676 /* Maybe a UTF-8 BOM (EF BB BF) */ 1677 /* If there's an explicitly specified (external) encoding 1678 of ISO-8859-1 or some flavour of UTF-16 1679 and this is an external text entity, 1680 don't look for the BOM, 1681 because it might be a legal data. 1682 */ 1683 if (state == XML_CONTENT_STATE) { 1684 int e = INIT_ENC_INDEX(enc); 1685 if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC 1686 || e == UTF_16_ENC) 1687 break; 1688 } 1689 if (ptr + 2 == end) 1690 return XML_TOK_PARTIAL; 1691 if ((unsigned char)ptr[2] == 0xBF) { 1692 *nextTokPtr = ptr + 3; 1693 *encPtr = encodingTable[UTF_8_ENC]; 1694 return XML_TOK_BOM; 1695 } 1696 break; 1697 default: 1698 if (ptr[0] == '\0') { 1699 /* 0 isn't a legal data character. Furthermore a document 1700 entity can only start with ASCII characters. So the only 1701 way this can fail to be big-endian UTF-16 if it it's an 1702 external parsed general entity that's labelled as 1703 UTF-16LE. 1704 */ 1705 if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) 1706 break; 1707 *encPtr = encodingTable[UTF_16BE_ENC]; 1708 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1709 } else if (ptr[1] == '\0') { 1710 /* We could recover here in the case: 1711 - parsing an external entity 1712 - second byte is 0 1713 - no externally specified encoding 1714 - no encoding declaration 1715 by assuming UTF-16LE. But we don't, because this would mean when 1716 presented just with a single byte, we couldn't reliably determine 1717 whether we needed further bytes. 1718 */ 1719 if (state == XML_CONTENT_STATE) 1720 break; 1721 *encPtr = encodingTable[UTF_16LE_ENC]; 1722 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1723 } 1724 break; 1725 } 1726 } 1727 *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; 1728 return XmlTok(*encPtr, state, ptr, end, nextTokPtr); 1729 } 1730 1731 #define NS(x) x 1732 #define ns(x) x 1733 #define XML_TOK_NS_C 1734 #include "xmltok_ns.c" 1735 #undef XML_TOK_NS_C 1736 #undef NS 1737 #undef ns 1738 1739 #ifdef XML_NS 1740 1741 # define NS(x) x##NS 1742 # define ns(x) x##_ns 1743 1744 # define XML_TOK_NS_C 1745 # include "xmltok_ns.c" 1746 # undef XML_TOK_NS_C 1747 1748 # undef NS 1749 # undef ns 1750 1751 ENCODING * 1752 XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert, 1753 void *userData) { 1754 ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); 1755 if (enc) 1756 ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; 1757 return enc; 1758 } 1759 1760 #endif /* XML_NS */ 1761