예제 #1
0
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);
}
예제 #2
0
파일: idna.cpp 프로젝트: xun-wang/coreclr
/*
Function:
ToUnicode

Used by System.Globalization.IdnMapping.GetUnicodeCore to convert an ASCII name
to Unicode

Return values:
0: internal error during conversion.
>0: the length of the converted string (not including the null terminator).
*/
extern "C" int32_t GlobalizationNative_ToUnicode(
    int32_t flags, const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength)
{
    UErrorCode err = U_ZERO_ERROR;
    UIDNAInfo info = UIDNA_INFO_INITIALIZER;

    UIDNA* pIdna = uidna_openUTS46(GetOptions(flags), &err);

    int32_t unicodeStrLen = uidna_nameToUnicode(pIdna, lpSrc, cwSrcLength, lpDst, cwDstLength, &info, &err);

    uidna_close(pIdna);

    return ((U_SUCCESS(err) || (err == U_BUFFER_OVERFLOW_ERROR)) && (info.errors == 0)) ? unicodeStrLen : 0;
}
예제 #3
0
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;
}
예제 #4
0
파일: idn.c 프로젝트: Furgas/php-src
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);
}
예제 #5
0
파일: idn.c 프로젝트: AllenJB/php-src
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS,
		const zend_string *domain, uint32_t option, int mode)
{
	UChar* ustring = NULL;
	int ustring_len = 0;
	UErrorCode status;
	zend_string *u8str;

	/* convert the string to UTF-16. */
	status = U_ZERO_ERROR;
	intl_convert_utf8_to_utf16(&ustring, &ustring_len, ZSTR_VAL(domain), ZSTR_LEN(domain), &status);

	if (U_FAILURE(status)) {
		intl_error_set_code(NULL, status);

		/* Set error messages. */
		intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 );
		if (ustring) {
			efree(ustring);
		}
		RETURN_FALSE;
	} else {
		UChar       converted[MAXPATHLEN];
		int32_t     converted_ret_len;

		status = U_ZERO_ERROR;

#if U_ICU_VERSION_MAJOR_NUM >= 55
		UIDNAInfo info = UIDNA_INFO_INITIALIZER;
		UIDNA *idna = uidna_openUTS46((int32_t)option, &status);

		if (U_FAILURE(status)) {
			intl_error_set( NULL, status, "idn_to_ascii: failed to create an UIDNA instance", 0 );
			RETURN_FALSE;
		}

		if (mode == INTL_IDN_TO_ASCII) {
			converted_ret_len = uidna_nameToASCII(idna, ustring, ustring_len, converted, MAXPATHLEN, &info, &status);
		} else {
			converted_ret_len = uidna_nameToUnicode(idna, ustring, ustring_len, converted, MAXPATHLEN, &info, &status);
		}
		uidna_close(idna);
#else
		UParseError parse_error;
		if (mode == INTL_IDN_TO_ASCII) {
			converted_ret_len = uidna_IDNToASCII(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status);
		} else {
			converted_ret_len = uidna_IDNToUnicode(ustring, ustring_len, converted, MAXPATHLEN, (int32_t)option, &parse_error, &status);
		}
#endif
		efree(ustring);

		if (U_FAILURE(status)) {
			intl_error_set( NULL, status, "idn_to_ascii: cannot convert to ASCII", 0 );
			RETURN_FALSE;
		}

		status = U_ZERO_ERROR;
		u8str = intl_convert_utf16_to_utf8(converted, converted_ret_len, &status);

		if (!u8str) {
			/* Set global error code. */
			intl_error_set_code(NULL, status);

			/* Set error messages. */
			intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 );
			RETURN_FALSE;
		}
	}

	/* return the allocated string, not a duplicate */
	RETVAL_NEW_STR(u8str);
}
예제 #6
0
파일: psl.c 프로젝트: jcajka/libpsl
/**
 * psl_load_fp:
 * @fp: FILE pointer
 *
 * This function loads the public suffixes from a FILE pointer.
 * To free the allocated resources, call psl_free().
 *
 * The suffixes are expected to be lowercase UTF-8 encoded if they are international.
 *
 * Returns: Pointer to a PSL context or %NULL on failure.
 *
 * Since: 0.1
 */
psl_ctx_t *psl_load_fp(FILE *fp)
{
	psl_ctx_t *psl;
	_psl_entry_t suffix, *suffixp;
	char buf[256], *linep, *p;
#ifdef WITH_LIBICU
	UIDNA *idna;
	UErrorCode status = 0;
#endif

	if (!fp)
		return NULL;

	if (!(psl = calloc(1, sizeof(psl_ctx_t))))
		return NULL;

#ifdef WITH_LIBICU
	idna = uidna_openUTS46(UIDNA_USE_STD3_RULES, &status);
#endif

	/*
	 *  as of 02.11.2012, the list at http://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions.
	 *  as of 19.02.2014, the list at http://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions.
	 */
	psl->suffixes = _vector_alloc(8*1024, _suffix_compare);
	psl->suffix_exceptions = _vector_alloc(64, _suffix_compare);

	while ((linep = fgets(buf, sizeof(buf), fp))) {
		while (isspace(*linep)) linep++; /* ignore leading whitespace */
		if (!*linep) continue; /* skip empty lines */

		if (*linep == '/' && linep[1] == '/')
			continue; /* skip comments */

		/* parse suffix rule */
		for (p = linep; *linep && !isspace(*linep);) linep++;
		*linep = 0;

		if (*p == '!') {
			/* add to exceptions */
			if (_suffix_init(&suffix, p + 1, linep - p - 1) == 0) {
				suffixp = _vector_get(psl->suffix_exceptions, _vector_add(psl->suffix_exceptions, &suffix));
				suffixp->label = suffixp->label_buf; /* set label to changed address */
#ifdef WITH_LIBICU
				_add_punycode_if_needed(idna, psl->suffix_exceptions, suffixp);
#elif defined(WITH_LIBIDN2) || defined(WITH_LIBIDN)
				_add_punycode_if_needed(psl->suffix_exceptions, suffixp);
#endif
			}
		} else {
			/* add to suffixes */
			if (_suffix_init(&suffix, p, linep - p) == 0) {
				suffixp = _vector_get(psl->suffixes, _vector_add(psl->suffixes, &suffix));
				suffixp->label = suffixp->label_buf; /* set label to changed address */
#ifdef WITH_LIBICU
				_add_punycode_if_needed(idna, psl->suffixes, suffixp);
#elif defined(WITH_LIBIDN2) || defined(WITH_LIBIDN)
				_add_punycode_if_needed(psl->suffixes, suffixp);
#endif
			}
		}
	}

	_vector_sort(psl->suffix_exceptions);
	_vector_sort(psl->suffixes);

#ifdef WITH_LIBICU
	if (idna)
		uidna_close(idna);
#endif

	return psl;
}