Пример #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
/*
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
// Use LocalXyzPointer types that are not covered elsewhere in the intltest suite.
void LocalPointerTest::TestLocalXyzPointer() {
    IcuTestErrorCode errorCode(*this, "TestLocalXyzPointer");

    static const char *const encoding="ISO-8859-1";
    LocalUConverterSelectorPointer sel(
        ucnvsel_open(&encoding, 1, NULL, UCNV_ROUNDTRIP_SET, errorCode));
    if(errorCode.logIfFailureAndReset("ucnvsel_open()")) {
        return;
    }
    if(sel.isNull()) {
        errln("LocalUConverterSelectorPointer failure");
        return;
    }

#if !UCONFIG_NO_FORMATTING
    LocalUCalendarPointer cal(ucal_open(NULL, 0, "root", UCAL_GREGORIAN, errorCode));
    if(errorCode.logDataIfFailureAndReset("ucal_open()")) {
        return;
    }
    if(cal.isNull()) {
        errln("LocalUCalendarPointer failure");
        return;
    }

    LocalUDateTimePatternGeneratorPointer patgen(udatpg_open("root", errorCode));
    if(errorCode.logDataIfFailureAndReset("udatpg_open()")) {
        return;
    }
    if(patgen.isNull()) {
        errln("LocalUDateTimePatternGeneratorPointer failure");
        return;
    }

    LocalULocaleDisplayNamesPointer ldn(uldn_open("de-CH", ULDN_STANDARD_NAMES, errorCode));
    if(errorCode.logIfFailureAndReset("uldn_open()")) {
        return;
    }
    if(ldn.isNull()) {
        errln("LocalULocaleDisplayNamesPointer failure");
        return;
    }

    UnicodeString hello=UNICODE_STRING_SIMPLE("Hello {0}!");
    LocalUMessageFormatPointer msg(
        umsg_open(hello.getBuffer(), hello.length(), "root", NULL, errorCode));
    if(errorCode.logIfFailureAndReset("umsg_open()")) {
        return;
    }
    if(msg.isNull()) {
        errln("LocalUMessageFormatPointer failure");
        return;
    }
#endif  /* UCONFIG_NO_FORMATTING  */

#if !UCONFIG_NO_NORMALIZATION
    const UNormalizer2 *nfc=unorm2_getNFCInstance(errorCode);
    UnicodeSet emptySet;
    LocalUNormalizer2Pointer fn2(unorm2_openFiltered(nfc, emptySet.toUSet(), errorCode));
    if(errorCode.logIfFailureAndReset("unorm2_openFiltered()")) {
        return;
    }
    if(fn2.isNull()) {
        errln("LocalUNormalizer2Pointer failure");
        return;
    }
#endif /* !UCONFIG_NO_NORMALIZATION */

#if !UCONFIG_NO_IDNA
    LocalUIDNAPointer idna(uidna_openUTS46(0, errorCode));
    if(errorCode.logIfFailureAndReset("uidna_openUTS46()")) {
        return;
    }
    if(idna.isNull()) {
        errln("LocalUIDNAPointer failure");
        return;
    }
#endif  /* !UCONFIG_NO_IDNA */

#if !UCONFIG_NO_REGULAR_EXPRESSIONS
    UnicodeString pattern=UNICODE_STRING_SIMPLE("abc|xy+z");
    LocalURegularExpressionPointer regex(
        uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, errorCode));
    if(errorCode.logIfFailureAndReset("uregex_open()")) {
        return;
    }
    if(regex.isNull()) {
        errln("LocalURegularExpressionPointer failure");
        return;
    }
#endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */

#if !UCONFIG_NO_TRANSLITERATION
    UnicodeString id=UNICODE_STRING_SIMPLE("Grek-Latn");
    LocalUTransliteratorPointer trans(
        utrans_openU(id.getBuffer(), id.length(), UTRANS_FORWARD, NULL, 0, NULL, errorCode));
    if(errorCode.logIfFailureAndReset("utrans_open()")) {
        return;
    }
    if(trans.isNull()) {
        errln("LocalUTransliteratorPointer failure");
        return;
    }
#endif /* !UCONFIG_NO_TRANSLITERATION */

    // destructors
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
/**
 * 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;
}