summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Jones <sixd@php.net>2013-07-01 13:45:41 -0700
committerChristopher Jones <sixd@php.net>2013-07-01 13:45:41 -0700
commit06418aca285945253a5f558781c8151cd161327c (patch)
treee210e5a0abba4b1da1892fef60a9d522da83e78d
parent8cb782bbcebf9ac0af7f5286e9a64a43f0486097 (diff)
parent46214a23b8152179b5c8b3b74986ede1400ed809 (diff)
downloadphp-git-06418aca285945253a5f558781c8151cd161327c.tar.gz
Merge branch 'PHP-5.4' of https://git.php.net/repository/php-src into PHP-5.4
# By Stanislav Malyshev (3) and others # Via Stanislav Malyshev (1) and Yasuo Ohgaki (1) * 'PHP-5.4' of https://git.php.net/repository/php-src: Update NEWS Fixed bug #35703: when session_name("123") consist only digits, should warning 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 small optimization fix bug #61860: use USearch for searches, it does the right thing
-rw-r--r--NEWS10
-rwxr-xr-xUPGRADING3
-rw-r--r--ext/intl/grapheme/grapheme_string.c18
-rw-r--r--ext/intl/grapheme/grapheme_util.c388
-rw-r--r--ext/intl/grapheme/grapheme_util.h24
-rw-r--r--ext/intl/tests/bug61860.phpt18
-rw-r--r--ext/session/mod_files.sh67
-rw-r--r--ext/session/session.c27
-rw-r--r--ext/session/tests/session_name_error.phpt100
-rw-r--r--ext/session/tests/session_name_variation1.phpt12
-rw-r--r--ext/spl/spl_fixedarray.c33
-rw-r--r--ext/spl/tests/SplFixedArray_serialize.phpt52
12 files changed, 376 insertions, 376 deletions
diff --git a/NEWS b/NEWS
index 8a209b5eff..094ce8aaee 100644
--- a/NEWS
+++ b/NEWS
@@ -27,7 +27,9 @@ PHP NEWS
(askalski at gmail dot com)
- Intl:
- . Fixed bug #62759: Buggy grapheme_substr() on edge case. (Stas)
+ . Fixed bug #62759 (Buggy grapheme_substr() on edge case). (Stas)
+ . Fixed bug #61860 (Offsets may be wrong for grapheme_stri* functions).
+ (Stas)
- ODBC:
. Fixed bug #61387 (NULL valued anonymous column causes segfault in
@@ -40,6 +42,10 @@ PHP NEWS
- Session
. Fixed bug #62535 ($_SESSION[$key]["cancel_upload"] doesn't work as
documented). (Arpad)
+ . Fixed bug #35703 (when session_name("123") consist only digits,
+ should warning). (Yasuo)
+ . Fixed bug #49175 (mod_files.sh does not support hash bits). Patch by
+ oorza2k5 at gmail dot com (Yasuo)
- Sockets:
. Implemented FR #63472 (Setting SO_BINDTODEVICE with socket_set_option).
@@ -49,6 +55,8 @@ PHP NEWS
. Fixed bug #65136 (RecursiveDirectoryIterator segfault). (Laruence)
. Fixed bug #61828 (Memleak when calling Directory(Recursive)Iterator
/Spl(Temp)FileObject ctor twice). (Laruence)
+ . Fixed bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0,
+ keys are strings). (Adam)
?? ??? 2013, PHP 5.4.17
diff --git a/UPGRADING b/UPGRADING
index 0293a6a660..e6f582a4a8 100755
--- a/UPGRADING
+++ b/UPGRADING
@@ -640,6 +640,9 @@ c. New functions
- SPL
- class_uses()
+ - SplFixedArray
+ - SplFixedArray::__wakeup() (5.4.18)
+
d. New global constants
- CURLOPT_MAX_RECV_SPEED_LARGE
diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c
index 1b7327e001..8a094e015e 100644
--- a/ext/intl/grapheme/grapheme_string.c
+++ b/ext/intl/grapheme/grapheme_string.c
@@ -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;
diff --git a/ext/intl/grapheme/grapheme_util.c b/ext/intl/grapheme/grapheme_util.c
index 92008554d4..883fa0391a 100644
--- a/ext/intl/grapheme/grapheme_util.c
+++ b/ext/intl/grapheme/grapheme_util.c
@@ -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,225 +107,101 @@ 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 );
- }
- if (uneedle) {
- efree( uneedle );
+#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; \
}
- 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;
- }
+ 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");
/* 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));
+ 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");
- 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;
- }
+ 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 ) {
- grapheme_intl_case_fold(&uhaystack, &puhaystack, &uhaystack_len, &status );
+ 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);
}
- uneedle = NULL;
- uneedle_len = 0;
- status = U_ZERO_ERROR;
- intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, (char *) needle, needle_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");
+ }
- 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(last) {
+ char_pos = usearch_last(src, &status);
+ if(char_pos < offset_pos) {
+ /* last one is beyound our start offset */
+ char_pos = USEARCH_DONE;
}
- if (uneedle) {
- efree( uneedle );
- }
- ubrk_close (bi);
-
- return -1;
+ } else {
+ char_pos = usearch_next(src, &status);
}
-
- if ( f_ignore_case ) {
- grapheme_intl_case_fold(&uneedle, &uneedle, &uneedle_len, &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;
}
- ret_pos = grapheme_memnstr_grapheme(bi, puhaystack, uneedle, uneedle_len, puhaystack + uhaystack_len );
-
- *puchar_pos = ubrk_current(bi);
-
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;
diff --git a/ext/intl/grapheme/grapheme_util.h b/ext/intl/grapheme/grapheme_util.h
index c91aeaff7d..14f3f22c45 100644
--- a/ext/intl/grapheme/grapheme_util.h
+++ b/ext/intl/grapheme/grapheme_util.h
@@ -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) )
diff --git a/ext/intl/tests/bug61860.phpt b/ext/intl/tests/bug61860.phpt
new file mode 100644
index 0000000000..123d9ff239
--- /dev/null
+++ b/ext/intl/tests/bug61860.phpt
@@ -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"
diff --git a/ext/session/mod_files.sh b/ext/session/mod_files.sh
index 1d2672847c..4fc4f20f7f 100644
--- a/ext/session/mod_files.sh
+++ b/ext/session/mod_files.sh
@@ -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
+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="$1/$i"
- mkdir $newpath || exit 1
- sh $0 $newpath `expr $2 - 1` $3
+ newpath="$directory/$i"
+ mkdir $newpath || exit 1
+ sh $0 $newpath `expr $depth - 1` $hashbits recurse
done
diff --git a/ext/session/session.c b/ext/session/session.c
index a130947419..3879edcce6 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -615,6 +615,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;
@@ -706,7 +731,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)
diff --git a/ext/session/tests/session_name_error.phpt b/ext/session/tests/session_name_error.phpt
index 2ed10d92a2..1b99d4ea35 100644
--- a/ext/session/tests/session_name_error.phpt
+++ b/ext/session/tests/session_name_error.phpt
@@ -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 \ No newline at end of file
diff --git a/ext/session/tests/session_name_variation1.phpt b/ext/session/tests/session_name_variation1.phpt
index 16d6ad462c..b0de3ee361 100644
--- a/ext/session/tests/session_name_variation1.phpt
+++ b/ext/session/tests/session_name_variation1.phpt
@@ -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
diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c
index ebc4e341a6..fec7e2c4ac 100644
--- a/ext/spl/spl_fixedarray.c
+++ b/ext/spl/spl_fixedarray.c
@@ -604,6 +604,38 @@ SPL_METHOD(SplFixedArray, __construct)
}
/* }}} */
+/* {{{ proto void SplFixedArray::__wakeup()
+*/
+SPL_METHOD(SplFixedArray, __wakeup)
+{
+ spl_fixedarray_object *intern = (spl_fixedarray_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+ HashPosition ptr;
+ HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
+ zval **data;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
+ return;
+ }
+
+ if (!intern->array) {
+ int index = 0;
+ int size = zend_hash_num_elements(intern_ht);
+
+ intern->array = emalloc(sizeof(spl_fixedarray));
+ spl_fixedarray_init(intern->array, size TSRMLS_CC);
+
+ for (zend_hash_internal_pointer_reset_ex(intern_ht, &ptr); zend_hash_get_current_data_ex(intern_ht, (void **) &data, &ptr) == SUCCESS; zend_hash_move_forward_ex(intern_ht, &ptr)) {
+ Z_ADDREF_PP(data);
+ intern->array->elements[index++] = *data;
+ }
+
+ /* Remove the unserialised properties, since we now have the elements
+ * within the spl_fixedarray_object structure. */
+ zend_hash_clean(intern_ht);
+ }
+}
+/* }}} */
+
/* {{{ proto int SplFixedArray::count(void)
*/
SPL_METHOD(SplFixedArray, count)
@@ -1086,6 +1118,7 @@ ZEND_END_ARG_INFO()
static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
SPL_ME(SplFixedArray, __construct, arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC)
+ SPL_ME(SplFixedArray, __wakeup, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, count, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, toArray, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
SPL_ME(SplFixedArray, fromArray, arginfo_fixedarray_fromArray, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
diff --git a/ext/spl/tests/SplFixedArray_serialize.phpt b/ext/spl/tests/SplFixedArray_serialize.phpt
new file mode 100644
index 0000000000..f99812ecce
--- /dev/null
+++ b/ext/spl/tests/SplFixedArray_serialize.phpt
@@ -0,0 +1,52 @@
+--TEST--
+SplFixedArray serialisation
+--FILE--
+<?php
+
+$array = new SplFixedArray(5);
+
+$obj = new stdClass;
+$obj->prop = 'value';
+
+$array[0] = 'foo';
+$array[2] = 42;
+$array[3] = $obj;
+$array[4] = range(1, 5);
+
+$ser = serialize($array);
+echo "$ser\n";
+$unser = unserialize($ser);
+
+printf("count: %d\n", count($unser));
+printf("getSize(): %d\n", $unser->getSize());
+
+var_dump($unser[0], $unser[1], $unser[2], $unser[3], $unser[4]);
+
+$unser[4] = 'quux';
+var_dump($unser[4]);
+
+?>
+--EXPECT--
+O:13:"SplFixedArray":5:{i:0;s:3:"foo";i:1;N;i:2;i:42;i:3;O:8:"stdClass":1:{s:4:"prop";s:5:"value";}i:4;a:5:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;}}
+count: 5
+getSize(): 5
+string(3) "foo"
+NULL
+int(42)
+object(stdClass)#4 (1) {
+ ["prop"]=>
+ string(5) "value"
+}
+array(5) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+ [3]=>
+ int(4)
+ [4]=>
+ int(5)
+}
+string(4) "quux"