static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) { zend_string *domain; zend_long option = 0, variant = INTL_IDN_VARIANT_UTS46; zval *idna_info = NULL; intl_error_reset(NULL); if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|llz", &domain, &option, &variant, &idna_info) == FAILURE) { RETURN_NULL(); /* don't set FALSE because that's not the way it was before... */ } if (variant != INTL_IDN_VARIANT_UTS46) { php_intl_bad_args("invalid variant, must be INTL_IDNA_VARIANT_UTS46"); RETURN_FALSE; } if (ZSTR_LEN(domain) < 1) { php_intl_bad_args("empty domain name"); RETURN_FALSE; } if (ZSTR_LEN(domain) > INT32_MAX - 1) { php_intl_bad_args("domain name too large"); RETURN_FALSE; } /* don't check options; it wasn't checked before */ if (idna_info != NULL) { idna_info = zend_try_array_init(idna_info); if (!idna_info) { return; } } php_intl_idn_to_46(INTERNAL_FUNCTION_PARAM_PASSTHRU, domain, (uint32_t)option, mode, idna_info); }
static Variant php_intl_idn_to(const String& domain, int64_t options, IdnVariant idn_variant, VRefParam idna_info, int mode) { UChar* ustring = NULL; int ustring_len = 0; UErrorCode status; char *converted_utf8 = NULL; int32_t converted_utf8_len; UChar* converted = NULL; int32_t converted_ret_len; if (idn_variant != INTL_IDN_VARIANT_2003) { #ifdef HAVE_46_API if (idn_variant == INTL_IDN_VARIANT_UTS46) { return php_intl_idn_to_46(domain, options, idn_variant, ref(idna_info), mode); } #endif return false; } // Convert the string to UTF-16 status = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&ustring, &ustring_len, (char*)domain.data(), domain.size(), &status); if (U_FAILURE(status)) { free(ustring); return false; } // Call the appropriate IDN function int converted_len = (ustring_len > 1) ? ustring_len : 1; for (;;) { UParseError parse_error; status = U_ZERO_ERROR; converted = (UChar*)malloc(sizeof(UChar)*converted_len); // If the malloc failed, bail out if (!converted) { free(ustring); return false; } if (mode == INTL_IDN_TO_ASCII) { converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, converted_len, (int32_t)options, &parse_error, &status); } else { converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, converted_len, (int32_t)options, &parse_error, &status); } if (status != U_BUFFER_OVERFLOW_ERROR) break; // If we have a buffer overflow error, try again with a larger buffer free(converted); converted = NULL; converted_len = converted_len * 2; } free(ustring); if (U_FAILURE(status)) { free(converted); return false; } // Convert the string back to UTF-8 status = U_ZERO_ERROR; intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status); free(converted); if (U_FAILURE(status)) { free(converted_utf8); return false; } // Return the string return String(converted_utf8, converted_utf8_len, AttachString); }
static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) { char *domain; size_t domain_len; zend_long option = 0, variant = INTL_IDN_VARIANT_2003; zval *idna_info = NULL; intl_error_reset(NULL); if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|llz/", &domain, &domain_len, &option, &variant, &idna_info) == FAILURE) { php_intl_bad_args("bad arguments", mode); RETURN_NULL(); /* don't set FALSE because that's not the way it was before... */ } #ifdef HAVE_46_API if (variant != INTL_IDN_VARIANT_2003 && variant != INTL_IDN_VARIANT_UTS46) { php_intl_bad_args("invalid variant, must be one of {" "INTL_IDNA_VARIANT_2003, INTL_IDNA_VARIANT_UTS46}", mode); RETURN_FALSE; } #else if (variant != INTL_IDN_VARIANT_2003) { php_intl_bad_args("invalid variant, PHP was compiled against " "an old version of ICU and only supports INTL_IDN_VARIANT_2003", mode); RETURN_FALSE; } #endif if (domain_len < 1) { php_intl_bad_args("empty domain name", mode); RETURN_FALSE; } if (domain_len > INT32_MAX - 1) { php_intl_bad_args("domain name too large", mode); RETURN_FALSE; } /* don't check options; it wasn't checked before */ if (idna_info != NULL) { if (variant == INTL_IDN_VARIANT_2003) { php_error_docref0(NULL, E_NOTICE, "4 arguments were provided, but INTL_IDNA_VARIANT_2003 only " "takes 3 - extra argument ignored"); } else { zval_dtor(idna_info); array_init(idna_info); } } if (variant == INTL_IDN_VARIANT_2003) { php_intl_idn_to(INTERNAL_FUNCTION_PARAM_PASSTHRU, domain, (int32_t)domain_len, (uint32_t)option, mode); } #ifdef HAVE_46_API else { php_intl_idn_to_46(INTERNAL_FUNCTION_PARAM_PASSTHRU, domain, (int32_t)domain_len, (uint32_t)option, mode, idna_info); } #endif }