diff options
| author | Ondřej Surý <ondrej@sury.org> | 2014-08-25 11:37:32 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2014-08-25 11:37:32 +0200 |
| commit | 4b01785e700724da58ab36336a92a44c5d8246a8 (patch) | |
| tree | 94beaa316d16d2a191164f26efc78b3a744718d0 /ext/standard | |
| parent | 66921ccd8c83bce7c509b6f005951c2fac8fbb80 (diff) | |
| download | php-upstream/5.4.32.tar.gz | |
New upstream version 5.4.32upstream/5.4.32
Diffstat (limited to 'ext/standard')
| -rw-r--r-- | ext/standard/array.c | 2 | ||||
| -rw-r--r-- | ext/standard/basic_functions.c | 3 | ||||
| -rw-r--r-- | ext/standard/dns.c | 84 | ||||
| -rw-r--r-- | ext/standard/info.c | 8 | ||||
| -rw-r--r-- | ext/standard/string.c | 11 | ||||
| -rw-r--r-- | ext/standard/tests/array/bug67693.phpt | 25 | ||||
| -rw-r--r-- | ext/standard/tests/strings/ucwords_error.phpt | 6 | ||||
| -rw-r--r-- | ext/standard/tests/strings/ucwords_variation5.phpt | 25 |
8 files changed, 131 insertions, 33 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index c2efca58f..06cac0e64 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2020,7 +2020,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end) if (should_rehash) { zend_hash_rehash(Z_ARRVAL_P(stack)); } - } else if (!key_len && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) { + } else if (!key_len && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) { Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1; } diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 4d4354d4a..9a9df3094 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/dns.c b/ext/standard/dns.c index 214a7dc7e..0b5e69ca5 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -412,8 +412,14 @@ PHP_FUNCTION(dns_check_record) #if HAVE_FULL_DNS_FUNCS +#define CHECKCP(n) do { \ + if (cp + n > end) { \ + return NULL; \ + } \ +} while (0) + /* {{{ php_parserr */ -static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, int raw, zval **subarray) +static u_char *php_parserr(u_char *cp, u_char *end, querybuf *answer, int type_to_fetch, int store, int raw, zval **subarray) { u_short type, class, dlen; u_long ttl; @@ -425,16 +431,18 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int *subarray = NULL; - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, sizeof(name) - 2); + n = dn_expand(answer->qb2, end, cp, name, sizeof(name) - 2); if (n < 0) { return NULL; } cp += n; + CHECKCP(10); GETSHORT(type, cp); GETSHORT(class, cp); GETLONG(ttl, cp); GETSHORT(dlen, cp); + CHECKCP(dlen); if (type_to_fetch != T_ANY && type != type_to_fetch) { cp += dlen; return cp; @@ -461,12 +469,14 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int switch (type) { case DNS_T_A: + CHECKCP(4); add_assoc_string(*subarray, "type", "A", 1); snprintf(name, sizeof(name), "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]); add_assoc_string(*subarray, "ip", name, 1); cp += dlen; break; case DNS_T_MX: + CHECKCP(2); add_assoc_string(*subarray, "type", "MX", 1); GETSHORT(n, cp); add_assoc_long(*subarray, "pri", n); @@ -485,7 +495,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int if (type == DNS_T_PTR) { add_assoc_string(*subarray, "type", "PTR", 1); } - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2); + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } @@ -495,18 +505,22 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int case DNS_T_HINFO: /* See RFC 1010 for values */ add_assoc_string(*subarray, "type", "HINFO", 1); + CHECKCP(1); n = *cp & 0xFF; cp++; + CHECKCP(n); add_assoc_stringl(*subarray, "cpu", (char*)cp, n, 1); cp += n; + CHECKCP(1); n = *cp & 0xFF; cp++; + CHECKCP(n); add_assoc_stringl(*subarray, "os", (char*)cp, n, 1); cp += n; break; case DNS_T_TXT: { - int ll = 0; + int l1 = 0, l2 = 0; zval *entries = NULL; add_assoc_string(*subarray, "type", "TXT", 1); @@ -515,37 +529,41 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int MAKE_STD_ZVAL(entries); array_init(entries); - while (ll < dlen) { - n = cp[ll]; - if ((ll + n) >= dlen) { + while (l1 < dlen) { + n = cp[l1]; + if ((l1 + n) >= dlen) { // Invalid chunk length, truncate - n = dlen - (ll + 1); + n = dlen - (l1 + 1); + } + if (n) { + memcpy(tp + l2 , cp + l1 + 1, n); + add_next_index_stringl(entries, cp + l1 + 1, n, 1); } - memcpy(tp + ll , cp + ll + 1, n); - add_next_index_stringl(entries, cp + ll + 1, n, 1); - ll = ll + n + 1; + l1 = l1 + n + 1; + l2 = l2 + n; } - tp[dlen] = '\0'; + tp[l2] = '\0'; cp += dlen; - add_assoc_stringl(*subarray, "txt", tp, (dlen>0)?dlen - 1:0, 0); + add_assoc_stringl(*subarray, "txt", tp, l2, 0); add_assoc_zval(*subarray, "entries", entries); } break; case DNS_T_SOA: add_assoc_string(*subarray, "type", "SOA", 1); - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) -2); + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2); if (n < 0) { return NULL; } cp += n; add_assoc_string(*subarray, "mname", name, 1); - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) -2); + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2); if (n < 0) { return NULL; } cp += n; add_assoc_string(*subarray, "rname", name, 1); + CHECKCP(5*4); GETLONG(n, cp); add_assoc_long(*subarray, "serial", n); GETLONG(n, cp); @@ -559,6 +577,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int break; case DNS_T_AAAA: tp = (u_char*)name; + CHECKCP(8*2); for(i=0; i < 8; i++) { GETSHORT(s, cp); if (s != 0) { @@ -593,6 +612,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int case DNS_T_A6: p = cp; add_assoc_string(*subarray, "type", "A6", 1); + CHECKCP(1); n = ((int)cp[0]) & 0xFF; cp++; add_assoc_long(*subarray, "masklen", n); @@ -628,6 +648,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int cp++; } for (i = (n + 8) / 16; i < 8; i++) { + CHECKCP(2); GETSHORT(s, cp); if (s != 0) { if (tp > (u_char *)name) { @@ -657,7 +678,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int tp[0] = '\0'; add_assoc_string(*subarray, "ipv6", name, 1); if (cp < p + dlen) { - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2); + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } @@ -666,6 +687,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int } break; case DNS_T_SRV: + CHECKCP(3*2); add_assoc_string(*subarray, "type", "SRV", 1); GETSHORT(n, cp); add_assoc_long(*subarray, "pri", n); @@ -673,7 +695,7 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int add_assoc_long(*subarray, "weight", n); GETSHORT(n, cp); add_assoc_long(*subarray, "port", n); - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2); + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } @@ -681,21 +703,35 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int add_assoc_string(*subarray, "target", name, 1); break; case DNS_T_NAPTR: + CHECKCP(2*2); add_assoc_string(*subarray, "type", "NAPTR", 1); GETSHORT(n, cp); add_assoc_long(*subarray, "order", n); GETSHORT(n, cp); add_assoc_long(*subarray, "pref", n); + + CHECKCP(1); n = (cp[0] & 0xFF); - add_assoc_stringl(*subarray, "flags", (char*)++cp, n, 1); + cp++; + CHECKCP(n); + add_assoc_stringl(*subarray, "flags", (char*)cp, n, 1); cp += n; + + CHECKCP(1); n = (cp[0] & 0xFF); - add_assoc_stringl(*subarray, "services", (char*)++cp, n, 1); + cp++; + CHECKCP(n); + add_assoc_stringl(*subarray, "services", (char*)cp, n, 1); cp += n; + + CHECKCP(1); n = (cp[0] & 0xFF); - add_assoc_stringl(*subarray, "regex", (char*)++cp, n, 1); + cp++; + CHECKCP(n); + add_assoc_stringl(*subarray, "regex", (char*)cp, n, 1); cp += n; - n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2); + + n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } @@ -888,7 +924,7 @@ PHP_FUNCTION(dns_get_record) while (an-- && cp && cp < end) { zval *retval; - cp = php_parserr(cp, &answer, type_to_fetch, store_results, raw, &retval); + cp = php_parserr(cp, end, &answer, type_to_fetch, store_results, raw, &retval); if (retval != NULL && store_results) { add_next_index_zval(return_value, retval); } @@ -901,7 +937,7 @@ PHP_FUNCTION(dns_get_record) while (ns-- > 0 && cp && cp < end) { zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, raw, &retval); + cp = php_parserr(cp, end, &answer, DNS_T_ANY, authns != NULL, raw, &retval); if (retval != NULL) { add_next_index_zval(authns, retval); } @@ -913,7 +949,7 @@ PHP_FUNCTION(dns_get_record) while (ar-- > 0 && cp && cp < end) { zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, 1, raw, &retval); + cp = php_parserr(cp, end, &answer, DNS_T_ANY, 1, raw, &retval); if (retval != NULL) { add_next_index_zval(addtl, retval); } diff --git a/ext/standard/info.c b/ext/standard/info.c index 98b4a8098..786820866 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -600,6 +600,14 @@ PHPAPI char *php_get_uname(char mode) php_get_windows_cpu(wincpu, sizeof(wincpu)); dwBuild = (DWORD)(HIWORD(dwVersion)); + + /* Windows "version" 6.2 could be Windows 8/Windows Server 2012, but also Windows 8.1/Windows Server 2012 R2 */ + if (dwWindowsMajorVersion == 6 && dwWindowsMinorVersion == 2) { + if (strncmp(winver, "Windows 8.1", 11) == 0 || strncmp(winver, "Windows Server 2012 R2", 22) == 0) { + dwWindowsMinorVersion = 3; + } + } + snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d (%s) %s", "Windows NT", ComputerName, dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild, winver?winver:"unknown", wincpu); diff --git a/ext/standard/string.c b/ext/standard/string.c index 22b1957f1..7bc215987 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/array/bug67693.phpt b/ext/standard/tests/array/bug67693.phpt new file mode 100644 index 000000000..516436c51 --- /dev/null +++ b/ext/standard/tests/array/bug67693.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #67693 - incorrect push to empty array +--FILE-- +<?php + +$array = array(-1 => 0); + +array_pop($array); + +array_push($array, 0); +array_push($array, 0); + +var_dump($array); + +echo"\nDone"; +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(0) +} + +Done diff --git a/ext/standard/tests/strings/ucwords_error.phpt b/ext/standard/tests/strings/ucwords_error.phpt index d79e569cc..a01c688c4 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 000000000..985df47c4 --- /dev/null +++ b/ext/standard/tests/strings/ucwords_variation5.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test ucwords() function : usage variations - custom delimiters +--FILE-- +<?php +/* Prototype : string ucwords ( string $str ) + * Description: Uppercase the first character of each word in a string + * Source code: ext/standard/string.c +*/ + +echo "*** Testing ucwords() : usage variations ***\n"; + +var_dump(ucwords('testing-dashed-words', '-')); +var_dump(ucwords('test(braced)words', '()')); +var_dump(ucwords('testing empty delimiters', '')); +var_dump(ucwords('testing ranges', 'a..e')); + +echo "Done\n"; +?> +--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 |
