@@ -104,6 +104,11 @@ static void php_mb_gpc_get_detect_order(const zend_encoding ***list, size_t *lis
104
104
105
105
static void php_mb_gpc_set_input_encoding (const zend_encoding * encoding );
106
106
107
+ static inline zend_bool php_mb_is_unsupported_no_encoding (enum mbfl_no_encoding no_enc );
108
+
109
+ static inline zend_bool php_mb_is_no_encoding_unicode (enum mbfl_no_encoding no_enc );
110
+
111
+ static inline zend_bool php_mb_is_no_encoding_utf8 (enum mbfl_no_encoding no_enc );
107
112
/* }}} */
108
113
109
114
/* {{{ php_mb_default_identify_list */
@@ -1992,6 +1997,73 @@ PHP_FUNCTION(mb_detect_order)
1992
1997
}
1993
1998
/* }}} */
1994
1999
2000
+ static inline int php_mb_check_code_point (long cp )
2001
+ {
2002
+ enum mbfl_no_encoding no_enc ;
2003
+ char * buf ;
2004
+ char buf_len ;
2005
+
2006
+ no_enc = MBSTRG (current_internal_encoding )-> no_encoding ;
2007
+
2008
+ if (php_mb_is_no_encoding_utf8 (no_enc )) {
2009
+
2010
+ if ((cp > 0 && 0xd800 > cp ) || (cp > 0xdfff && 0x110000 > cp )) {
2011
+ return 1 ;
2012
+ }
2013
+
2014
+ return 0 ;
2015
+ } else if (php_mb_is_no_encoding_unicode (no_enc )) {
2016
+
2017
+ if (0 > cp || cp > 0x10ffff ) {
2018
+ return 0 ;
2019
+ }
2020
+
2021
+ return 1 ;
2022
+
2023
+ // backward compatibility
2024
+ } else if (php_mb_is_unsupported_no_encoding (no_enc )) {
2025
+ return cp < 0xffff && cp > 0x0 ;
2026
+ }
2027
+
2028
+ if (cp < 0x100 ) {
2029
+ buf_len = 1 ;
2030
+ buf = (char * ) safe_emalloc (buf_len , 1 , 1 );
2031
+ buf [0 ] = cp ;
2032
+ buf [1 ] = 0 ;
2033
+ } else if (cp < 0x10000 ) {
2034
+ buf_len = 2 ;
2035
+ buf = (char * ) safe_emalloc (buf_len , 1 , 1 );
2036
+ buf [0 ] = cp >> 8 ;
2037
+ buf [1 ] = cp & 0xff ;
2038
+ buf [2 ] = 0 ;
2039
+ } else if (cp < 0x1000000 ) {
2040
+ buf_len = 3 ;
2041
+ buf = (char * ) safe_emalloc (buf_len , 1 , 1 );
2042
+ buf [0 ] = cp >> 16 ;
2043
+ buf [1 ] = (cp >> 8 ) & 0xff ;
2044
+ buf [2 ] = cp & 0xff ;
2045
+ buf [3 ] = 0 ;
2046
+ } else {
2047
+ buf_len = 4 ;
2048
+ buf = (char * ) safe_emalloc (buf_len , 1 , 1 );
2049
+ buf [0 ] = cp >> 24 ;
2050
+ buf [1 ] = (cp >> 16 ) & 0xff ;
2051
+ buf [2 ] = (cp >> 8 ) & 0xff ;
2052
+ buf [3 ] = cp & 0xff ;
2053
+ buf [4 ] = 0 ;
2054
+ }
2055
+
2056
+ if (php_mb_check_encoding (buf , buf_len , NULL )) {
2057
+ efree (buf );
2058
+
2059
+ return 1 ;
2060
+ }
2061
+
2062
+ efree (buf );
2063
+
2064
+ return 0 ;
2065
+ }
2066
+
1995
2067
/* {{{ proto mixed mb_substitute_character([mixed substchar])
1996
2068
Sets the current substitute_character or returns the current substitute_character */
1997
2069
PHP_FUNCTION (mb_substitute_character )
@@ -2026,7 +2098,7 @@ PHP_FUNCTION(mb_substitute_character)
2026
2098
} else {
2027
2099
convert_to_long_ex (arg1 );
2028
2100
2029
- if (Z_LVAL_P ( arg1 ) < 0xffff && Z_LVAL_P (arg1 ) > 0x0 ) {
2101
+ if (php_mb_check_code_point ( Z_LVAL_P (arg1 )) ) {
2030
2102
MBSTRG (current_filter_illegal_mode ) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR ;
2031
2103
MBSTRG (current_filter_illegal_substchar ) = Z_LVAL_P (arg1 );
2032
2104
} else {
@@ -2037,7 +2109,7 @@ PHP_FUNCTION(mb_substitute_character)
2037
2109
break ;
2038
2110
default :
2039
2111
convert_to_long_ex (arg1 );
2040
- if (Z_LVAL_P ( arg1 ) < 0xffff && Z_LVAL_P (arg1 ) > 0x0 ) {
2112
+ if (php_mb_check_code_point ( Z_LVAL_P (arg1 )) ) {
2041
2113
MBSTRG (current_filter_illegal_mode ) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR ;
2042
2114
MBSTRG (current_filter_illegal_substchar ) = Z_LVAL_P (arg1 );
2043
2115
} else {
@@ -3124,7 +3196,7 @@ PHP_FUNCTION(mb_strimwidth)
3124
3196
if (from < 0 ) {
3125
3197
from += swidth ;
3126
3198
}
3127
-
3199
+
3128
3200
if (from < 0 || (size_t )from > str_len ) {
3129
3201
php_error_docref (NULL , E_WARNING , "Start position is out of range" );
3130
3202
RETURN_FALSE ;
0 commit comments