idn_result_t mdn_decodename(int actions, const char *from, char *to, size_t tolen) { idn_result_t r; assert(from != NULL && to != NULL); TRACE(("idn_decodename(actions=%s, from=\"%s\", tolen=%d)\n", idn__res_actionstostring(actions), idn__debug_xstring(from, 50), (int)tolen)); if (!initialized && ((r = idn_nameinit(1)) != idn_success)) return (r); return (idn_res_decodename(default_conf, actions, from, to, tolen)); }
static idn_result_t convert_line (idnconv_strbuf_t * from, idnconv_strbuf_t * to, idn_resconf_t conf, idn_action_t actions, int flags) { idn_result_t r = idn_success; char *from_str = strbuf_get (from); for (;;) { char *to_str = strbuf_get (to); size_t to_size = strbuf_size (to); switch (flags & (FLAG_REVERSE | FLAG_SELECTIVE)) { case 0: r = idn_res_encodename (conf, actions, from_str, to_str, to_size); break; case FLAG_REVERSE: r = idn_res_decodename (conf, actions, from_str, to_str, to_size); break; case FLAG_SELECTIVE: r = selective_encode (conf, actions, from_str, to_str, to_size); break; case FLAG_REVERSE | FLAG_SELECTIVE: r = selective_decode (conf, actions, from_str, to_str, to_size); break; } if (r == idn_buffer_overflow) { /* * Conversion is not successful because * the size of the target buffer is not enough. * Double the size and retry. */ if (strbuf_double (to) == NULL) { /* oops. allocation failed. */ return (idn_nomemory); } } else { break; } } return (r); }
BOOL idnConvRsp(idn_resconf_t ctx, const char FAR *from, char FAR *to, size_t tolen) { idnLogReset(); idnLogPrintf(idn_log_level_trace, "idnConvRsp(from=%-.100s)\n", from); if (ctx == NULL) { if (strlen(from) >= tolen) return FALSE; strcpy(to, from); return TRUE; } else if (idn_res_decodename(ctx, IDN_DECODE_APP, from, to, tolen) == idn_success) { return TRUE; } else { return FALSE; } }
idn_result_t idn_decodename(idn_action_t actions, const char *from, char *to, size_t tolen) { idn_result_t r; assert(from != NULL && to != NULL); TRACE(("idn_decodename(actions=%s, from=\"%s\", tolen=%d)\n", idn__res_actionstostring(actions), idn__debug_xstring(from, 50), (int)tolen)); if (!initialized && ((r = idn_nameinit(0)) != idn_success)) goto ret; r = idn_res_decodename(default_conf, actions, from, to, tolen); ret: if (r == idn_success) { TRACE(("idn_decodename(): success (to=\"%s\")\n", idn__debug_xstring(to, 50))); } else { TRACE(("idn_decodename(): %s\n", idn_result_tostring(r))); } return (r); }
idn_result_t selective_decode(idn_resconf_t conf, idn_action_t actions, char *from, char *to, int tolen) { char *domain_name; char *ignored_chunk; char save; int len; idn_result_t r; /* * While `*from' points to a character in a string which may be * a domain name, `domain_name' refers to the beginning of the * domain name. */ domain_name = NULL; /* * We ignore chunks matching to the regular expression: * [\-\.][0-9A-Za-z\-\.]* * * While `*from' points to a character in such a chunk, * `ignored_chunk' refers to the beginning of the chunk. */ ignored_chunk = NULL; for (;;) { if (*from == '-') { /* * We don't recognize `.-' as a part of domain name. */ if (domain_name != NULL) { if (*(from - 1) == '.') { ignored_chunk = domain_name; domain_name = NULL; } } else if (ignored_chunk == NULL) { ignored_chunk = from; } } else if (*from == '.') { /* * We don't recognize `-.' nor `..' as a part of * domain name. */ if (domain_name != NULL) { if (*(from - 1) == '-' || *(from - 1) == '.') { ignored_chunk = domain_name; domain_name = NULL; } } else if (ignored_chunk == NULL) { ignored_chunk = from; } } else if (('a' <= *from && *from <= 'z') || ('A' <= *from && *from <= 'Z') || ('0' <= *from && *from <= '9')) { if (ignored_chunk == NULL && domain_name == NULL) domain_name = from; } else { if (ignored_chunk != NULL) { /* * `from' reaches the end of the ignored chunk. * Copy the chunk to `to'. */ len = from - ignored_chunk; if (tolen < len) return (idn_buffer_overflow); (void)memcpy(to, ignored_chunk, len); to += len; tolen -= len; } else if (domain_name != NULL) { /* * `from' reaches the end of the domain name. * Decode the domain name, and copy the result * to `to'. */ save = *from; *from = '\0'; r = idn_res_decodename(conf, actions, domain_name, to, tolen); *from = save; if (r == idn_success) { len = strlen(to); } else if (r == idn_invalid_encoding) { len = from - domain_name; if (tolen < len) return (idn_buffer_overflow); (void)memcpy(to, domain_name, len); } else { return (r); } to += len; tolen -= len; } /* * Copy a character `*from' to `to'. */ if (tolen < 1) return (idn_buffer_overflow); *to = *from; to++; tolen--; domain_name = NULL; ignored_chunk = NULL; if (*from == '\0') break; } from++; } return (idn_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 */ }