- ucs_ch = ch;
- break;
-
- case 3: ch = byte; /* 1st byte */
- ch <<= 6;
- ch += *utf8p++; /* 2nd byte */
- ch <<= 6;
- ch += *utf8p++; /* 3rd byte */
- ch <<= 6;
- ch += *utf8p++; /* 4th byte */
- ch -= 0x03C82080UL + SP_HALF_BASE;
- ucs_ch = (ch >> SP_HALF_SHIFT) + SP_HIGH_FIRST;
- *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
- if (ucsp >= bufend)
- goto toolong;
- ucs_ch = (ch & SP_HALF_MASK) + SP_LOW_FIRST;
- *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
+ if (ch == 0xFFFE || ch == 0xFFFF)
+ goto invalid;
+ }
+ ucs_ch = ch;
+ break;
+ case 3:
+ ch = byte; ch <<= 6; /* 1st byte */
+ byte = *utf8p++; /* 2nd byte */
+ if ((byte >> 6) != 2)
+ goto invalid;
+ ch += byte; ch <<= 6;
+ byte = *utf8p++; /* 3rd byte */
+ if ((byte >> 6) != 2)
+ goto invalid;
+ ch += byte; ch <<= 6;
+ byte = *utf8p++; /* 4th byte */
+ if ((byte >> 6) != 2)
+ goto invalid;
+ ch += byte;
+ ch -= 0x03C82080UL + SP_HALF_BASE;
+ ucs_ch = (ch >> SP_HALF_SHIFT) + SP_HIGH_FIRST;
+ if (ucs_ch < SP_HIGH_FIRST || ucs_ch > SP_HIGH_LAST)
+ goto invalid;
+ *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;
+ if (ucsp >= bufend)
+ goto toolong;
+ ucs_ch = (ch & SP_HALF_MASK) + SP_LOW_FIRST;
+ if (ucs_ch < SP_LOW_FIRST || ucs_ch > SP_LOW_LAST)
+ goto invalid;
+ *ucsp++ = swapbytes ? NXSwapShort(ucs_ch) : ucs_ch;