mirror of
https://github.com/php/php-src.git
synced 2024-10-03 07:46:12 +00:00
Merge branch 'master' of https://git.php.net/repository/php-src
# By Yasuo Ohgaki (5) and others # Via Stanislav Malyshev (5) and others * 'master' of https://git.php.net/repository/php-src: added test code for #65045. fixed #65045: mb_convert_encoding breaks well-formed character. Don't try to clean up generator stack on unclean shutdown NEWS Added PHP_FCGI_BACKLOG, overrides the default listen backlog Merge branch 'PHP-5.5' into master Fixed bug #49175: mod_files.sh does not support hash bits Fixed bug #35703: when session_name("123") consist only digits, should warning Fixed bug #49175: mod_files.sh does not support hash bits Fixed bug #49175: mod_files.sh does not support hash bits add fix for #60560 into upgrading Add a __wakeup() method to SplFixedArray, thereby fixing serialising an Update NEWS small optimization fix bug #61860: use USearch for searches, it does the right thing
This commit is contained in:
commit
7a331856df
20
Zend/tests/generators/bug65035.phpt
Normal file
20
Zend/tests/generators/bug65035.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #65035: yield / exit segfault
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
fn();
|
||||
yield;
|
||||
}
|
||||
|
||||
function fn() {
|
||||
exit('Done');
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
$gen->current();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
20
Zend/tests/generators/bug65161.phpt
Normal file
20
Zend/tests/generators/bug65161.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #65161: Generator + autoload + syntax error = segfault
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function autoload() {
|
||||
foo();
|
||||
}
|
||||
spl_autoload_register('autoload');
|
||||
|
||||
function testGenerator() {
|
||||
new SyntaxError('param');
|
||||
yield;
|
||||
}
|
||||
|
||||
foreach (testGenerator() as $i);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Call to undefined function foo() in %s on line %d
|
@ -55,6 +55,12 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
zval_ptr_dtor(&execute_data->current_this);
|
||||
}
|
||||
|
||||
/* A fatal error / die occured during the generator execution. Trying to clean
|
||||
* up the stack may not be safe in this case. */
|
||||
if (CG(unclean_shutdown)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the generator is closed before it can finish execution (reach
|
||||
* a return statement) we have to free loop variables manually, as
|
||||
* we don't know whether the SWITCH_FREE / FREE opcodes have run */
|
||||
|
@ -113,7 +113,7 @@ PHP_FUNCTION(grapheme_strpos)
|
||||
unsigned char *found;
|
||||
long loffset = 0;
|
||||
int32_t offset = 0;
|
||||
int ret_pos, uchar_pos;
|
||||
int ret_pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", (char **)&haystack, &haystack_len, (char **)&needle, &needle_len, &loffset) == FAILURE) {
|
||||
|
||||
@ -160,10 +160,10 @@ PHP_FUNCTION(grapheme_strpos)
|
||||
}
|
||||
|
||||
/* do utf16 part of the strpos */
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, &uchar_pos, 0 /* fIgnoreCase */ TSRMLS_CC );
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 0 /* fIgnoreCase */, 0 /* last */ TSRMLS_CC );
|
||||
|
||||
if ( ret_pos >= 0 ) {
|
||||
RETURN_LONG(ret_pos + offset);
|
||||
RETURN_LONG(ret_pos);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -180,7 +180,7 @@ PHP_FUNCTION(grapheme_stripos)
|
||||
unsigned char *found;
|
||||
long loffset = 0;
|
||||
int32_t offset = 0;
|
||||
int ret_pos, uchar_pos;
|
||||
int ret_pos;
|
||||
int is_ascii;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", (char **)&haystack, &haystack_len, (char **)&needle, &needle_len, &loffset) == FAILURE) {
|
||||
@ -235,10 +235,10 @@ PHP_FUNCTION(grapheme_stripos)
|
||||
}
|
||||
|
||||
/* do utf16 part of the strpos */
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, &uchar_pos, 1 /* fIgnoreCase */ TSRMLS_CC );
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 1 /* fIgnoreCase */, 0 /*last */ TSRMLS_CC );
|
||||
|
||||
if ( ret_pos >= 0 ) {
|
||||
RETURN_LONG(ret_pos + offset);
|
||||
RETURN_LONG(ret_pos);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -304,7 +304,7 @@ PHP_FUNCTION(grapheme_strrpos)
|
||||
/* else we need to continue via utf16 */
|
||||
}
|
||||
|
||||
ret_pos = grapheme_strrpos_utf16(haystack, haystack_len, needle, needle_len, offset, 0 /* f_ignore_case */ TSRMLS_CC);
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 0 /* f_ignore_case */, 1/* last */ TSRMLS_CC);
|
||||
|
||||
if ( ret_pos >= 0 ) {
|
||||
RETURN_LONG(ret_pos);
|
||||
@ -382,7 +382,7 @@ PHP_FUNCTION(grapheme_strripos)
|
||||
/* else we need to continue via utf16 */
|
||||
}
|
||||
|
||||
ret_pos = grapheme_strrpos_utf16(haystack, haystack_len, needle, needle_len, offset, 1 /* f_ignore_case */ TSRMLS_CC);
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 1 /* f_ignore_case */, 1 /*last */ TSRMLS_CC);
|
||||
|
||||
if ( ret_pos >= 0 ) {
|
||||
RETURN_LONG(ret_pos);
|
||||
@ -659,7 +659,7 @@ static void strstr_common_handler(INTERNAL_FUNCTION_PARAMETERS, int f_ignore_cas
|
||||
}
|
||||
|
||||
/* need to work in utf16 */
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, 0, &uchar_pos, f_ignore_case TSRMLS_CC );
|
||||
ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, 0, &uchar_pos, f_ignore_case, 0 /*last */ TSRMLS_CC );
|
||||
|
||||
if ( ret_pos < 0 ) {
|
||||
RETURN_FALSE;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <unicode/ucol.h>
|
||||
#include <unicode/ustring.h>
|
||||
#include <unicode/ubrk.h>
|
||||
#include <unicode/usearch.h>
|
||||
|
||||
#include "ext/standard/php_string.h"
|
||||
|
||||
@ -47,49 +48,8 @@ grapheme_close_global_iterator( TSRMLS_D )
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_intl_case_fold: convert string to lowercase */
|
||||
void
|
||||
grapheme_intl_case_fold(UChar** ptr_to_free, UChar **str, int32_t *str_len, UErrorCode *pstatus )
|
||||
{
|
||||
UChar *dest;
|
||||
int32_t dest_len, size_required;
|
||||
|
||||
/* allocate a destination string that is a bit larger than the src, hoping that is enough */
|
||||
dest_len = (*str_len) + ( *str_len / 10 );
|
||||
dest = (UChar*) eumalloc(dest_len);
|
||||
|
||||
*pstatus = U_ZERO_ERROR;
|
||||
size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
|
||||
|
||||
dest_len = size_required;
|
||||
|
||||
if ( U_BUFFER_OVERFLOW_ERROR == *pstatus ) {
|
||||
|
||||
dest = (UChar*) eurealloc(dest, dest_len);
|
||||
|
||||
*pstatus = U_ZERO_ERROR;
|
||||
size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
|
||||
}
|
||||
|
||||
if ( U_FAILURE(*pstatus) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( NULL != ptr_to_free) {
|
||||
efree(*ptr_to_free);
|
||||
*ptr_to_free = dest;
|
||||
}
|
||||
|
||||
*str = dest;
|
||||
*str_len = dest_len;
|
||||
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_substr_ascii f='from' - starting point, l='length' */
|
||||
void
|
||||
grapheme_substr_ascii(char *str, int str_len, int f, int l, int argc, char **sub_str, int *sub_str_len)
|
||||
void grapheme_substr_ascii(char *str, int str_len, int f, int l, int argc, char **sub_str, int *sub_str_len)
|
||||
{
|
||||
*sub_str = NULL;
|
||||
|
||||
@ -147,224 +107,100 @@ grapheme_substr_ascii(char *str, int str_len, int f, int l, int argc, char **sub
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_strrpos_utf16 - strrpos using utf16 */
|
||||
int
|
||||
grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC)
|
||||
{
|
||||
UChar *uhaystack, *puhaystack, *uhaystack_end, *uneedle;
|
||||
int32_t uhaystack_len, uneedle_len;
|
||||
UErrorCode status;
|
||||
unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
|
||||
UBreakIterator* bi = NULL;
|
||||
int ret_pos, pos;
|
||||
|
||||
/* convert the strings to UTF-16. */
|
||||
uhaystack = NULL;
|
||||
uhaystack_len = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_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 input string to UTF-16", 0 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( f_ignore_case ) {
|
||||
grapheme_intl_case_fold(&uhaystack, &uhaystack, &uhaystack_len, &status );
|
||||
}
|
||||
|
||||
/* get a pointer to the haystack taking into account the offset */
|
||||
bi = NULL;
|
||||
status = U_ZERO_ERROR;
|
||||
bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC );
|
||||
|
||||
puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset);
|
||||
|
||||
if ( NULL == puhaystack ) {
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uneedle = NULL;
|
||||
uneedle_len = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_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 input string to UTF-16", 0 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
if (uneedle) {
|
||||
efree( uneedle );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( f_ignore_case ) {
|
||||
grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status );
|
||||
}
|
||||
|
||||
ret_pos = -1; /* -1 represents 'not found' */
|
||||
|
||||
/* back up until there's needle_len characters to compare */
|
||||
|
||||
uhaystack_end = uhaystack + uhaystack_len;
|
||||
pos = ubrk_last(bi);
|
||||
puhaystack = uhaystack + pos;
|
||||
|
||||
while ( uhaystack_end - puhaystack < uneedle_len ) {
|
||||
|
||||
pos = ubrk_previous(bi);
|
||||
|
||||
if ( UBRK_DONE == pos ) {
|
||||
break;
|
||||
}
|
||||
|
||||
puhaystack = uhaystack + pos;
|
||||
}
|
||||
|
||||
/* is there enough haystack left to hold the needle? */
|
||||
if ( ( uhaystack_end - puhaystack ) < uneedle_len ) {
|
||||
/* not enough, not found */
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while ( UBRK_DONE != pos ) {
|
||||
|
||||
if (!u_memcmp(uneedle, puhaystack, uneedle_len)) { /* needle_len - 1 in zend memnstr? */
|
||||
|
||||
/* does the grapheme in the haystack end at the same place as the last grapheme in the needle? */
|
||||
|
||||
if ( ubrk_isBoundary(bi, pos + uneedle_len) ) {
|
||||
|
||||
/* found it, get grapheme count offset */
|
||||
ret_pos = grapheme_count_graphemes(bi, uhaystack, pos);
|
||||
break;
|
||||
}
|
||||
|
||||
/* set position back */
|
||||
ubrk_isBoundary(bi, pos);
|
||||
}
|
||||
|
||||
pos = ubrk_previous(bi);
|
||||
puhaystack = uhaystack + pos;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
#define STRPOS_CHECK_STATUS(status, error) \
|
||||
if ( U_FAILURE( (status) ) ) { \
|
||||
intl_error_set_code( NULL, (status) TSRMLS_CC ); \
|
||||
intl_error_set_custom_msg( NULL, (error), 0 TSRMLS_CC ); \
|
||||
if (uhaystack) { \
|
||||
efree( uhaystack ); \
|
||||
} \
|
||||
if (uneedle) { \
|
||||
efree( uneedle ); \
|
||||
} \
|
||||
if(bi) { \
|
||||
ubrk_close (bi); \
|
||||
} \
|
||||
if(src) { \
|
||||
usearch_close(src); \
|
||||
} \
|
||||
return -1; \
|
||||
}
|
||||
if (uneedle) {
|
||||
efree( uneedle );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
|
||||
return ret_pos;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/
|
||||
int
|
||||
grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case TSRMLS_DC)
|
||||
int grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case, int last TSRMLS_DC)
|
||||
{
|
||||
UChar *uhaystack, *puhaystack, *uneedle;
|
||||
int32_t uhaystack_len, uneedle_len;
|
||||
int ret_pos;
|
||||
UChar *uhaystack = NULL, *puhaystack, *uneedle = NULL;
|
||||
int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0;
|
||||
unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE];
|
||||
UBreakIterator* bi;
|
||||
UBreakIterator* bi = NULL;
|
||||
UErrorCode status;
|
||||
UStringSearch* src = NULL;
|
||||
UCollator *coll;
|
||||
|
||||
*puchar_pos = -1;
|
||||
|
||||
if(puchar_pos) {
|
||||
*puchar_pos = -1;
|
||||
}
|
||||
/* convert the strings to UTF-16. */
|
||||
|
||||
uhaystack = NULL;
|
||||
uhaystack_len = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, (char *) haystack, haystack_len, &status );
|
||||
STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16");
|
||||
|
||||
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 input string to UTF-16", 0 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get a pointer to the haystack taking into account the offset */
|
||||
bi = NULL;
|
||||
status = U_ZERO_ERROR;
|
||||
bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC );
|
||||
|
||||
puhaystack = grapheme_get_haystack_offset(bi, uhaystack, uhaystack_len, offset);
|
||||
uhaystack_len = (uhaystack_len - ( puhaystack - uhaystack));
|
||||
|
||||
if ( NULL == puhaystack ) {
|
||||
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( f_ignore_case ) {
|
||||
grapheme_intl_case_fold(&uhaystack, &puhaystack, &uhaystack_len, &status );
|
||||
}
|
||||
|
||||
uneedle = NULL;
|
||||
uneedle_len = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_len, &status );
|
||||
STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16");
|
||||
|
||||
if ( U_FAILURE( status ) ) {
|
||||
/* Set global error code. */
|
||||
intl_error_set_code( NULL, status TSRMLS_CC );
|
||||
/* get a pointer to the haystack taking into account the offset */
|
||||
status = U_ZERO_ERROR;
|
||||
bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status TSRMLS_CC );
|
||||
STRPOS_CHECK_STATUS(status, "Failed to get iterator");
|
||||
status = U_ZERO_ERROR;
|
||||
ubrk_setText(bi, uhaystack, uhaystack_len, &status);
|
||||
STRPOS_CHECK_STATUS(status, "Failed to set up iterator");
|
||||
|
||||
/* Set error messages. */
|
||||
intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 TSRMLS_CC );
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
}
|
||||
if (uneedle) {
|
||||
efree( uneedle );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
|
||||
return -1;
|
||||
status = U_ZERO_ERROR;
|
||||
src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len, "", bi, &status);
|
||||
STRPOS_CHECK_STATUS(status, "Error creating search object");
|
||||
|
||||
if(f_ignore_case) {
|
||||
coll = usearch_getCollator(src);
|
||||
status = U_ZERO_ERROR;
|
||||
ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &status);
|
||||
STRPOS_CHECK_STATUS(status, "Error setting collation strength");
|
||||
usearch_reset(src);
|
||||
}
|
||||
|
||||
if ( f_ignore_case ) {
|
||||
grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &status );
|
||||
if(offset != 0) {
|
||||
offset_pos = grapheme_get_haystack_offset(bi, offset);
|
||||
if(offset_pos == -1) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
STRPOS_CHECK_STATUS(status, "Invalid search offset");
|
||||
}
|
||||
status = U_ZERO_ERROR;
|
||||
usearch_setOffset(src, offset_pos, &status);
|
||||
STRPOS_CHECK_STATUS(status, "Invalid search offset");
|
||||
}
|
||||
|
||||
ret_pos = grapheme_memnstr_grapheme(bi, puhaystack, uneedle, uneedle_len, puhaystack + uhaystack_len );
|
||||
|
||||
*puchar_pos = ubrk_current(bi);
|
||||
|
||||
if(last) {
|
||||
char_pos = usearch_last(src, &status);
|
||||
if(char_pos < offset_pos) {
|
||||
/* last one is beyound our start offset */
|
||||
char_pos = USEARCH_DONE;
|
||||
}
|
||||
} else {
|
||||
char_pos = usearch_next(src, &status);
|
||||
}
|
||||
STRPOS_CHECK_STATUS(status, "Error looking up string");
|
||||
if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) {
|
||||
ret_pos = grapheme_count_graphemes(bi, uhaystack,char_pos);
|
||||
if(puchar_pos) {
|
||||
*puchar_pos = char_pos;
|
||||
}
|
||||
} else {
|
||||
ret_pos = -1;
|
||||
}
|
||||
|
||||
if (uhaystack) {
|
||||
efree( uhaystack );
|
||||
@ -373,6 +209,7 @@ grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned ch
|
||||
efree( uneedle );
|
||||
}
|
||||
ubrk_close (bi);
|
||||
usearch_close (src);
|
||||
|
||||
return ret_pos;
|
||||
}
|
||||
@ -432,8 +269,7 @@ int grapheme_split_string(const UChar *text, int32_t text_length, int boundary_a
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_count_graphemes */
|
||||
int32_t
|
||||
grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len)
|
||||
int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len)
|
||||
{
|
||||
int ret_len = 0;
|
||||
int pos = 0;
|
||||
@ -455,85 +291,16 @@ grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_memnstr_grapheme: find needle in haystack using grapheme boundaries */
|
||||
int32_t
|
||||
grapheme_memnstr_grapheme(UBreakIterator *bi, UChar *haystack, UChar *needle, int32_t needle_len, UChar *end)
|
||||
{
|
||||
UChar *p = haystack;
|
||||
UChar ne = needle[needle_len-1];
|
||||
UErrorCode status;
|
||||
int32_t grapheme_offset;
|
||||
|
||||
end -= needle_len;
|
||||
|
||||
while (p <= end) {
|
||||
|
||||
if ((p = u_memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
|
||||
|
||||
if (!u_memcmp(needle, p, needle_len - 1)) { /* needle_len - 1 works because if needle_len is 1, we've already tested the char */
|
||||
|
||||
/* does the grapheme end here? */
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ubrk_setText (bi, haystack, (end - haystack) + needle_len, &status);
|
||||
|
||||
if ( ubrk_isBoundary (bi, (p - haystack) + needle_len) ) {
|
||||
|
||||
/* found it, get grapheme count offset */
|
||||
grapheme_offset = grapheme_count_graphemes(bi, haystack, (p - haystack));
|
||||
|
||||
return grapheme_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_memrstr_grapheme: reverse find needle in haystack using grapheme boundaries */
|
||||
inline void *grapheme_memrchr_grapheme(const void *s, int c, int32_t n)
|
||||
{
|
||||
register unsigned char *e;
|
||||
|
||||
if (n <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (e = (unsigned char *)s + n - 1; e >= (unsigned char *)s; e--) {
|
||||
if (*e == (unsigned char)c) {
|
||||
return (void *)e;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_get_haystack_offset - bump the haystack pointer based on the grapheme count offset */
|
||||
UChar *
|
||||
grapheme_get_haystack_offset(UBreakIterator* bi, UChar *uhaystack, int32_t uhaystack_len, int32_t offset)
|
||||
int grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset)
|
||||
{
|
||||
UErrorCode status;
|
||||
int32_t pos;
|
||||
int32_t (*iter_op)(UBreakIterator* bi);
|
||||
int iter_incr;
|
||||
|
||||
if ( NULL != bi ) {
|
||||
status = U_ZERO_ERROR;
|
||||
ubrk_setText (bi, uhaystack, uhaystack_len, &status);
|
||||
}
|
||||
|
||||
if ( 0 == offset ) {
|
||||
return uhaystack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( offset < 0 ) {
|
||||
@ -558,10 +325,10 @@ grapheme_get_haystack_offset(UBreakIterator* bi, UChar *uhaystack, int32_t uhays
|
||||
}
|
||||
|
||||
if ( offset != 0 ) {
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return uhaystack + pos;
|
||||
return pos;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -607,8 +374,7 @@ grapheme_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned c
|
||||
/* }}} */
|
||||
|
||||
/* {{{ grapheme_get_break_iterator: get a clone of the global character break iterator */
|
||||
UBreakIterator*
|
||||
grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC )
|
||||
UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC )
|
||||
{
|
||||
int32_t buffer_size;
|
||||
|
||||
|
@ -23,35 +23,25 @@
|
||||
/* get_break_interator: get a break iterator from the global structure */
|
||||
UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC );
|
||||
|
||||
void
|
||||
grapheme_substr_ascii(char *str, int32_t str_len, int32_t f, int32_t l, int argc, char **sub_str, int *sub_str_len);
|
||||
void grapheme_substr_ascii(char *str, int32_t str_len, int32_t f, int32_t l, int argc, char **sub_str, int *sub_str_len);
|
||||
|
||||
int
|
||||
grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC);
|
||||
int grapheme_strrpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int f_ignore_case TSRMLS_DC);
|
||||
|
||||
int
|
||||
grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int *puchar_pos, int f_ignore_case TSRMLS_DC);
|
||||
int grapheme_strpos_utf16(unsigned char *haystack, int32_t haystack_len, unsigned char*needle, int32_t needle_len, int32_t offset, int *puchar_pos, int f_ignore_case, int last TSRMLS_DC);
|
||||
|
||||
int grapheme_ascii_check(const unsigned char *day, int32_t len);
|
||||
|
||||
int grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len TSRMLS_DC );
|
||||
|
||||
int32_t
|
||||
grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len);
|
||||
|
||||
int32_t
|
||||
grapheme_memnstr_grapheme(UBreakIterator *bi, UChar *haystack, UChar *needle, int32_t needle_len, UChar *end);
|
||||
int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len);
|
||||
|
||||
inline void *grapheme_memrchr_grapheme(const void *s, int c, int32_t n);
|
||||
|
||||
UChar *
|
||||
grapheme_get_haystack_offset(UBreakIterator* bi, UChar *uhaystack, int32_t uhaystack_len, int32_t offset);
|
||||
int grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset);
|
||||
|
||||
int32_t
|
||||
grapheme_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned char *needle, int32_t needle_len, int32_t offset);
|
||||
int32_t grapheme_strrpos_ascii(unsigned char *haystack, int32_t haystack_len, unsigned char *needle, int32_t needle_len, int32_t offset);
|
||||
|
||||
UBreakIterator*
|
||||
grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC );
|
||||
UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status TSRMLS_DC );
|
||||
|
||||
/* OUTSIDE_STRING: check if (possibly negative) long offset is outside the string with int32_t length */
|
||||
#define OUTSIDE_STRING(offset, max_len) ( offset <= INT32_MIN || offset > INT32_MAX || (offset < 0 ? -offset > (long) max_len : offset >= (long) max_len) )
|
||||
|
18
ext/intl/tests/bug61860.phpt
Normal file
18
ext/intl/tests/bug61860.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #61860: Offsets may be wrong for grapheme_stri* functions
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$haystack = 'Auf der Straße nach Paris habe ich mit dem Fahrer gesprochen';
|
||||
var_dump(
|
||||
grapheme_stripos($haystack, 'pariS '),
|
||||
grapheme_stristr($haystack, 'paRis '),
|
||||
grapheme_substr($haystack, grapheme_stripos($haystack, 'Paris'))
|
||||
);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(20)
|
||||
string(40) "Paris habe ich mit dem Fahrer gesprochen"
|
||||
string(40) "Paris habe ich mit dem Fahrer gesprochen"
|
@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_wchar = {
|
||||
mbfl_filt_conv_common_ctor,
|
||||
mbfl_filt_conv_common_dtor,
|
||||
mbfl_filt_conv_utf8_wchar,
|
||||
mbfl_filt_conv_common_flush
|
||||
mbfl_filt_conv_utf8_wchar_flush
|
||||
};
|
||||
|
||||
const struct mbfl_convert_vtbl vtbl_wchar_utf8 = {
|
||||
@ -93,6 +93,17 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8 = {
|
||||
|
||||
#define CK(statement) do { if ((statement) < 0) return (-1); } while (0)
|
||||
|
||||
int mbfl_filt_put_invalid_char(int c, mbfl_convert_filter *filter)
|
||||
{
|
||||
int w;
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
w |= MBFL_WCSGROUP_THROUGH;
|
||||
filter->status = 0;
|
||||
filter->cache = 0;
|
||||
CK((*filter->output_function)(w, filter->data));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* UTF-8 => wchar
|
||||
*/
|
||||
@ -100,111 +111,104 @@ int mbfl_filt_conv_utf8_wchar(int c, mbfl_convert_filter *filter)
|
||||
{
|
||||
int s, c1, w = 0, flag = 0;
|
||||
|
||||
if (c < 0x80) {
|
||||
if (filter->status != 0) {
|
||||
w = (filter->cache & MBFL_WCSGROUP_MASK) | MBFL_WCSGROUP_THROUGH;
|
||||
CK((*filter->output_function)(w, filter->data));
|
||||
filter->status = 0;
|
||||
filter->cache = 0;
|
||||
}
|
||||
if (c >= 0) {
|
||||
retry:
|
||||
switch (filter->status & 0xff) {
|
||||
case 0x00:
|
||||
if (c < 0x80) {
|
||||
CK((*filter->output_function)(c, filter->data));
|
||||
}
|
||||
} else if (c < 0xc0) {
|
||||
int status = filter->status & 0xff;
|
||||
switch (status) {
|
||||
case 0x10: /* 2byte code 2nd char: 0x80-0xbf */
|
||||
case 0x21: /* 3byte code 3rd char: 0x80-0xbf */
|
||||
case 0x32: /* 4byte code 4th char: 0x80-0xbf */
|
||||
filter->status = 0;
|
||||
s = filter->cache | (c & 0x3f);
|
||||
filter->cache = 0;
|
||||
if ((status == 0x10 && s >= 0x80) ||
|
||||
(status == 0x21 && s >= 0x800 && (s < 0xd800 || s > 0xdfff)) ||
|
||||
(status == 0x32 && s >= 0x10000 && s < 0x110000)) {
|
||||
CK((*filter->output_function)(s, filter->data));
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */
|
||||
s = filter->cache | ((c & 0x3f) << 6);
|
||||
c1 = (s >> 12) & 0xf;
|
||||
if ((c1 == 0x0 && c >= 0xa0) ||
|
||||
(c1 == 0xd && c < 0xa0) ||
|
||||
(c1 > 0x0 && c1 != 0xd)) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
case 0x31: /* 4byte code 3rd char: 0x80-0xbf */
|
||||
filter->cache |= ((c & 0x3f) << 6);
|
||||
filter->status++;
|
||||
break;
|
||||
case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */
|
||||
s = filter->cache | ((c & 0x3f) << 12);
|
||||
c1 = (s >> 18) & 0x7;
|
||||
if ((c1 == 0x0 && c >= 0x90) ||
|
||||
(c1 > 0x0 && c1 < 0x4) ||
|
||||
(c1 == 0x4 && c < 0x90)) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
} else if (c < 0xc2) { /* invalid: 0xc0,0xc1 */
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
} else if (c < 0xe0) { /* 2byte code first char: 0xc2-0xdf */
|
||||
if (filter->status == 0x0) {
|
||||
} else if (c >= 0xc2 && c <= 0xdf) { /* 2byte code first char: 0xc2-0xdf */
|
||||
filter->status = 0x10;
|
||||
filter->cache = (c & 0x1f) << 6;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
} else if (c < 0xf0) { /* 3byte code first char: 0xe0-0xef */
|
||||
if (filter->status == 0x0) {
|
||||
filter->cache = c & 0x1f;
|
||||
} else if (c >= 0xe0 && c <= 0xef) { /* 3byte code first char: 0xe0-0xef */
|
||||
filter->status = 0x20;
|
||||
filter->cache = (c & 0xf) << 12;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
} else if (c < 0xf5) { /* 4byte code first char: 0xf0-0xf4 */
|
||||
if (filter->status == 0x0) {
|
||||
filter->cache = c & 0xf;
|
||||
} else if (c >= 0xf0 && c <= 0xf4) { /* 3byte code first char: 0xf0-0xf4 */
|
||||
filter->status = 0x30;
|
||||
filter->cache = (c & 0x7) << 18;
|
||||
filter->cache = c & 0x7;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
mbfl_filt_put_invalid_char(c, filter);
|
||||
}
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
w |= MBFL_WCSGROUP_THROUGH;
|
||||
CK((*filter->output_function)(w, filter->data));
|
||||
break;
|
||||
case 0x10: /* 2byte code 2nd char: 0x80-0xbf */
|
||||
case 0x21: /* 3byte code 3rd char: 0x80-0xbf */
|
||||
case 0x32: /* 4byte code 4th char: 0x80-0xbf */
|
||||
filter->status = 0;
|
||||
filter->cache = 0;
|
||||
if (c >= 0x80 && c <= 0xbf) {
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
filter->cache = 0;
|
||||
CK((*filter->output_function)(s, filter->data));
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
c1 = filter->cache & 0xf;
|
||||
|
||||
if ((c >= 0x80 && c <= 0xbf) &&
|
||||
((c1 == 0x0 && c >= 0xa0) ||
|
||||
(c1 == 0xd && c < 0xa0) ||
|
||||
(c1 > 0x0 && c1 != 0xd))) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
c1 = filter->cache & 0x7;
|
||||
|
||||
if ((c >= 0x80 && c <= 0xbf) &&
|
||||
((c1 == 0x0 && c >= 0x90) ||
|
||||
(c1 == 0x4 && c < 0x90) ||
|
||||
(c1 > 0x0 && c1 != 0x4))) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x31: /* 4byte code 3rd char: 0x80-0xbf */
|
||||
if (c >= 0x80 && c <= 0xbf) {
|
||||
filter->cache = (filter->cache<<6) | (c & 0x3f);
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
filter->status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter)
|
||||
{
|
||||
int status, cache;
|
||||
|
||||
status = filter->status;
|
||||
cache = filter->cache;
|
||||
|
||||
filter->status = 0;
|
||||
filter->cache = 0;
|
||||
|
||||
if (status != 0) {
|
||||
mbfl_filt_put_invalid_char(cache, filter);
|
||||
}
|
||||
|
||||
if (filter->flush_function != NULL) {
|
||||
(*filter->flush_function)(filter->data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wchar => UTF-8
|
||||
*/
|
||||
|
@ -37,5 +37,6 @@ extern const struct mbfl_convert_vtbl vtbl_wchar_utf8;
|
||||
|
||||
int mbfl_filt_conv_utf8_wchar(int c, mbfl_convert_filter *filter);
|
||||
int mbfl_filt_conv_wchar_utf8(int c, mbfl_convert_filter *filter);
|
||||
int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter);
|
||||
|
||||
#endif /* MBFL_MBFILTER_UTF8_H */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "mbfilter_sjis_mobile.h"
|
||||
|
||||
extern int mbfl_filt_ident_utf8(int c, mbfl_identify_filter *filter);
|
||||
extern int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter);
|
||||
|
||||
extern const unsigned char mblen_table_utf8[];
|
||||
|
||||
@ -115,7 +116,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_docomo_wchar = {
|
||||
mbfl_filt_conv_common_ctor,
|
||||
mbfl_filt_conv_common_dtor,
|
||||
mbfl_filt_conv_utf8_mobile_wchar,
|
||||
mbfl_filt_conv_common_flush
|
||||
mbfl_filt_conv_utf8_wchar_flush
|
||||
};
|
||||
|
||||
const struct mbfl_convert_vtbl vtbl_wchar_utf8_docomo = {
|
||||
@ -133,7 +134,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_kddi_a_wchar = {
|
||||
mbfl_filt_conv_common_ctor,
|
||||
mbfl_filt_conv_common_dtor,
|
||||
mbfl_filt_conv_utf8_mobile_wchar,
|
||||
mbfl_filt_conv_common_flush
|
||||
mbfl_filt_conv_utf8_wchar_flush
|
||||
};
|
||||
|
||||
const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_a = {
|
||||
@ -151,7 +152,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_kddi_b_wchar = {
|
||||
mbfl_filt_conv_common_ctor,
|
||||
mbfl_filt_conv_common_dtor,
|
||||
mbfl_filt_conv_utf8_mobile_wchar,
|
||||
mbfl_filt_conv_common_flush
|
||||
mbfl_filt_conv_utf8_wchar_flush
|
||||
};
|
||||
|
||||
const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_b = {
|
||||
@ -169,7 +170,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_sb_wchar = {
|
||||
mbfl_filt_conv_common_ctor,
|
||||
mbfl_filt_conv_common_dtor,
|
||||
mbfl_filt_conv_utf8_mobile_wchar,
|
||||
mbfl_filt_conv_common_flush
|
||||
mbfl_filt_conv_utf8_wchar_flush
|
||||
};
|
||||
|
||||
const struct mbfl_convert_vtbl vtbl_wchar_utf8_sb = {
|
||||
@ -191,119 +192,97 @@ int mbfl_filt_conv_utf8_mobile_wchar(int c, mbfl_convert_filter *filter)
|
||||
int s, w = 0, flag = 0;
|
||||
int s1 = 0, c1 = 0, snd = 0;
|
||||
|
||||
if (c < 0x80) {
|
||||
if (c >= 0) {
|
||||
retry:
|
||||
switch (filter->status & 0xff) {
|
||||
case 0x00:
|
||||
if (c < 0x80) {
|
||||
CK((*filter->output_function)(c, filter->data));
|
||||
}
|
||||
filter->status = 0;
|
||||
} else if (c < 0xc0) {
|
||||
int status = filter->status & 0xff;
|
||||
switch (status) {
|
||||
case 0x10: /* 2byte code 2nd char: 0x80-0xbf */
|
||||
case 0x21: /* 3byte code 3rd char: 0x80-0xbf */
|
||||
case 0x32: /* 4byte code 4th char: 0x80-0xbf */
|
||||
filter->status = 0;
|
||||
s = filter->cache | (c & 0x3f);
|
||||
filter->cache = 0;
|
||||
if ((status == 0x10 && s >= 0x80) ||
|
||||
(status == 0x21 && s >= 0x800 && (s < 0xd800 || s > 0xdfff)) ||
|
||||
(status == 0x32 && s >= 0x10000 && s < 0x110000)) {
|
||||
|
||||
if (filter->from->no_encoding == mbfl_no_encoding_utf8_docomo &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_docomo2uni_pua, 4) > 0) {
|
||||
s = mbfilter_sjis_emoji_docomo2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_a &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_kddi2uni_pua, 7) > 0) {
|
||||
s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_b &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_kddi2uni_pua_b, 8) > 0) {
|
||||
s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_sb &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_sb2uni_pua, 6) > 0) {
|
||||
s = mbfilter_sjis_emoji_sb2unicode(s1, &snd);
|
||||
}
|
||||
|
||||
if (snd > 0) {
|
||||
CK((*filter->output_function)(snd, filter->data));
|
||||
}
|
||||
CK((*filter->output_function)(s, filter->data));
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */
|
||||
s = filter->cache | ((c & 0x3f) << 6);
|
||||
c1 = (s >> 12) & 0xf;
|
||||
if ((c1 == 0x0 && c >= 0xa0) ||
|
||||
(c1 == 0xd && c < 0xa0) ||
|
||||
(c1 > 0x0 && c1 != 0xd)) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
case 0x31: /* 4byte code 3rd char: 0x80-0xbf */
|
||||
filter->cache |= ((c & 0x3f) << 6);
|
||||
filter->status++;
|
||||
break;
|
||||
case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */
|
||||
s = filter->cache | ((c & 0x3f) << 12);
|
||||
c1 = (s >> 18) & 0x7;
|
||||
if ((c1 == 0x0 && c >= 0x90) ||
|
||||
(c1 > 0x0 && c1 < 0x4) ||
|
||||
(c1 == 0x4 && c < 0x90)) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
w = s & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
break;
|
||||
}
|
||||
} else if (c < 0xc2) { /* invalid: 0xc0,0xc1 */
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
} else if (c < 0xe0) { /* 2byte code first char: 0xc2-0xdf */
|
||||
if (filter->status == 0x0) {
|
||||
} else if (c >= 0xc2 && c <= 0xdf) { /* 2byte code first char: 0xc2-0xdf */
|
||||
filter->status = 0x10;
|
||||
filter->cache = (c & 0x1f) << 6;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
} else if (c < 0xf0) { /* 3byte code first char: 0xe0-0xef */
|
||||
if (filter->status == 0x0) {
|
||||
filter->cache = c & 0x1f;
|
||||
} else if (c >= 0xe0 && c <= 0xef) { /* 3byte code first char: 0xe0-0xef */
|
||||
filter->status = 0x20;
|
||||
filter->cache = (c & 0xf) << 12;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
} else if (c < 0xf5) { /* 4byte code first char: 0xf0-0xf4 */
|
||||
if (filter->status == 0x0) {
|
||||
filter->cache = c & 0xf;
|
||||
} else if (c >= 0xf0 && c <= 0xf4) { /* 3byte code first char: 0xf0-0xf4 */
|
||||
filter->status = 0x30;
|
||||
filter->cache = (c & 0x7) << 18;
|
||||
filter->cache = c & 0x7;
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
mbfl_filt_put_invalid_char(c, filter);
|
||||
}
|
||||
} else {
|
||||
w = c & MBFL_WCSGROUP_MASK;
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
w |= MBFL_WCSGROUP_THROUGH;
|
||||
CK((*filter->output_function)(w, filter->data));
|
||||
break;
|
||||
case 0x10: /* 2byte code 2nd char: 0x80-0xbf */
|
||||
case 0x21: /* 3byte code 3rd char: 0x80-0xbf */
|
||||
case 0x32: /* 4byte code 4th char: 0x80-0xbf */
|
||||
filter->status = 0;
|
||||
filter->cache = 0;
|
||||
if (c >= 0x80 && c <= 0xbf) {
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
filter->cache = 0;
|
||||
|
||||
if (filter->from->no_encoding == mbfl_no_encoding_utf8_docomo &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_docomo2uni_pua, 4) > 0) {
|
||||
s = mbfilter_sjis_emoji_docomo2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_a &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_kddi2uni_pua, 7) > 0) {
|
||||
s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_b &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_kddi2uni_pua_b, 8) > 0) {
|
||||
s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd);
|
||||
} else if (filter->from->no_encoding == mbfl_no_encoding_utf8_sb &&
|
||||
mbfilter_conv_r_map_tbl(s, &s1, mbfl_sb2uni_pua, 6) > 0) {
|
||||
s = mbfilter_sjis_emoji_sb2unicode(s1, &snd);
|
||||
}
|
||||
|
||||
if (snd > 0) {
|
||||
CK((*filter->output_function)(snd, filter->data));
|
||||
}
|
||||
CK((*filter->output_function)(s, filter->data));
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
c1 = filter->cache & 0xf;
|
||||
|
||||
if ((c >= 0x80 && c <= 0xbf) &&
|
||||
((c1 == 0x0 && c >= 0xa0) ||
|
||||
(c1 == 0xd && c < 0xa0) ||
|
||||
(c1 > 0x0 && c1 != 0xd))) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */
|
||||
s = (filter->cache<<6) | (c & 0x3f);
|
||||
c1 = filter->cache & 0x7;
|
||||
|
||||
if ((c >= 0x80 && c <= 0xbf) &&
|
||||
((c1 == 0x0 && c >= 0x90) ||
|
||||
(c1 == 0x4 && c < 0x90) ||
|
||||
(c1 > 0x0 && c1 != 0x4))) {
|
||||
filter->cache = s;
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
case 0x31: /* 4byte code 3rd char: 0x80-0xbf */
|
||||
if (c >= 0x80 && c <= 0xbf) {
|
||||
filter->cache = (filter->cache<<6) | (c & 0x3f);
|
||||
filter->status++;
|
||||
} else {
|
||||
mbfl_filt_put_invalid_char(filter->cache, filter);
|
||||
goto retry;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
filter->status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
|
29
ext/mbstring/tests/bug65045.phpt
Normal file
29
ext/mbstring/tests/bug65045.phpt
Normal file
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #65045: mb_convert_encoding breaks well-formed character
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
//declare(encoding = 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
$str = "\xF0\xA4\xAD". "\xF0\xA4\xAD\xA2"."\xF0\xA4\xAD\xA2";
|
||||
$expected = "\xEF\xBF\xBD"."\xF0\xA4\xAD\xA2"."\xF0\xA4\xAD\xA2";
|
||||
|
||||
$str2 = "\xF0\xA4\xAD\xA2"."\xF0\xA4\xAD\xA2"."\xF0\xA4\xAD";
|
||||
$expected2 = "\xF0\xA4\xAD\xA2"."\xF0\xA4\xAD\xA2"."\xEF\xBF\xBD";
|
||||
|
||||
mb_substitute_character(0xFFFD);
|
||||
var_dump(
|
||||
$expected === htmlspecialchars_decode(htmlspecialchars($str, ENT_SUBSTITUTE, 'UTF-8')),
|
||||
$expected2 === htmlspecialchars_decode(htmlspecialchars($str2, ENT_SUBSTITUTE, 'UTF-8')),
|
||||
$expected === mb_convert_encoding($str, 'UTF-8', 'UTF-8'),
|
||||
$expected2 === mb_convert_encoding($str2, 'UTF-8', 'UTF-8')
|
||||
);
|
||||
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
@ -1,24 +1,65 @@
|
||||
#! /bin/sh
|
||||
|
||||
if test "$2" = ""; then
|
||||
echo "usage: $0 basedir depth"
|
||||
exit 1
|
||||
if [[ "$2" = "" ]] || [[ "$3" = "" ]]; then
|
||||
echo "Usage: $0 BASE_DIRECTORY DEPTH HASH_BITS"
|
||||
echo "BASE_DIRECTORY will be created if it doesn't exist"
|
||||
echo "DEPTH must be an integer number >0"
|
||||
echo "HASH_BITS(session.hash_bits_per_charactor) should be one of 4, 5, or 6"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$2" = "0"; then
|
||||
exit 0
|
||||
if [[ "$2" = "0" ]] && [[ ! "$4" = "recurse" ]]; then
|
||||
echo "Can't create a directory tree with depth of 0, exiting."
|
||||
fi
|
||||
|
||||
if [[ "$2" = "0" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
directory="$1"
|
||||
depth="$2"
|
||||
hashbits="$3"
|
||||
|
||||
hash_chars="0 1 2 3 4 5 6 7 8 9 a b c d e f"
|
||||
if test "$3" -a "$3" -ge "5"; then
|
||||
hash_chars="$hash_chars g h i j k l m n o p q r s t u v"
|
||||
if test "$3" -eq "6"; then
|
||||
hash_chars="$hash_chars w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - ,"
|
||||
fi
|
||||
|
||||
if [[ "$hashbits" -ge "5" ]]; then
|
||||
hash_chars="$hash_chars g h i j k l m n o p q r s t u v"
|
||||
fi
|
||||
|
||||
for i in $hash_chars; do
|
||||
newpath="$1/$i"
|
||||
mkdir $newpath || exit 1
|
||||
sh $0 $newpath `expr $2 - 1` $3
|
||||
if [[ "$hashbits" -ge "6" ]]; then
|
||||
hash_chars="$hash_chars w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - ,"
|
||||
fi
|
||||
|
||||
while [[ -d $directory ]] && [[ $( ls $directory ) ]]; do
|
||||
echo "Directory $directory is not empty! What would you like to do?"
|
||||
|
||||
options="\"Delete directory contents\" \"Choose another directory\" \"Quit\""
|
||||
eval set $options
|
||||
select opt in "$@"; do
|
||||
|
||||
if [[ $opt = "Delete directory contents" ]]; then
|
||||
echo "Deleting $directory contents... "
|
||||
rm -rf $directory/*
|
||||
elif [[ $opt = "Choose another directory" ]]; then
|
||||
echo "Which directory would you like to choose?"
|
||||
read directory
|
||||
elif [[ $opt = "Quit" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
break;
|
||||
done
|
||||
done
|
||||
|
||||
if [[ ! -d $directory ]]; then
|
||||
mkdir -p $directory
|
||||
fi
|
||||
|
||||
|
||||
echo "Creating session path in $directory with a depth of $depth for session.hash_bits_per_character = $hashbits"
|
||||
|
||||
for i in $hash_chars; do
|
||||
newpath="$directory/$i"
|
||||
mkdir $newpath || exit 1
|
||||
sh $0 $newpath `expr $depth - 1` $hashbits recurse
|
||||
done
|
||||
|
@ -618,6 +618,31 @@ static PHP_INI_MH(OnUpdateSaveDir) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static PHP_INI_MH(OnUpdateName) /* {{{ */
|
||||
{
|
||||
/* Numeric session.name won't work at all */
|
||||
if (PG(modules_activated) &&
|
||||
(!new_value_length || is_numeric_string(new_value, new_value_length, NULL, NULL, 0))) {
|
||||
int err_type;
|
||||
|
||||
if (stage == ZEND_INI_STAGE_RUNTIME) {
|
||||
err_type = E_WARNING;
|
||||
} else {
|
||||
err_type = E_ERROR;
|
||||
}
|
||||
|
||||
/* Do not output error when restoring ini options. */
|
||||
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
|
||||
php_error_docref(NULL TSRMLS_CC, err_type, "session.name cannot be a numeric or empty '%s'", new_value);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
OnUpdateStringUnempty(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static PHP_INI_MH(OnUpdateHashFunc) /* {{{ */
|
||||
{
|
||||
long val;
|
||||
@ -709,7 +734,7 @@ static ZEND_INI_MH(OnUpdateSmartStr) /* {{{ */
|
||||
*/
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir,save_path, php_ps_globals, ps_globals)
|
||||
STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateString, session_name, php_ps_globals, ps_globals)
|
||||
STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals)
|
||||
PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler)
|
||||
STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_ALL, OnUpdateBool, auto_start, php_ps_globals, ps_globals)
|
||||
STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateLong, gc_probability, php_ps_globals, ps_globals)
|
||||
|
@ -86,7 +86,7 @@ $inputs = array(
|
||||
$iterator = 1;
|
||||
foreach($inputs as $input) {
|
||||
echo "\n-- Iteration $iterator --\n";
|
||||
var_dump(session_name($input));
|
||||
var_dump($input, session_name($input));
|
||||
$iterator++;
|
||||
};
|
||||
|
||||
@ -98,77 +98,139 @@ ob_end_flush();
|
||||
*** Testing session_name() : error functionality ***
|
||||
|
||||
-- Iteration 1 --
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '0' in %s on line %d
|
||||
int(0)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 2 --
|
||||
string(1) "0"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '1' in %s on line %d
|
||||
int(1)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 3 --
|
||||
string(1) "1"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '12345' in %s on line %d
|
||||
int(12345)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 4 --
|
||||
string(5) "12345"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '-2345' in %s on line %d
|
||||
int(-2345)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 5 --
|
||||
string(5) "-2345"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '10.5' in %s on line %d
|
||||
float(10.5)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 6 --
|
||||
string(4) "10.5"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '-10.5' in %s on line %d
|
||||
float(-10.5)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 7 --
|
||||
string(5) "-10.5"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '123456789000' in %s on line %d
|
||||
float(123456789000)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 8 --
|
||||
string(12) "123456789000"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '1.23456789E-9' in %s on line %d
|
||||
float(1.23456789E-9)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 9 --
|
||||
string(13) "1.23456789E-9"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '0.5' in %s on line %d
|
||||
float(0.5)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 10 --
|
||||
string(3) "0.5"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
NULL
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 11 --
|
||||
string(0) ""
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
NULL
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 12 --
|
||||
string(0) ""
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '1' in %s on line %d
|
||||
bool(true)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 13 --
|
||||
string(1) "1"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
bool(false)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 14 --
|
||||
string(0) ""
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '1' in %s on line %d
|
||||
bool(true)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 15 --
|
||||
string(1) "1"
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
bool(false)
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 16 --
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
string(0) ""
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 17 --
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
string(0) ""
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 18 --
|
||||
string(0) ""
|
||||
string(7) "Nothing"
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
-- Iteration 19 --
|
||||
string(7) "Nothing"
|
||||
string(7) "Nothing"
|
||||
|
||||
-- Iteration 20 --
|
||||
string(12) "Hello World!"
|
||||
string(7) "Nothing"
|
||||
|
||||
-- Iteration 21 --
|
||||
object(classA)#1 (0) {
|
||||
}
|
||||
string(12) "Hello World!"
|
||||
|
||||
-- Iteration 22 --
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
NULL
|
||||
string(12) "Hello World!"
|
||||
|
||||
-- Iteration 23 --
|
||||
string(0) ""
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
NULL
|
||||
string(12) "Hello World!"
|
||||
|
||||
-- Iteration 24 --
|
||||
|
||||
Warning: session_name() expects parameter 1 to be string, resource given in %s on line %d
|
||||
resource(5) of type (stream)
|
||||
NULL
|
||||
Done
|
||||
|
||||
Done
|
@ -43,18 +43,20 @@ ob_end_flush();
|
||||
*** Testing session_name() : variation ***
|
||||
string(9) "PHPSESSID"
|
||||
bool(true)
|
||||
string(0) ""
|
||||
string(9) "PHPSESSID"
|
||||
bool(true)
|
||||
string(0) ""
|
||||
string(0) ""
|
||||
string(9) "PHPSESSID"
|
||||
string(9) "PHPSESSID"
|
||||
bool(true)
|
||||
string(1) " "
|
||||
bool(true)
|
||||
string(1) " "
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
string(1) " "
|
||||
bool(true)
|
||||
string(0) ""
|
||||
string(1) " "
|
||||
bool(true)
|
||||
string(0) ""
|
||||
string(1) " "
|
||||
Done
|
||||
|
||||
|
@ -1955,7 +1955,11 @@ consult the installation file that came with this distribution, or visit \n\
|
||||
}
|
||||
|
||||
if (bindpath) {
|
||||
fcgi_fd = fcgi_listen(bindpath, 128);
|
||||
int backlog = 128;
|
||||
if (getenv("PHP_FCGI_BACKLOG")) {
|
||||
backlog = atoi(getenv("PHP_FCGI_BACKLOG"));
|
||||
}
|
||||
fcgi_fd = fcgi_listen(bindpath, backlog);
|
||||
if (fcgi_fd < 0) {
|
||||
fprintf(stderr, "Couldn't create FastCGI listen socket on port %s\n", bindpath);
|
||||
#ifdef ZTS
|
||||
|
Loading…
Reference in New Issue
Block a user