Example #1
0
static int
traverse_string(const unsigned char *p, int len, int inform,
    int (*rfunc)(unsigned long value, void *in), void *arg)
{
	unsigned long value;
	int ret;

	while (len) {
		switch (inform) {
		case MBSTRING_ASC:
			value = *p++;
			len--;
			break;
		case MBSTRING_BMP:
			value = *p++ << 8;
			value |= *p++;
			/* BMP is explictly defined to not support surrogates */
			if (UNICODE_IS_SURROGATE(value))
				return -1;
			len -= 2;
			break;
		case MBSTRING_UNIV:
			value = (unsigned long)*p++ << 24;
			value |= *p++ << 16;
			value |= *p++ << 8;
			value |= *p++;
			if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
				return -1;
			len -= 4;
			break;
		default:
			ret = UTF8_getc(p, len, &value);
			if (ret < 0)
				return -1;
			len -= ret;
			p += ret;
			break;
		}
		if (rfunc) {
			ret = rfunc(value, arg);
			if (ret <= 0)
				return ret;
		}
	}
	return 1;
}
Example #2
0
static int
do_buf(unsigned char *buf, int buflen, int type, unsigned char flags,
    char *quotes, char_io *io_ch, void *arg)
{
	int i, outlen, len;
	unsigned char orflags, *p, *q;
	unsigned long c;

	p = buf;
	q = buf + buflen;
	outlen = 0;
	while (p != q) {
		if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
			orflags = CHARTYPE_FIRST_ESC_2253;
		else
			orflags = 0;
		switch (type & BUF_TYPE_WIDTH_MASK) {
		case 4:
			c = ((unsigned long)*p++) << 24;
			c |= ((unsigned long)*p++) << 16;
			c |= ((unsigned long)*p++) << 8;
			c |= *p++;
			if (c > UNICODE_MAX || UNICODE_IS_SURROGATE(c))
				return -1;
			break;

		case 2:
			c = ((unsigned long)*p++) << 8;
			c |= *p++;
			if (UNICODE_IS_SURROGATE(c))
				return -1;
			break;

		case 1:
			c = *p++;
			break;

		case 0:
			i = UTF8_getc(p, q - p, &c);
			if (i < 0)
				return -1;	/* Invalid UTF8String */
			p += i;
			break;
		default:
			return -1;		/* invalid width */
		}
		if (p == q && flags & ASN1_STRFLGS_ESC_2253)
			orflags = CHARTYPE_LAST_ESC_2253;
		if (type & BUF_TYPE_CONVUTF8) {
			unsigned char utfbuf[6];
			int utflen;

			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
			if (utflen < 0)
				return -1;
			for (i = 0; i < utflen; i++) {
				/* We don't need to worry about setting orflags correctly
				 * because if utflen==1 its value will be correct anyway
				 * otherwise each character will be > 0x7f and so the
				 * character will never be escaped on first and last.
				 */
				len = do_esc_char(utfbuf[i],
				    (unsigned char)(flags | orflags), quotes,
				    io_ch, arg);
				if (len < 0)
					return -1;
				outlen += len;
			}
		} else {
			len = do_esc_char(c, (unsigned char)(flags | orflags),
			    quotes, io_ch, arg);
			if (len < 0)
				return -1;
			outlen += len;
		}
	}
	return outlen;
}