mdn_result_t mdn_res_localtoucs(mdn_resconf_t conf, const char *local_name, char *ucs_name, size_t ucs_name_len) { mdn_converter_t conv; mdn_result_t r; assert(local_name != NULL && ucs_name != NULL); TRACE(("mdn_res_localtoucs(local_name=\"%-.20s\")\n", local_name)); if (conf == NULL) return (copy_verbatim(local_name, ucs_name, ucs_name_len)); if (!contain_invalid_char(local_name) && (conv = mdn_resconf_alternateconverter(conf)) != NULL) { TRACE(("mdn_res_localtoucs: trying alternate converter..\n")); r = mdn_converter_convert(conv, mdn_converter_l2u, local_name, ucs_name, ucs_name_len); if (r == mdn_success) return (r); } if ((conv = mdn_resconf_localconverter(conf)) == NULL) return (copy_verbatim(local_name, ucs_name, ucs_name_len)); TRACE(("mdn_res_localtoucs: using local converter..\n")); return (mdn_converter_convert(conv, mdn_converter_l2u, local_name, ucs_name, ucs_name_len)); }
mdn_result_t mdn_res_dnstoucs(mdn_resconf_t conf, const char *dns_name, char *ucs_name, size_t ucs_name_len) { const char *zld; mdn_converter_t conv; char domainbuf[512]; int convert; assert(dns_name != NULL && ucs_name != NULL); TRACE(("mdn_res_dnstoucs(dns_name=\"%s\")\n", mdn_debug_xstring(dns_name, 20))); if (conf == NULL || (conv = mdn_resconf_serverconverter(conf)) == NULL) return (copy_verbatim(dns_name, ucs_name, ucs_name_len)); if ((zld = mdn_resconf_zld(conf)) != NULL) { if (mdn_translator_matchzld(dns_name, zld)) { /* * Strip 'zld' from 'dns_name'. */ size_t namelen = strlen(dns_name); TRACE(("mdn_res_dnstoucs: ZLD matched\n")); /* 'zld' must end with dot, but 'dns_name' may not. */ if (namelen > 0 && dns_name[namelen - 1] != '.') namelen++; namelen -= strlen(zld); if (namelen >= sizeof(domainbuf)) return (mdn_invalid_name); (void)strncpy(domainbuf, dns_name, namelen); domainbuf[namelen] = '\0'; dns_name = domainbuf; convert = 1; } else if (contain_invalid_char(dns_name)) { TRACE(("mdn_res_dnstoucs: contain invalid char\n")); return (mdn_invalid_name); } else { convert = 0; } } else if (!mdn_converter_isasciicompatible(conv) && !contain_invalid_char(dns_name)) { convert = 0; } else { convert = 1; } if (convert) { TRACE(("mdn_res_dnstoucs: convert to ucs\n")); return (mdn_converter_convert(conv, mdn_converter_l2u, dns_name, ucs_name, ucs_name_len)); } else { return (copy_verbatim(dns_name, ucs_name, ucs_name_len)); } }
mdn_result_t mdn_res_ucstolocal(mdn_resconf_t conf, const char *ucs_name, char *local_name, size_t local_name_len) { mdn_converter_t conv; mdn_result_t r; assert(ucs_name != NULL && local_name != NULL); TRACE(("mdn_res_ucstolocal(ucs_name=\"%s\")\n", mdn_debug_xstring(ucs_name, 20))); if (conf == NULL || (conv = mdn_resconf_localconverter(conf)) == NULL) return (copy_verbatim(ucs_name, local_name, local_name_len)); r = mdn_converter_convert(conv, mdn_converter_u2l, ucs_name, local_name, local_name_len); if (r == mdn_nomapping && (conv = mdn_resconf_alternateconverter(conf)) != NULL) { TRACE(("mdn_res_ucstolocal: switched to alternate converter\n")); r = mdn_converter_convert(conv, mdn_converter_u2l, ucs_name, local_name, local_name_len); } return (r); }
mdn_result_t mdn_res_normalize(mdn_resconf_t conf, const char *name, char *normalized_name, size_t normalized_name_len) { mdn_normalizer_t norm; assert(name != NULL && normalized_name != NULL); TRACE(("mdn_res_normalize(name=\"%s\")\n", mdn_debug_xstring(name, 20))); if (conf == NULL || (norm = mdn_resconf_normalizer(conf)) == NULL) return (copy_verbatim(name, normalized_name, normalized_name_len)); return (mdn_normalizer_normalize(norm, name, normalized_name, normalized_name_len)); }
mdn_result_t mdn_res_ucstodns(mdn_resconf_t conf, const char *ucs_name, char *dns_name, size_t dns_name_len) { mdn_converter_t conv; mdn_result_t r; const char *zld; assert(ucs_name != NULL && dns_name != NULL); TRACE(("mdn_res_ucstodns(ucs_name=\"%s\")\n", mdn_debug_xstring(ucs_name, 20))); if (conf == NULL || (conv = mdn_resconf_serverconverter(conf)) == NULL || !contain_invalid_char(ucs_name)) return (copy_verbatim(ucs_name, dns_name, dns_name_len)); r = mdn_converter_convert(conv, mdn_converter_u2l, ucs_name, dns_name, dns_name_len); if (r != mdn_success) return (r); if ((zld = mdn_resconf_zld(conf)) != NULL) { size_t len; TRACE(("mdn_res_ucstodns: adding ZLD\n")); len = strlen(dns_name); if (len > 0 && dns_name[len - 1] != '.') { if (len + 1 >= dns_name_len) return (mdn_buffer_overflow); strcpy(dns_name + len, "."); len++; } if (len + strlen(zld) >= dns_name_len) return (mdn_buffer_overflow); (void)strcat(dns_name, zld); } return (mdn_success); }
idn_result_t idn_res_decodename2(idn_resconf_t ctx, idn_action_t actions, const char *from, char *to, size_t tolen, const char *auxencoding) { #ifdef WITHOUT_ICONV return idn_failure; #else /* WITHOUT_ICONV */ idn_result_t r; idn_converter_t aux_converter = NULL; unsigned long *buffer_ucs4 = NULL; char *buffer_utf8 = NULL; size_t buffer_length; assert(ctx != NULL && from != NULL && to != NULL); TRACE(("idn_res_decodename2(actions=%s, from=\"%s\", tolen=%d, " "auxencoding=\"%s\")\n", idn__res_actionstostring(actions), idn__debug_xstring(from, 50), (int)tolen, (auxencoding != NULL) ? auxencoding : "<null>")); if (!initialized) idn_res_initialize(); if (!enabled || actions == 0) { r = copy_verbatim(from, to, tolen); goto ret; } else if (tolen <= 0) { r = idn_buffer_overflow; goto ret; } if (auxencoding == NULL || strcmp(auxencoding, IDN_UTF8_ENCODING_NAME) == 0 || strcmp(auxencoding, "UTF-8") == 0) { return idn_res_decodename(ctx, actions, from, to, tolen); } /* * Convert `from' to UCS4. */ r = idn_resconf_setauxidnconvertername(ctx, auxencoding, IDN_CONVERTER_DELAYEDOPEN); if (r != idn_success) { goto ret; } aux_converter = idn_resconf_getauxidnconverter(ctx); if (aux_converter == NULL) { r = idn_failure; goto ret; } buffer_length = tolen * 2; for (;;) { void *new_buffer; new_buffer = realloc(buffer_ucs4, sizeof(*buffer_ucs4) * buffer_length); if (new_buffer == NULL) { r = idn_nomemory; goto ret; } buffer_ucs4 = (unsigned long *)new_buffer; r = idn_converter_convtoucs4(aux_converter, from, buffer_ucs4, buffer_length); if (r == idn_success) break; else if (r != idn_buffer_overflow) goto ret; buffer_length *= 2; } if (*buffer_ucs4 == '\0') { if (tolen <= 0) { r = idn_buffer_overflow; goto ret; } *to = '\0'; r = idn_success; goto ret; } /* * Convert `buffer_ucs4' to UTF-8. */ buffer_length = tolen * 2; for (;;) { void *new_buffer; new_buffer = realloc(buffer_utf8, sizeof(*buffer_utf8) * buffer_length); if (new_buffer == NULL) { r = idn_nomemory; goto ret; } buffer_utf8 = (char *)new_buffer; r = idn_ucs4_ucs4toutf8(buffer_ucs4, buffer_utf8, buffer_length); if (r == idn_success) break; else if (r != idn_buffer_overflow) goto ret; buffer_length *= 2; } if (*buffer_utf8 == '\0') { if (tolen <= 0) { r = idn_buffer_overflow; goto ret; } *to = '\0'; r = idn_success; goto ret; } r = idn_res_decodename(ctx, actions, buffer_utf8, to, tolen); ret: if (r == idn_success) { TRACE(("idn_res_decodename2(): success (to=\"%s\")\n", idn__debug_xstring(to, 50))); } else { TRACE(("idn_res_decodename2(): %s\n", idn_result_tostring(r))); } free(buffer_ucs4); free(buffer_utf8); if (aux_converter != NULL) idn_converter_destroy(aux_converter); return (r); #endif /* WITHOUT_ICONV */ }
idn_result_t idn_res_decodename(idn_resconf_t ctx, idn_action_t actions, const char *from, char *to, size_t tolen) { idn_converter_t local_converter = NULL; idn_converter_t idn_converter = NULL; idn_delimitermap_t delimiter_mapper; idn_result_t r; labellist_t labels = NULL, l; unsigned long *buffer = NULL; unsigned long *saved_name = NULL; size_t buffer_length; int idn_is_ace; assert(ctx != NULL && from != NULL && to != NULL); TRACE(("idn_res_decodename(actions=%s, from=\"%s\", tolen=%d)\n", idn__res_actionstostring(actions), idn__debug_xstring(from, 50), (int)tolen)); if (actions & ~DECODE_MASK) { WARNING(("idn_res_decodename: invalid actions 0x%x\n", actions)); r = idn_invalid_action; goto ret; } if (!initialized) idn_res_initialize(); if (!enabled || actions == 0) { r = copy_verbatim(from, to, tolen); goto ret; } else if (tolen <= 0) { r = idn_buffer_overflow; goto ret; } if (actions & IDN_DECODE_QUERY) { #ifndef WITHOUT_ICONV actions |= (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | \ IDN_PROHCHECK | IDN_BIDICHECK | IDN_IDNCONV | \ IDN_RTCHECK | IDN_LOCALCONV); #else actions |= (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | \ IDN_PROHCHECK | IDN_BIDICHECK | IDN_IDNCONV | \ IDN_RTCHECK); #endif } /* * Convert `from' to UCS4. */ local_converter = idn_resconf_getlocalconverter(ctx); #ifndef WITHOUT_ICONV if (local_converter == NULL) { r = idn_invalid_name; goto ret; } #endif idn_converter = idn_resconf_getidnconverter(ctx); if (idn_converter != NULL && idn_converter_isasciicompatible(idn_converter)) idn_is_ace = 1; else idn_is_ace = 0; buffer_length = tolen * 2; TRACE(("res idndecode(name=\"%s\")\n", idn__debug_xstring(from, 50))); for (;;) { void *new_buffer; new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length); if (new_buffer == NULL) { r = idn_nomemory; goto ret; } buffer = (unsigned long *)new_buffer; if ((actions & IDN_IDNCONV) && idn_converter != NULL && !idn_is_ace) { r = idn_converter_convtoucs4(idn_converter, from, buffer, buffer_length); } else { r = idn_ucs4_utf8toucs4(from, buffer, buffer_length); } if (r == idn_success) break; else if (r != idn_buffer_overflow) goto ret; buffer_length *= 2; } if (*buffer == '\0') { if (tolen <= 0) { r = idn_buffer_overflow; goto ret; } *to = '\0'; r = idn_success; goto ret; } /* * Delimiter map. */ if (actions & IDN_DELIMMAP) { TRACE(("res delimitermap(name=\"%s\")\n", idn__debug_ucs4xstring(buffer, 50))); delimiter_mapper = idn_resconf_getdelimitermap(ctx); if (delimiter_mapper != NULL) { r = idn_delimitermap_map(delimiter_mapper, buffer, buffer, buffer_length); idn_delimitermap_destroy(delimiter_mapper); if (r != idn_success) goto ret; } TRACE(("res delimitermap(): success (name=\"%s\")\n", idn__debug_ucs4xstring(buffer, 50))); } /* * Split the name into a list of labels. */ r = labellist_create(buffer, &labels); if (r != idn_success) goto ret; /* * Perform conversions and tests. */ for (l = labellist_tail(labels); l != NULL; l = labellist_previous(l)) { free(saved_name); saved_name = NULL; if (!idn__util_ucs4isasciirange(labellist_getname(l))) { if (actions & IDN_MAP) { r = label_map(ctx, l); if (r != idn_success) goto ret; } if (actions & IDN_NORMALIZE) { r = label_normalize(ctx, l); if (r != idn_success) goto ret; } if (actions & IDN_PROHCHECK) { r = label_prohcheck(ctx, l); if (r == idn_prohibited) { labellist_undo(l); continue; } else if (r != idn_success) { goto ret; } } if (actions & IDN_UNASCHECK) { r = label_unascheck(ctx, l); if (r == idn_prohibited) { labellist_undo(l); continue; } else if (r != idn_success) { goto ret; } } if (actions & IDN_BIDICHECK) { r = label_bidicheck(ctx, l); if (r == idn_prohibited) { labellist_undo(l); continue; } else if (r != idn_success) { goto ret; } } } if ((actions & IDN_IDNCONV) && idn_is_ace) { saved_name = idn_ucs4_strdup(labellist_getname(l)); if (saved_name == NULL) { r = idn_nomemory; goto ret; } r = label_idndecode(ctx, l); if (r == idn_invalid_encoding) { labellist_undo(l); continue; } else if (r != idn_success) { goto ret; } } if ((actions & IDN_RTCHECK) && saved_name != NULL) { r = label_rtcheck(ctx, actions, l, saved_name); if (r == idn_invalid_encoding) { labellist_undo(l); continue; } else if (r != idn_success) { goto ret; } } #ifndef WITHOUT_ICONV if (actions & IDN_LOCALCONV) { r = label_localdecodecheck(ctx, l); if (r != idn_success) goto ret; } #endif } /* * Concat a list of labels to a name. */ for (;;) { void *new_buffer; new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length); if (new_buffer == NULL) { r = idn_nomemory; goto ret; } buffer = (unsigned long *)new_buffer; r = labellist_getnamelist(labels, buffer, buffer_length); if (r == idn_success) break; else if (r != idn_buffer_overflow) goto ret; buffer_length *= 2; } if (actions & IDN_LOCALCONV) { r = idn_converter_convfromucs4(local_converter, buffer, to, tolen); } else { r = idn_ucs4_ucs4toutf8(buffer, to, tolen); } ret: if (r == idn_success) { TRACE(("idn_res_decodename(): success (to=\"%s\")\n", idn__debug_xstring(to, 50))); } else { TRACE(("idn_res_decodename(): %s\n", idn_result_tostring(r))); } free(saved_name); free(buffer); if (local_converter != NULL) idn_converter_destroy(local_converter); if (idn_converter != NULL) idn_converter_destroy(idn_converter); if (labels != NULL) labellist_destroy(labels); return (r); }