uschar * string_localpart_utf8_to_alabel(const uschar * utf8, uschar ** err) { size_t ucs4_len; punycode_uint * p; size_t p_len; uschar * res; int rc; if (!string_is_utf8(utf8)) return string_copy(utf8); p = (punycode_uint *) stringprep_utf8_to_ucs4(CCS utf8, -1, &ucs4_len); p_len = ucs4_len*4; /* this multiplier is pure guesswork */ res = store_get(p_len+5); res[0] = 'x'; res[1] = 'n'; res[2] = res[3] = '-'; if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, CS res+4)) != PUNYCODE_SUCCESS) { DEBUG(D_expand) debug_printf("l_u2a: bad '%s'\n", punycode_strerror(rc)); free(p); if (err) *err = US punycode_strerror(rc); return NULL; } p_len += 4; free(p); res[p_len] = '\0'; return res; }
static VALUE decode(VALUE self, VALUE str) { int rc; punycode_uint *ustr; size_t len; char *buf = NULL; VALUE retv; str = rb_check_convert_type(str, T_STRING, "String", "to_s"); len = RSTRING_LEN(str); ustr = malloc(len * sizeof(punycode_uint)); if (ustr == NULL) { rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", (uint32_t)len); return Qnil; } rc = punycode_decode(RSTRING_LEN(str), RSTRING_PTR(str), &len, ustr, NULL); if (rc != PUNYCODE_SUCCESS) { xfree(ustr); rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc); return Qnil; } buf = stringprep_ucs4_to_utf8(ustr, len, NULL, &len); retv = rb_enc_str_new(buf, len, rb_utf8_encoding()); xfree(ustr); xfree(buf); return retv; }
uschar * string_localpart_alabel_to_utf8(const uschar * alabel, uschar ** err) { size_t p_len = Ustrlen(alabel); punycode_uint * p; uschar * s; uschar * res; int rc; if (alabel[0] != 'x' || alabel[1] != 'n' || alabel[2] != '-' || alabel[3] != '-') { if (err) *err = US"bad alabel prefix"; return NULL; } p_len -= 4; p = (punycode_uint *) store_get((p_len+1) * sizeof(*p)); if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUCCESS) { if (err) *err = US punycode_strerror(rc); return NULL; } s = US stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len); res = string_copyn(s, p_len); free(s); return res; }
static VALUE encode(VALUE self, VALUE str) { int rc; punycode_uint *ustr; size_t len; size_t buflen = 0x100; char *buf = NULL; VALUE retv; str = rb_check_convert_type(str, T_STRING, "String", "to_s"); ustr = stringprep_utf8_to_ucs4(RSTRING_PTR(str), RSTRING_LEN(str), &len); while (1) { buf = realloc(buf, buflen); if (buf == NULL) { xfree(ustr); rb_raise(rb_eNoMemError, "cannot allocate memory (%d bytes)", (uint32_t)buflen); return Qnil; } rc = punycode_encode(len, ustr, NULL, &buflen, buf); if (rc == PUNYCODE_SUCCESS) { break; } else if (rc == PUNYCODE_BIG_OUTPUT) { buflen += 0x100; } else { xfree(ustr); xfree(buf); rb_raise(ePunycodeError, "%s (%d)", punycode_strerror(rc), rc); return Qnil; } } retv = rb_str_new(buf, buflen); xfree(ustr); xfree(buf); return retv; }
static uschar * string_localpart_alabel_to_utf8_(const uschar * alabel, uschar ** err) { size_t p_len; punycode_uint * p; int rc; uschar * s, * res; DEBUG(D_expand) debug_printf("l_a2u: '%s'\n", alabel); alabel += 4; p_len = Ustrlen(alabel); p = (punycode_uint *) store_get((p_len+1) * sizeof(*p)); if ((rc = punycode_decode(p_len, CCS alabel, &p_len, p, NULL)) != PUNYCODE_SUCCESS) { if (err) *err = US punycode_strerror(rc); return NULL; } s = US stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len); res = string_copyn(s, p_len); free(s); return res; }
void doit (void) { const char *p; /* Test success. */ p = idna_strerror (0); if (strcmp (p, SUCCESS) != 0) fail ("idna_strerror (0) failed: %s\n", p); if (debug) printf ("idna_strerror (0) OK\n"); p = pr29_strerror (0); if (strcmp (p, SUCCESS) != 0) fail ("pr29_strerror (0) failed: %s\n", p); if (debug) printf ("pr29_strerror (0) OK\n"); p = punycode_strerror (0); if (strcmp (p, SUCCESS) != 0) fail ("punycode_strerror (0) failed: %s\n", p); if (debug) printf ("punycode_strerror (0) OK\n"); p = stringprep_strerror (0); if (strcmp (p, SUCCESS) != 0) fail ("stringprep_strerror (0) failed: %s\n", p); if (debug) printf ("stringprep_strerror (0) OK\n"); p = tld_strerror (0); if (strcmp (p, SUCCESS) != 0) fail ("tld_strerror (0) failed: %s\n", p); if (debug) printf ("tld_strerror (0) OK\n"); /* Test unknown error. */ p = idna_strerror (42); if (strcmp (p, UNKNOWN) != 0) fail ("idna_strerror (42) failed: %s\n", p); if (debug) printf ("idna_strerror (42) OK\n"); p = pr29_strerror (42); if (strcmp (p, UNKNOWN) != 0) fail ("pr29_strerror (42) failed: %s\n", p); if (debug) printf ("pr29_strerror (42) OK\n"); p = punycode_strerror (42); if (strcmp (p, UNKNOWN) != 0) fail ("punycode_strerror (42) failed: %s\n", p); if (debug) printf ("punycode_strerror (42) OK\n"); p = stringprep_strerror (42); if (strcmp (p, UNKNOWN) != 0) fail ("stringprep_strerror (42) failed: %s\n", p); if (debug) printf ("stringprep_strerror (42) OK\n"); p = tld_strerror (42); if (strcmp (p, UNKNOWN) != 0) fail ("tld_strerror (42) failed: %s\n", p); if (debug) printf ("tld_strerror (42) OK\n"); /* Iterate through all error codes. */ { size_t i; const char *last_p = NULL; for (i = 0;; i++) { p = idna_strerror (i); if (p == last_p) { if (i == 11) { i = 200; continue; } break; } if (debug) printf ("idna %ld: %s\n", i, p); last_p = p; } } { size_t i; const char *last_p = NULL; for (i = 0;; i++) { p = pr29_strerror (i); if (p == last_p) break; if (debug) printf ("pr29 %ld: %s\n", i, p); last_p = p; } } { size_t i; const char *last_p = NULL; for (i = 0;; i++) { p = punycode_strerror (i); if (p == last_p) break; if (debug) printf ("punycode %ld: %s\n", i, p); last_p = p; } } { size_t i; const char *last_p = NULL; for (i = 0;; i++) { p = stringprep_strerror (i); if (p == last_p) { if (i == 7) { i = 99; continue; } else if (i == 105) { i = 199; continue; } break; } if (debug) printf ("stringprep %ld: %s\n", i, p); last_p = p; } } { size_t i; const char *last_p = NULL; for (i = 0;; i++) { p = tld_strerror (i); if (p == last_p) break; if (debug) printf ("tld %ld: %s\n", i, p); last_p = p; } } }