예제 #1
0
U_CAPI int32_t U_EXPORT2
uidna_compare(  const UChar *s1, int32_t length1,
                const UChar *s2, int32_t length2,
                int32_t options,
                UErrorCode* status){

    if(status == NULL || U_FAILURE(*status)){
        return -1;
    }

    UChar b1Stack[MAX_IDN_BUFFER_SIZE], b2Stack[MAX_IDN_BUFFER_SIZE];
    UChar *b1 = b1Stack, *b2 = b2Stack;
    int32_t b1Len, b2Len, b1Capacity = MAX_IDN_BUFFER_SIZE, b2Capacity = MAX_IDN_BUFFER_SIZE;
    int32_t result=-1;

    UParseError parseError;

    b1Len = uidna_IDNToASCII(s1, length1, b1, b1Capacity, options, &parseError, status);
    if(*status == U_BUFFER_OVERFLOW_ERROR){
        // redo processing of string
        b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR);
        if(b1==NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        *status = U_ZERO_ERROR; // reset error

        b1Len = uidna_IDNToASCII(s1,length1,b1,b1Len, options, &parseError, status);

    }

    b2Len = uidna_IDNToASCII(s2,length2, b2,b2Capacity, options, &parseError, status);
    if(*status == U_BUFFER_OVERFLOW_ERROR){
        // redo processing of string
        b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR);
        if(b2==NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto CLEANUP;
        }

        *status = U_ZERO_ERROR; // reset error

        b2Len = uidna_IDNToASCII(s2, length2, b2, b2Len, options, &parseError, status);

    }
    // when toASCII is applied all label separators are replaced with FULL_STOP
    result = compareCaseInsensitiveASCII(b1,b1Len,b2,b2Len);

CLEANUP:
    if(b1 != b1Stack){
        uprv_free(b1);
    }

    if(b2 != b2Stack){
        uprv_free(b2);
    }

    return result;
}
예제 #2
0
파일: idnaconf.cpp 프로젝트: winlibs/icu4c
void IdnaConfTest::Call(){
    if (type == -1 || option == -1 || passfail == -1 || namebase.isBogus() || namezone.isBogus()){
        errln("Incomplete record");
    } else {
        UErrorCode status = U_ZERO_ERROR;
        UChar result[200] = {0,};   // simple life
        const UChar *p = namebase.getTerminatedBuffer();
        const int p_len = namebase.length();

        if (type == 0 && option == 0){
            uidna_IDNToASCII(p, p_len, result, 200, UIDNA_USE_STD3_RULES, NULL, &status);
        } else if (type == 0 && option == 1){
            uidna_IDNToASCII(p, p_len, result, 200, UIDNA_ALLOW_UNASSIGNED, NULL, &status);
        } else if (type == 1 && option == 0){
            uidna_IDNToUnicode(p, p_len, result, 200, UIDNA_USE_STD3_RULES, NULL, &status);
        } else if (type == 1 && option == 1){
            uidna_IDNToUnicode(p, p_len, result, 200, UIDNA_ALLOW_UNASSIGNED, NULL, &status);
        }
        if (passfail == 0){
            if (U_FAILURE(status)){
                id.append(" should pass, but failed. - ");
                id.append(u_errorName(status));
                errcheckln(status, id);
            } else{
                if (namezone.compare(result, -1) == 0){
                    // expected
                    logln(UnicodeString("namebase: ") + prettify(namebase) + UnicodeString(" result: ") + prettify(result));
                } else {
                    id.append(" no error, but result is not as expected.");
                    errln(id);
                }
            }
        } else if (passfail == 1){
            if (U_FAILURE(status)){
                // expected
                // TODO: Uncomment this when U_IDNA_ZERO_LENGTH_LABEL_ERROR is added to u_errorName
                //logln("Got the expected error: " + UnicodeString(u_errorName(status)));
            } else{
                if (namebase.compare(result, -1) == 0){
                    // garbage in -> garbage out
                    logln(UnicodeString("ICU will not recognize malformed ACE-Prefixes or incorrect ACE-Prefixes. ") + UnicodeString("namebase: ") + prettify(namebase) + UnicodeString(" result: ") + prettify(result));
                } else {
                    id.append(" should fail, but not failed. ");
                    id.append(u_errorName(status));
                    errln(id);
                }
            }
        }
    }
    type = option = passfail = -1;
    namebase.setToBogus();
    namezone.setToBogus();
    id.remove();
    return;
}
static jstring NativeIDN_convertImpl(JNIEnv* env, jclass, jstring javaSrc, jint flags, jboolean toAscii) {
    ScopedStringChars src(env, javaSrc);
    if (src.get() == NULL) {
        return NULL;
    }
    UChar dst[256];
    UErrorCode status = U_ZERO_ERROR;
    size_t resultLength = toAscii
        ? uidna_IDNToASCII(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status)
        : uidna_IDNToUnicode(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status);
    if (U_FAILURE(status)) {
        jniThrowException(env, "java/lang/IllegalArgumentException", u_errorName(status));
        return NULL;
    }
    if (!toAscii) {
        // ICU only translates separators to ASCII for toASCII.
        // Java expects the translation for toUnicode too.
        // We may as well do this here, while the string is still mutable.
        for (size_t i = 0; i < resultLength; ++i) {
            if (isLabelSeparator(dst[i])) {
                dst[i] = '.';
            }
        }
    }
    return env->NewString(&dst[0], resultLength);
}
예제 #4
0
int
WINAPI
IdnToAscii
(
	DWORD dwFlags,
	LPCWSTR lpUnicodeCharStr,
	int cchUnicodeChar,
	LPWSTR lpASCIICharStr,
	int cchASCIIChar
)
{
	UErrorCode status;
	int32_t retval = uidna_IDNToASCII
	(
		lpUnicodeCharStr,
		cchUnicodeChar,
		lpASCIICharStr,
		cchASCIIChar,
		IDNA_FlagsToICU(dwFlags),
		NULL,
		&status
	);

	if(U_FAILURE(status))
		SetLastError(NLS_ErrorFromICU(status));

	return retval;
}
예제 #5
0
파일: idn.c 프로젝트: Furgas/php-src
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS,
		const char *domain, int32_t domain_len, uint32_t option, int mode)
{
	UChar* ustring = NULL;
	int ustring_len = 0;
	UErrorCode status;
	char     *converted_utf8;
	size_t    converted_utf8_len;
	UChar     converted[MAXPATHLEN];
	int32_t   converted_ret_len;

	/* convert the string to UTF-16. */
	status = U_ZERO_ERROR;
	intl_convert_utf8_to_utf16(&ustring, &ustring_len, domain, domain_len, &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 {
		UParseError parse_error;

		status = U_ZERO_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);
		}
		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;
		intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status);

		if (U_FAILURE(status)) {
			/* 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 );
			efree(converted_utf8);
			RETURN_FALSE;
		}
	}

	/* return the allocated string, not a duplicate */
	RETVAL_STRINGL(converted_utf8, converted_utf8_len);
	//????
	efree(converted_utf8);
}
예제 #6
0
/*
 * imp: common/uidna.cpp
 * hdr: common/unicode/uidna.h
 * @stable ICU 2.6
 */
U_CAPI int32_t U_EXPORT2
uidna_IDNToASCII_4_0(  const UChar* src, int32_t srcLength,
                       UChar* dest, int32_t destCapacity,
                       int32_t options,
                       UParseError* parseError,
                       UErrorCode* status)
{
    return uidna_IDNToASCII(src, srcLength, dest, destCapacity, options, parseError, status);
}
예제 #7
0
// Converts the Unicode input representing a hostname to ASCII using IDN rules.
// The output must be ASCII, but is represented as wide characters.
//
// On success, the output will be filled with the ASCII host name and it will
// return true. Unlike most other canonicalization functions, this assumes that
// the output is empty. The beginning of the host will be at offset 0, and
// the length of the output will be set to the length of the new host name.
//
// On error, this will return false. The output in this case is undefined.
bool IDNToASCII(const UChar* src, int sourceLength, URLBuffer<UChar>& output)
{
    ASSERT(!output.length()); // Output buffer is assumed empty.
    while (true) {
        // Use ALLOW_UNASSIGNED to be more tolerant of hostnames that violate
        // the spec (which do exist). This does not present any risk and is a
        // little more future proof.
        UErrorCode err = U_ZERO_ERROR;
        int numConverted = uidna_IDNToASCII(src, sourceLength, output.data(),
                                             output.capacity(),
                                             UIDNA_ALLOW_UNASSIGNED, 0, &err);
        if (err == U_ZERO_ERROR) {
            output.setLength(numConverted);
            return true;
        }
        if (err != U_BUFFER_OVERFLOW_ERROR)
            return false; // Unknown error, give up.

        // Not enough room in our buffer, expand.
        output.resize(output.capacity() * 2);
    }
}
예제 #8
0
static void TestLength(){
    {
        static const char* cl = "my_very_very_very_very_very_very_very_very_very_very_very_very_very_long_and_incredibly_uncreative_domain_label";
        UChar ul[128] = {'\0'};
        UChar dest[256] = {'\0'};
        /* this unicode string is longer than MAX_LABEL_BUFFER_SIZE and produces an 
           IDNA prepared string (including xn--)that is exactly 63 bytes long */
        UChar ul1[] = { 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774, 
                        0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0x00AD, 0x034F, 0x1806, 0x180B, 
                        0x180C, 0x180D, 0x200B, 0x200C, 0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 
                        0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 
                        0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F, 0xFEFF, 0xD574, 0xD55C, 0xB2E4, 0xBA74, 
                        0xC138, 0x0041, 0x00AD, 0x034F, 0x1806, 0x180B, 0x180C, 0x180D, 0x200B, 
                        0x200C, 0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 
                        0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 
                        0xFE0F, 0xFEFF, 0x00AD, 0x034F, 0x1806, 0x180B, 0x180C, 0x180D, 0x200B, 
                        0x200C, 0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 
                        0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 
                        0xFE0F, 0xFEFF, 0x00AD, 0x034F, 0x1806, 0x180B, 0x180C, 0x180D, 0x200B, 
                        0x200C, 0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 
                        0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 
                        0xFE0F, 0xFEFF, 0x0000
                      };

        int32_t len1 = LENGTHOF(ul1)-1/*remove the null termination*/;
        int32_t destLen = LENGTHOF(dest);
        UErrorCode status = U_ZERO_ERROR;
        UParseError ps;
        int32_t len = (int32_t)strlen(cl);
        u_charsToUChars(cl, ul, len+1);
        destLen = uidna_toUnicode(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_ZERO_ERROR){
            log_err_status(status, "uidna_toUnicode failed with error %s.\n", u_errorName(status));
        }

        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = -1;
        destLen = uidna_toUnicode(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_ZERO_ERROR){
            log_err_status(status, "uidna_toUnicode failed with error %s.\n", u_errorName(status));
        }
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = (int32_t)strlen(cl);
        destLen = uidna_toASCII(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_LABEL_TOO_LONG_ERROR){
            log_err_status(status, "uidna_toASCII failed with error %s.\n", u_errorName(status));
        }
        
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = -1;
        destLen = uidna_toASCII(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_LABEL_TOO_LONG_ERROR){
            log_err_status(status, "uidna_toASCII failed with error %s.\n", u_errorName(status));
        }

        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        destLen = uidna_toASCII(ul1, len1, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_ZERO_ERROR){
            log_err_status(status, "uidna_toASCII failed with error %s.\n", u_errorName(status));
        }
        
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len1 = -1;
        destLen = uidna_toASCII(ul1, len1, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_ZERO_ERROR){
            log_err_status(status, "uidna_toASCII failed with error %s.\n", u_errorName(status));
        }
    }
    {
        static const char* cl = "my_very_very_long_and_incredibly_uncreative_domain_label.my_very_very_long_and_incredibly_uncreative_domain_label.my_very_very_long_and_incredibly_uncreative_domain_label.my_very_very_long_and_incredibly_uncreative_domain_label.my_very_very_long_and_incredibly_uncreative_domain_label.my_very_very_long_and_incredibly_uncreative_domain_label.ibm.com";
        UChar ul[400] = {'\0'};
        UChar dest[400] = {'\0'};
        int32_t destLen = LENGTHOF(dest);
        UErrorCode status = U_ZERO_ERROR;
        UParseError ps;
        int32_t len = (int32_t)strlen(cl);
        u_charsToUChars(cl, ul, len+1);
        
        destLen = uidna_IDNToUnicode(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_IDNToUnicode failed with error %s.\n", u_errorName(status));
        }
        
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = -1;
        destLen = uidna_IDNToUnicode(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_IDNToUnicode failed with error %s.\n", u_errorName(status));
        }
        
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = (int32_t)strlen(cl);
        destLen = uidna_IDNToASCII(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_IDNToASCII failed with error %s.\n", u_errorName(status));
        }
        
        status = U_ZERO_ERROR;
        destLen = LENGTHOF(dest);
        len = -1;
        destLen = uidna_IDNToASCII(ul, len, dest, destLen, UIDNA_DEFAULT, &ps, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_IDNToASCII failed with error %s.\n", u_errorName(status));
        }

        status = U_ZERO_ERROR;
        uidna_compare(ul, len, ul, len, UIDNA_DEFAULT, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_compare failed with error %s.\n", u_errorName(status));
        }
        uidna_compare(ul, -1, ul, -1, UIDNA_DEFAULT, &status);
        if(status != U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR){
            log_err_status(status, "uidna_compare failed with error %s.\n", u_errorName(status));
        }
    }    
}
예제 #9
0
static Variant php_intl_idn_to(CStrRef domain, VRefParam errorcode, int mode) {
  long option = 0;
  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;

  // 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);
    errorcode = status;
    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);
      errorcode = U_MEMORY_ALLOCATION_ERROR;
      return false;
    }
    if (mode == INTL_IDN_TO_ASCII) {
      converted_ret_len = uidna_IDNToASCII(ustring,
          ustring_len, converted, converted_len,
          (int32_t)option, &parse_error, &status);
    } else {
      converted_ret_len = uidna_IDNToUnicode(ustring,
          ustring_len, converted, converted_len,
          (int32_t)option, &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);
    errorcode = status;
    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);
    errorcode = status;
    return false;
  }

  // Return the string
  return String(converted_utf8, converted_utf8_len, AttachString);
}
예제 #10
0
static char *
IDNToASCII(const char *text) // IN
{
#ifdef HAVE_UIDNA_IDNTOASCII
   /*
    * To convert UTF-8 to ASCII, first we need to convert it to UTF-16
    * for ICU, then convert it to 16-bit "ASCII", and then back to
    * 8-bit ASCII (which is ASCII) for xmlParse().
    */
   long utf16Len;
   GError *error = NULL;
   gunichar2 *utf16Text = g_utf8_to_utf16(text, -1, NULL, &utf16Len,
                                          &error);
   if (error) {
      g_warning("Could not convert text \"%s\" to UTF-16: %s\n", text,
                error->message);
      g_error_free(error);
      return NULL;
   }

   int32_t idnLen = 2 * utf16Len;
   UChar *idnText;
   UErrorCode status;
   int32_t len;
   /*
    * If we don't allocate enough characters on the first attempt,
    * IDNToASCII() will return how many characters we need.  If the
    * second attempt fails, just give up rather than looping forever.
    */
tryConversion:
   idnText = g_new(UChar, idnLen + 1);
   status = U_ZERO_ERROR;
   len = uidna_IDNToASCII((const UChar *)utf16Text, utf16Len,
                          idnText, idnLen, UIDNA_DEFAULT, NULL,
                          &status);
   if (len > idnLen) {
      g_free(idnText);
      // Guard against multiple loops.
      if (idnLen != 2 * utf16Len) {
         g_warning("The ASCII length was greater than we allocated after two "
                   "attempts; giving up on \"%s\".", text);
         g_free(idnText);
         g_free(utf16Text);
         return NULL;
      }
      idnLen = len;
      goto tryConversion;
   } else if (U_FAILURE(status)) {
      g_warning("Could not convert text \"%s\" to IDN: %s\n", text,
                u_errorName(status));
      g_free(idnText);
      g_free(utf16Text);
      return NULL;
   }

   // Convert it back to UTF-8/ASCII.
   char *ret = g_utf16_to_utf8((gunichar2 *)idnText, len, NULL, NULL,
                               NULL);
   g_free(idnText);
   g_free(utf16Text);

   return ret;
#else
   g_assert_not_reached();
   return NULL;
#endif // HAVE_UIDNA_IDNTOASCII
}
예제 #11
0
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);
}
예제 #12
0
파일: idn.c 프로젝트: aholmes/php-src
static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, int mode)
{
	unsigned char* domain;
	int domain_len;
	long option = 0;
	UChar* ustring = NULL;
	int ustring_len = 0;
	UErrorCode status;
	char     *converted_utf8;
	int32_t   converted_utf8_len;
	UChar     converted[MAXPATHLEN];
	int32_t   converted_ret_len;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", (char **)&domain, &domain_len, &option) == FAILURE) {
		return;
	}

	if (domain_len < 1) {
		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "idn_to_ascii: empty domain name", 0 TSRMLS_CC );
		RETURN_FALSE;
	}

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

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

		/* Set error messages. */
		intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC );
		efree(ustring);
		RETURN_FALSE;
	} else {
		UParseError parse_error;

		status = U_ZERO_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);
		}
		efree(ustring);

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

		status = U_ZERO_ERROR;
		intl_convert_utf16_to_utf8(&converted_utf8, &converted_utf8_len, converted, converted_ret_len, &status);

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

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

	/* return the allocated string, not a duplicate */
	RETURN_STRINGL(((char *)converted_utf8), converted_utf8_len, 0);
}
예제 #13
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);
}