static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, const zend_string *domain, uint32_t option, int mode, zval *idna_info) { UErrorCode status = U_ZERO_ERROR; UIDNA *uts46; int32_t len; zend_string *buffer; UIDNAInfo info = UIDNA_INFO_INITIALIZER; uts46 = uidna_openUTS46(option, &status); if (php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE) { RETURN_FALSE; } if (mode == INTL_IDN_TO_ASCII) { const int32_t buffer_capac = 255; buffer = zend_string_alloc(buffer_capac, 0); len = uidna_nameToASCII_UTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), ZSTR_VAL(buffer), buffer_capac, &info, &status); if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) { uidna_close(uts46); zend_string_efree(buffer); RETURN_FALSE; } } else { const int32_t buffer_capac = 252*4; buffer = zend_string_alloc(buffer_capac, 0); len = uidna_nameToUnicodeUTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), ZSTR_VAL(buffer), buffer_capac, &info, &status); if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) { uidna_close(uts46); zend_string_efree(buffer); RETURN_FALSE; } } ZSTR_VAL(buffer)[len] = '\0'; ZSTR_LEN(buffer) = len; if (info.errors == 0) { RETVAL_STR_COPY(buffer); } else { RETVAL_FALSE; } if (idna_info) { add_assoc_str_ex(idna_info, "result", sizeof("result")-1, zend_string_copy(buffer)); add_assoc_bool_ex(idna_info, "isTransitionalDifferent", sizeof("isTransitionalDifferent")-1, info.isTransitionalDifferent); add_assoc_long_ex(idna_info, "errors", sizeof("errors")-1, (zend_long)info.errors); } zend_string_release(buffer); uidna_close(uts46); }
static Variant php_intl_idn_to_46(const String& domain, int64_t options, IdnVariant idn_variant, VRefParam idna_info, int mode) { int32_t converted_capacity; char *converted = NULL; int32_t converted_len; UIDNA *uts46; UIDNAInfo info = UIDNA_INFO_INITIALIZER; UErrorCode status = U_ZERO_ERROR; // Get UIDNA instance which implements UTS #46. uts46 = uidna_openUTS46(options, &status); SCOPE_EXIT { uidna_close(uts46); }; if (U_FAILURE(status)) return false; // Call the appropriate IDN function status = U_ZERO_ERROR; converted_capacity = 255; // no domain name may exceed this String result(converted_capacity, ReserveString); // reserves converted_capacity+1 characters. converted = result.bufferSlice().ptr; if (mode == INTL_IDN_TO_ASCII) { converted_len = uidna_nameToASCII_UTF8(uts46, (char*)domain.data(), domain.size(), converted, converted_capacity, &info, &status); } else { converted_len = uidna_nameToUnicodeUTF8(uts46, (char*)domain.data(), domain.size(), converted, converted_capacity, &info, &status); } if (U_FAILURE(status) || converted_len > converted_capacity) return false; if (info.errors == 0) { result.setSize(converted_len); } else { result.setSize(0); } // Set up the array returned in idna_info. ArrayInit arr(3); arr.set(s_result, result); arr.set(s_isTransitionalDifferent, info.isTransitionalDifferent); arr.set(s_errors, (long)info.errors); // As in Zend, the previous value of idn_variant is overwritten, not modified. idna_info = arr.create(); if (info.errors == 0) { return result; } return false; }
static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, const char *domain, int32_t domain_len, uint32_t option, int mode, zval *idna_info) { UErrorCode status = U_ZERO_ERROR; UIDNA *uts46; int32_t len; int32_t buffer_capac = 255; /* no domain name may exceed this */ zend_string *buffer = zend_string_alloc(buffer_capac, 0); UIDNAInfo info = UIDNA_INFO_INITIALIZER; int buffer_used = 0; uts46 = uidna_openUTS46(option, &status); if (php_intl_idn_check_status(status, "failed to open UIDNA instance", mode) == FAILURE) { zend_string_free(buffer); RETURN_FALSE; } if (mode == INTL_IDN_TO_ASCII) { len = uidna_nameToASCII_UTF8(uts46, domain, domain_len, ZSTR_VAL(buffer), buffer_capac, &info, &status); } else { len = uidna_nameToUnicodeUTF8(uts46, domain, domain_len, ZSTR_VAL(buffer), buffer_capac, &info, &status); } if (php_intl_idn_check_status(status, "failed to convert name", mode) == FAILURE) { uidna_close(uts46); zend_string_free(buffer); RETURN_FALSE; } if (len >= 255) { php_error_docref(NULL, E_ERROR, "ICU returned an unexpected length"); } ZSTR_VAL(buffer)[len] = '\0'; ZSTR_LEN(buffer) = len; if (info.errors == 0) { RETVAL_STR(buffer); buffer_used = 1; } else { RETVAL_FALSE; } if (idna_info) { if (buffer_used) { /* used in return_value then */ zval_addref_p(return_value); add_assoc_zval_ex(idna_info, "result", sizeof("result")-1, return_value); } else { zval zv; ZVAL_NEW_STR(&zv, buffer); buffer_used = 1; add_assoc_zval_ex(idna_info, "result", sizeof("result")-1, &zv); } add_assoc_bool_ex(idna_info, "isTransitionalDifferent", sizeof("isTransitionalDifferent")-1, info.isTransitionalDifferent); add_assoc_long_ex(idna_info, "errors", sizeof("errors")-1, (zend_long)info.errors); } if (!buffer_used) { zend_string_free(buffer); } uidna_close(uts46); }