com php-src: Fix #70112 RFE Allow dirname to go up various times: ext/standard/basic_functions.c ext/standard/string.c
ext/standard/tests/strings/dirname_error.phpt ext/standar d/tests/strings/dirname_multi.phpt
| From: | Remi Collet | Date: | Mon, 27 Jul 2015 13:23:04 +0000 |
| Subject: | com php-src: Fix #70112 RFE Allow dirname to go up various times: ext/standard/basic_functions.c ext/standard/string.c ext/standard/tests/strings/dirname_error.phpt ext/standar d/tests/strings/dirname_multi.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-88179@lists.php.net to get a copy of this message | ||
Commit: e811770a68641c85d7e49f84f3230b4ed7a1e808
Author: Remi Collet <fedora@famillecollet.com> Sat, 25 Jul 2015 16:58:36 +0200
Committer: Remi Collet <remi@php.net> Mon, 27 Jul 2015 15:23:04 +0200
Parents: 64f25adb6bbb6002dce837243e3915e45af385cf
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e811770a68641c85d7e49f84f3230b4ed7a1e808
Log:
Fix #70112 RFE Allow dirname to go up various times
Bugs:
https://bugs.php.net/70112
Changed paths:
M ext/standard/basic_functions.c
M ext/standard/string.c
M ext/standard/tests/strings/dirname_error.phpt
A ext/standard/tests/strings/dirname_multi.phpt
Diff:
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 488b71b..3f03275 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -2213,8 +2213,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_basename, 0, 0, 1)
ZEND_ARG_INFO(0, suffix)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO(arginfo_dirname, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dirname, 0, 0, 1)
ZEND_ARG_INFO(0, path)
+ ZEND_ARG_INFO(0, levels)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pathinfo, 0, 0, 1)
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 2a9ddb2..143c6f6 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1648,21 +1648,36 @@ PHPAPI size_t php_dirname(char *path, size_t len)
}
/* }}} */
-/* {{{ proto string dirname(string path)
+/* {{{ proto string dirname(string path[, int levels])
Returns the directory name component of the path */
PHP_FUNCTION(dirname)
{
char *str;
zend_string *ret;
size_t str_len;
+ zend_long levels = 1;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &str_len, &levels)
== FAILURE) {
return;
}
ret = zend_string_init(str, str_len, 0);
- ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len);
+ if (levels == 1) {
+ /* Defaut case */
+ ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len);
+
+ } else if (levels < 1) {
+ php_error_docref(NULL, E_WARNING, "Invalid argument, levels must be >= 1");
+ return;
+
+
+ } else {
+ /* Some levels up */
+ do {
+ ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len=ZSTR_LEN(ret));
+ } while (ZSTR_LEN(ret)<str_len && --levels>0);
+ }
RETURN_NEW_STR(ret);
}
/* }}} */
diff --git a/ext/standard/tests/strings/dirname_error.phpt
b/ext/standard/tests/strings/dirname_error.phpt
index bf63102..303a59b 100644
--- a/ext/standard/tests/strings/dirname_error.phpt
+++ b/ext/standard/tests/strings/dirname_error.phpt
@@ -9,17 +9,23 @@ echo "*** Testing error conditions ***\n";
// zero arguments
var_dump( dirname() );
+// Bad arg
+var_dump( dirname("/var/tmp/bar.gz", 0) );
+
// more than expected no. of arguments
-var_dump( dirname("/var/tmp/bar.gz", ".gz") );
+var_dump( dirname("/var/tmp/bar..gz", 1, ".gz") );
echo "Done\n";
?>
--EXPECTF--
*** Testing error conditions ***
-Warning: dirname() expects exactly 1 parameter, 0 given in %s on line %d
+Warning: dirname() expects at least 1 parameter, 0 given in %s on line %d
+NULL
+
+Warning: dirname(): Invalid argument, levels must be >= 1 in %s on line %d
NULL
-Warning: dirname() expects exactly 1 parameter, 2 given in %s on line %d
+Warning: dirname() expects at most 2 parameters, 3 given in %s on line %d
NULL
Done
diff --git a/ext/standard/tests/strings/dirname_multi.phpt
b/ext/standard/tests/strings/dirname_multi.phpt
new file mode 100644
index 0000000...d0fdfac
--- /dev/null
+++ b/ext/standard/tests/strings/dirname_multi.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Test dirname() function : usage variations
+--FILE--
+<?php
+/* Prototype: string dirname ( string $path [, int nb]);
+ Description: Returns directory name component of path.
+*/
+for ($i=1 ; $i<5 ; $i++) {
+ var_dump(dirname("/foo/bar/baz", $i));
+}
+var_dump(dirname("/foo/bar/baz", PHP_INT_MAX));
+?>
+Done
+--EXPECT--
+string(8) "/foo/bar"
+string(4) "/foo"
+string(1) "/"
+string(1) "/"
+string(1) "/"
+Done