summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2014-08-25 11:37:32 +0200
committerOndřej Surý <ondrej@sury.org>2014-08-25 11:37:32 +0200
commit4b01785e700724da58ab36336a92a44c5d8246a8 (patch)
tree94beaa316d16d2a191164f26efc78b3a744718d0 /ext/standard
parent66921ccd8c83bce7c509b6f005951c2fac8fbb80 (diff)
downloadphp-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.c2
-rw-r--r--ext/standard/basic_functions.c3
-rw-r--r--ext/standard/dns.c84
-rw-r--r--ext/standard/info.c8
-rw-r--r--ext/standard/string.c11
-rw-r--r--ext/standard/tests/array/bug67693.phpt25
-rw-r--r--ext/standard/tests/strings/ucwords_error.phpt6
-rw-r--r--ext/standard/tests/strings/ucwords_variation5.phpt25
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