From 0baaf9fade6f4ef1b2da824cac76bb78ff798611 Mon Sep 17 00:00:00 2001 From: George Wang Date: Fri, 11 Jul 2014 14:31:59 -0400 Subject: [PATCH 1/8] Fixed a bug that cannot access custom request header stored in apache_request_headers() though array index. --- sapi/litespeed/lsapilib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 92c169f4f5a..786a3bd20b2 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1945,6 +1945,7 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; + *(pKey + keyLen ) = 0; pValue = pReq->m_pHttpHeader + pCur->valueOff; *(pValue + pCur->valueLen ) = 0; From 9f721967a329387bf73c0d5bebe9578ba772601e Mon Sep 17 00:00:00 2001 From: George Wang Date: Fri, 11 Jul 2014 14:31:59 -0400 Subject: [PATCH 2/8] Fixed a bug that cannot access custom request header stored in apache_request_headers() though array index. --- sapi/litespeed/lsapilib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 92c169f4f5a..786a3bd20b2 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1945,6 +1945,7 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; + *(pKey + keyLen ) = 0; pValue = pReq->m_pHttpHeader + pCur->valueOff; *(pValue + pCur->valueLen ) = 0; From 79d8be35f9053b09708f88d7a0b6b4e9af05b892 Mon Sep 17 00:00:00 2001 From: George Wang Date: Fri, 11 Jul 2014 14:31:59 -0400 Subject: [PATCH 3/8] Fixed a bug that cannot access custom request header stored in apache_request_headers() though array index. --- sapi/litespeed/lsapilib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 92c169f4f5a..786a3bd20b2 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1945,6 +1945,7 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; + *(pKey + keyLen ) = 0; pValue = pReq->m_pHttpHeader + pCur->valueOff; *(pValue + pCur->valueLen ) = 0; From ca8c94c917cb46983da681eec2cf6b17d22c5d5f Mon Sep 17 00:00:00 2001 From: George Wang Date: Fri, 11 Jul 2014 14:57:55 -0400 Subject: [PATCH 4/8] fixed broken merged code --- sapi/litespeed/lsapilib.c | 184 -------------------------------------- sapi/litespeed/lsapilib.h | 7 -- 2 files changed, 191 deletions(-) diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 1df2326ffe3..786a3bd20b2 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -868,190 +868,6 @@ static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * p #endif return 0; } -#endif - - -static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * pChroot) -{ - int rv; - struct passwd * pw; - pw = getpwuid( uid ); -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) - if ( s_lve ) - { - if( lsapi_enterLVE( pReq, uid ) == -1 ) - return -1; - if ( pw && fp_lve_jail) - { - rv = lsapi_jailLVE( pReq, uid, pw ); - if ( rv == -1 ) - return -1; - if (( rv == 1 )&&(s_enable_lve == LSAPI_CAGEFS_NO_SUEXEC )) //this mode only use cageFS, does not use suEXEC - { - uid = s_defaultUid; - gid = s_defaultGid; - pw = getpwuid( uid ); - } - } - } -#endif - //if ( !uid || !gid ) //do not allow root - //{ - // return -1; - //} - -#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ - || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - if ( s_enable_core_dump ) - lsapi_enable_core_dump(); -#endif - - rv = setgid(gid); - if (rv == -1) - { - LSAPI_perror_r(pReq, "LSAPI: setgid()", NULL); - return -1; - } - if ( pw && (pw->pw_gid == gid )) - { - rv = initgroups( pw->pw_name, gid ); - if (rv == -1) - { - LSAPI_perror_r(pReq, "LSAPI: initgroups()", NULL); - return -1; - } - } - else - { - rv = setgroups(1, &gid); - if (rv == -1) - { - LSAPI_perror_r(pReq, "LSAPI: setgroups()", NULL); - } - } - if ( pChroot ) - { - rv = chroot( pChroot ); - if ( rv == -1 ) - { - LSAPI_perror_r(pReq, "LSAPI: chroot()", NULL); - return -1; - } - } - rv = setuid(uid); - if (rv == -1) - { - LSAPI_perror_r(pReq, "LSAPI: setuid()", NULL); - return -1; - } -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) - if ( s_enable_core_dump ) - lsapi_enable_core_dump(); -#endif - return 0; -} - -static int lsapi_suexec_auth( LSAPI_Request *pReq, - char * pAuth, int len, char * pUgid, int ugidLen ) -{ - lsapi_MD5_CTX md5ctx; - unsigned char achMD5[16]; - if ( len < 32 ) - return -1; - memmove( achMD5, pAuth + 16, 16 ); - memmove( pAuth + 16, s_pSecret, 16 ); - lsapi_MD5Init( &md5ctx ); - lsapi_MD5Update( &md5ctx, (unsigned char *)pAuth, 32 ); - lsapi_MD5Update( &md5ctx, (unsigned char *)pUgid, 8 ); - lsapi_MD5Final( (unsigned char *)pAuth + 16, &md5ctx); - if ( memcmp( achMD5, pAuth + 16, 16 ) == 0 ) - return 0; - return 1; -} - - -static int lsapi_changeUGid( LSAPI_Request * pReq ) -{ - int uid = s_defaultUid; - int gid = s_defaultGid; - const char * pChroot = NULL; - struct LSAPI_key_value_pair * pEnv; - struct LSAPI_key_value_pair * pAuth; - int i; - if ( s_uid ) - return 0; - //with special ID 0x00 - //authenticate the suEXEC request; - //first one should be MD5( nonce + lscgid secret ) - //remember to clear the secret after verification - //it should be set at the end of special env - i = pReq->m_pHeader->m_cntSpecialEnv - 1; - if ( i >= 0 ) - { - pEnv = pReq->m_pSpecialEnvList + i; - if (( *pEnv->pKey == '\000' )&& - ( strcmp( pEnv->pKey+1, "SUEXEC_AUTH" ) == 0 )) - { - --pReq->m_pHeader->m_cntSpecialEnv; - pAuth = pEnv--; - if (( *pEnv->pKey == '\000' )&& - ( strcmp( pEnv->pKey+1, "SUEXEC_UGID" ) == 0 )) - { - --pReq->m_pHeader->m_cntSpecialEnv; - uid = *(uint32_t *)pEnv->pValue; - gid = *(((uint32_t *)pEnv->pValue) + 1 ); - //fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid ); - } - else - { - fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" ); - pEnv = NULL; - } - if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 ) - { - //read UID, GID from specialEnv - - } - else - { - //authentication error - fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" ); - uid = 0; - } - } - else - { - //fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" ); - } - } - - - if ( !uid ) - { - uid = s_defaultUid; - gid = s_defaultGid; - } - - //change uid - if ( setUID_LVE( pReq, uid, gid, pChroot ) == -1 ) - { - return -1; - } - - s_uid = uid; - - return 0; - -} - -static int parseContentLenFromHeader(LSAPI_Request * pReq) -{ - const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH ); - if ( pContentLen ) - pReq->m_reqBodyLen = strtoll( pContentLen, NULL, 10 ); - return 0; -} - static int lsapi_suexec_auth( LSAPI_Request *pReq, char * pAuth, int len, char * pUgid, int ugidLen ) diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h index 02543ef1a63..cae1863c792 100644 --- a/sapi/litespeed/lsapilib.h +++ b/sapi/litespeed/lsapilib.h @@ -48,13 +48,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/*************************************************************************** - lsapilib.h - description - ------------------- - begin : Mon Feb 21 2005 - copyright : (C) 2005 by George Wang - email : gwang@litespeedtech.com - ***************************************************************************/ #ifndef _LSAPILIB_H_ #define _LSAPILIB_H_ From 4fc0d46ae72de2b009357091b4e62eafd0f1e8a5 Mon Sep 17 00:00:00 2001 From: Tjerk Meesters Date: Wed, 2 Jul 2014 22:22:11 +0800 Subject: [PATCH 5/8] Fix for bug #34407 - ucwords and title case Added support for ranges like trim() has --- ext/standard/basic_functions.c | 3 ++- ext/standard/string.c | 11 +++++--- ext/standard/tests/strings/ucwords_error.phpt | 6 ++--- .../tests/strings/ucwords_variation5.phpt | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 ext/standard/tests/strings/ucwords_variation5.phpt diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 4d4354d4ad6..9a9df3094be 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2309,8 +2309,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_lcfirst, 0) ZEND_ARG_INFO(0, str) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_ucwords, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_ucwords, 0, 0, 1) ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(0, delimiters) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_strtr, 0, 0, 2) diff --git a/ext/standard/string.c b/ext/standard/string.c index 22b1957f1e0..7bc21598712 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2742,11 +2742,12 @@ PHP_FUNCTION(lcfirst) Uppercase the first character of every word in a string */ PHP_FUNCTION(ucwords) { - char *str; + char *str, *delims = " \t\r\n\f\v"; register char *r, *r_end; - int str_len; + int str_len, delims_len = 6; + char mask[256]; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &delims, &delims_len) == FAILURE) { return; } @@ -2754,12 +2755,14 @@ PHP_FUNCTION(ucwords) RETURN_EMPTY_STRING(); } + php_charmask((unsigned char *)delims, delims_len, mask TSRMLS_CC); + ZVAL_STRINGL(return_value, str, str_len, 1); r = Z_STRVAL_P(return_value); *r = toupper((unsigned char) *r); for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) { - if (isspace((int) *(unsigned char *)r++)) { + if (mask[(unsigned char)*r++]) { *r = toupper((unsigned char) *r); } } diff --git a/ext/standard/tests/strings/ucwords_error.phpt b/ext/standard/tests/strings/ucwords_error.phpt index d79e569cc7b..a01c688c4a5 100644 --- a/ext/standard/tests/strings/ucwords_error.phpt +++ b/ext/standard/tests/strings/ucwords_error.phpt @@ -18,7 +18,7 @@ echo "\n-- Testing ucwords() function with more than expected no. of arguments - $str = 'string_val'; $extra_arg = 10; -var_dump( ucwords($str, $extra_arg) ); +var_dump( ucwords($str, $extra_arg, $extra_arg) ); // check if there were any changes made to $str var_dump($str); @@ -30,12 +30,12 @@ echo "Done\n"; -- Testing ucwords() function with Zero arguments -- -Warning: ucwords() expects exactly 1 parameter, 0 given in %s on line %d +Warning: ucwords() expects at least 1 parameter, 0 given in %s on line %d NULL -- Testing ucwords() function with more than expected no. of arguments -- -Warning: ucwords() expects exactly 1 parameter, 2 given in %s on line %d +Warning: ucwords() expects at most 2 parameters, 3 given in %s on line %d NULL string(10) "string_val" Done diff --git a/ext/standard/tests/strings/ucwords_variation5.phpt b/ext/standard/tests/strings/ucwords_variation5.phpt new file mode 100644 index 00000000000..985df47c4ab --- /dev/null +++ b/ext/standard/tests/strings/ucwords_variation5.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test ucwords() function : usage variations - custom delimiters +--FILE-- + +--EXPECTF-- +*** Testing ucwords() : usage variations *** +string(%d) "Testing-Dashed-Words" +string(%d) "Test(Braced)Words" +string(%d) "Testing empty delimiters" +string(%d) "TeSting raNgeS" +Done From f25ff02b54ac2dc161df91569ce0a396d59e5a4d Mon Sep 17 00:00:00 2001 From: Tjerk Meesters Date: Sat, 12 Jul 2014 11:07:06 +0800 Subject: [PATCH 6/8] Updated NEWS for 34407 --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 20d4f30b5f1..fd58bd62a32 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS . Fixed bug #67151 (strtr with empty array crashes). (Nikita) . Fixed bug #67407 (Windows 8.1/Server 2012 R2 reported as Windows 8/Server 2012). (Christian Wenz) + . Implemented FR #34407 (ucwords and Title Case). (Tjerk) - CLI server: . Implemented FR #67429 (CLI server is missing some new HTTP response codes). From 377750cd8f9618498d05c0ac7a79b05a5c6794d4 Mon Sep 17 00:00:00 2001 From: Tjerk Meesters Date: Sat, 12 Jul 2014 11:09:35 +0800 Subject: [PATCH 7/8] Updated NEWS for 34407 --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index bd76438534e..7ab2d29493e 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ PHP NEWS . Fixed bug #67151 (strtr with empty array crashes). (Nikita) . Fixed bug #67407 (Windows 8.1/Server 2012 R2 reported as Windows 8/Server 2012). (Christian Wenz) + . Implemented FR #34407 (ucwords and Title Case). (Tjerk) - CLI server: . Implemented FR #67429 (CLI server is missing some new HTTP response codes). From c3f5e2a1f9d309fdb684ea0e4ac40d881435fde9 Mon Sep 17 00:00:00 2001 From: Tjerk Meesters Date: Sat, 12 Jul 2014 11:14:18 +0800 Subject: [PATCH 8/8] Updated NEWS for 34407 --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index a2c7a22f089..4fec6bd2e84 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PHP NEWS . Fixed bug #67151 (strtr with empty array crashes). (Nikita) . Fixed bug #67407 (Windows 8.1/Server 2012 R2 reported as Windows 8/Server 2012). (Christian Wenz) + . Implemented FR #34407 (ucwords and Title Case). (Tjerk) - CLI server: . Fixed bug #66830 (Empty header causes PHP built-in web server to hang).