1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 2009 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Pierre A. Joye <pierre@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id: idn.c 292566 2009-12-23 21:41:05Z stas $ */
/* {{{ includes */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <php.h>
#include <unicode/uidna.h>
#include <unicode/ustring.h>
#include "ext/standard/php_string.h"
#include "intl_error.h"
#include "intl_convert.h"
/* }}} */
/* {{{ grapheme_register_constants
* Register API constants
*/
void idn_register_constants( INIT_FUNC_ARGS )
{
/* Option to prohibit processing of unassigned codepoints in the input and
do not check if the input conforms to STD-3 ASCII rules. */
REGISTER_LONG_CONSTANT("IDNA_DEFAULT", UIDNA_DEFAULT, CONST_CS | CONST_PERSISTENT);
/* Option to allow processing of unassigned codepoints in the input */
REGISTER_LONG_CONSTANT("IDNA_ALLOW_UNASSIGNED", UIDNA_ALLOW_UNASSIGNED, CONST_CS | CONST_PERSISTENT);
/* Option to check if input conforms to STD-3 ASCII rules */
REGISTER_LONG_CONSTANT("IDNA_USE_STD3_RULES", UIDNA_USE_STD3_RULES, CONST_CS | CONST_PERSISTENT);
}
/* }}} */
enum {
INTL_IDN_TO_ASCII = 0,
INTL_IDN_TO_UTF8
};
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);
}
/* {{{ proto int idn_to_ascii(string domain[, int options])
Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC */
PHP_FUNCTION(idn_to_ascii)
{
php_intl_idn_to(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_ASCII);
}
/* }}} */
/* {{{ proto int idn_to_utf8(string domain[, int options])
Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC */
PHP_FUNCTION(idn_to_utf8)
{
php_intl_idn_to(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_UTF8);
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: fdm=marker
* vim: noet sw=4 ts=4
*/
|