Example #1
0
idn_result_t
idn__race_decode(idn_converter_t ctx, void *privdata, 
		 const char *from, unsigned long *to, size_t tolen) {
	unsigned short *buf = NULL;
	size_t prefixlen = strlen(IDN_RACE_PREFIX);
	size_t fromlen;
	size_t buflen;
	idn_result_t r;

	assert(ctx != NULL);

	TRACE(("idn__race_decode(from=\"%s\", tolen=%d)\n",
	       idn__debug_xstring(from, 50), (int)tolen));

	if (!idn__util_asciihaveaceprefix(from, IDN_RACE_PREFIX)) {
		if (*from == '\0') {
			r = idn_ucs4_utf8toucs4(from, to, tolen);
			goto ret;
		}
		r = idn_invalid_encoding;
		goto ret;
	}
	from += prefixlen;
	fromlen = strlen(from);

	/*
	 * Allocate sufficient buffer.
	 */
	buflen = fromlen + 1;
	buf = malloc(sizeof(*buf) * buflen);
	if (buf == NULL) {
		r = idn_nomemory;
		goto ret;
	}

	/*
	 * Decode base32 and decompress.
	 */
	r = race_decode_decompress(from, buf, buflen);
	if (r != idn_success)
		goto ret;

	/*
	 * Now 'buf' points the decompressed string, which must contain
	 * UTF-16 characters.
	 */

	/*
	 * Convert to UCS4.
	 */
	r = idn_ucs4_utf16toucs4(buf, to, tolen);
	if (r != idn_success)
		goto ret;

ret:
	free(buf);
	if (r == idn_success) {
		TRACE(("idn__race_decode(): succcess (to=\"%s\")\n",
		       idn__debug_ucs4xstring(to, 50)));
	} else {
		TRACE(("idn__race_decode(): %s\n", idn_result_tostring(r)));
	}
	return (r);
}
Example #2
0
idn_result_t
idn__punycode_decode(idn_converter_t ctx, void *privdata,
		    const char *from, unsigned long *to, size_t tolen) {
	unsigned long *to_org = to;
	unsigned long c, idx;
	size_t prefixlen = strlen(IDN_PUNYCODE_PREFIX);
	size_t fromlen;
	size_t uidx, fidx, ucslen;
	int first, bias;
	idn_result_t r;

	assert(ctx != NULL);

	TRACE(("idn__punycode_decode(from=\"%s\", tolen=%d)\n",
	       idn__debug_xstring(from, 50), (int)tolen));

	if (!idn__util_asciihaveaceprefix(from, IDN_PUNYCODE_PREFIX)) {
		if (*from == '\0') {
			r = idn_ucs4_utf8toucs4(from, to, tolen);
			goto ret;
		}
		r = idn_invalid_encoding;
		goto ret;
	}
	from += prefixlen;
	fromlen = strlen(from);

	/*
	 * Find the last delimiter, and copy the characters
	 * before it verbatim.
	 */
	ucslen = 0;
	for (fidx = fromlen; fidx > 0; fidx--) {
		if (from[fidx - 1] == '-') {
			if (tolen < fidx) {
				r = idn_buffer_overflow;
				goto ret;
			}
			for (uidx = 0; uidx < fidx - 1; uidx++) {
				to[uidx] = from[uidx];
			}
			ucslen = uidx;
			break;
		}
	}

	first = 1;
	bias = PUNYCODE_INITIAL_BIAS;
	c = PUNYCODE_INITIAL_N;
	idx = 0;
	while (fidx < fromlen) {
		int len;
		unsigned long delta;
		int i;

		len = punycode_getwc(from + fidx, fromlen - fidx, bias, &delta);
		if (len == 0) {
			r = idn_invalid_encoding;
			goto ret;
		}
		fidx += len;

		bias = punycode_update_bias(delta, ucslen + 1, first);
		first = 0;
		idx += delta;
		c += idx / (ucslen + 1);
		uidx = idx % (ucslen + 1);

		/* Insert 'c' at uidx. */
		if (tolen-- <= 0) {
			r = idn_buffer_overflow;
			goto ret;
		}
		for (i = ucslen; i > uidx; i--)
			to[i] = to[i - 1];
		to[uidx] = c;

		ucslen++;
		idx = uidx + 1;
	}

	/* Terminate with NUL. */
	if (tolen <= 0) {
		r = idn_buffer_overflow;
		goto ret;
	}
	to[ucslen] = '\0';
	r = idn_success;

ret:
	if (r == idn_success) {
		TRACE(("idn__punycode_decode(): succcess (to=\"%s\")\n",
		       idn__debug_ucs4xstring(to_org, 50)));
	} else {
		TRACE(("idn__punycode_decode(): %s\n", idn_result_tostring(r)));
	}
	return (r);
}