Skip to content

Commit

Permalink
Declare Directory properties
Browse files Browse the repository at this point in the history
Some error handling test changes, as changes to the $handle
property are now detected earlier.
  • Loading branch information
nikic committed Aug 19, 2021
1 parent 7e84b1e commit 29c6eb6
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 117 deletions.
18 changes: 11 additions & 7 deletions ext/standard/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ php_dir_globals dir_globals;

static zend_class_entry *dir_class_entry_ptr;

#define Z_DIRECTORY_PATH_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 0)
#define Z_DIRECTORY_HANDLE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 1)

#define FETCH_DIRP() \
myself = getThis(); \
if (!myself) { \
Expand All @@ -80,11 +83,12 @@ static zend_class_entry *dir_class_entry_ptr;
} \
} else { \
ZEND_PARSE_PARAMETERS_NONE(); \
if ((tmp = zend_hash_str_find(Z_OBJPROP_P(myself), "handle", sizeof("handle")-1)) == NULL) { \
zval *handle_zv = Z_DIRECTORY_HANDLE_P(myself); \
if (Z_TYPE_P(handle_zv) != IS_RESOURCE) { \
zend_throw_error(NULL, "Unable to find my handle property"); \
RETURN_THROWS(); \
} \
if ((dirp = (php_stream *)zend_fetch_resource_ex(tmp, "Directory", php_file_le_stream())) == NULL) { \
if ((dirp = (php_stream *)zend_fetch_resource_ex(handle_zv, "Directory", php_file_le_stream())) == NULL) { \
RETURN_THROWS(); \
} \
}
Expand Down Expand Up @@ -218,8 +222,8 @@ static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)

if (createobject) {
object_init_ex(return_value, dir_class_entry_ptr);
add_property_stringl(return_value, "path", dirname, dir_len);
add_property_resource(return_value, "handle", dirp->res);
ZVAL_STRINGL(Z_DIRECTORY_PATH_P(return_value), dirname, dir_len);
ZVAL_RES(Z_DIRECTORY_HANDLE_P(return_value), dirp->res);
php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */
} else {
php_stream_to_zval(dirp, return_value);
Expand All @@ -244,7 +248,7 @@ PHP_FUNCTION(dir)
/* {{{ Close directory connection identified by the dir_handle */
PHP_FUNCTION(closedir)
{
zval *id = NULL, *tmp, *myself;
zval *id = NULL, *myself;
php_stream *dirp;
zend_resource *res;

Expand Down Expand Up @@ -355,7 +359,7 @@ PHP_FUNCTION(getcwd)
/* {{{ Rewind dir_handle back to the start */
PHP_FUNCTION(rewinddir)
{
zval *id = NULL, *tmp, *myself;
zval *id = NULL, *myself;
php_stream *dirp;

FETCH_DIRP();
Expand All @@ -372,7 +376,7 @@ PHP_FUNCTION(rewinddir)
/* {{{ Read directory entry from dir_handle */
PHP_FUNCTION(readdir)
{
zval *id = NULL, *tmp, *myself;
zval *id = NULL, *myself;
php_stream *dirp;
php_stream_dirent entry;

Expand Down
5 changes: 5 additions & 0 deletions ext/standard/dir.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

class Directory
{
public readonly string $path;

/** @var resource */
public readonly mixed $handle;

/**
* @tentative-return-type
* @implementation-alias closedir
Expand Down
14 changes: 13 additions & 1 deletion ext/standard/dir_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: e3d46788bb18dc90a0922e5738442b2932dd53f6 */
* Stub hash: b3890e798e609e306027b4717ce0c5e782884087 */

ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Directory_close, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
Expand Down Expand Up @@ -29,5 +29,17 @@ static zend_class_entry *register_class_Directory(void)
INIT_CLASS_ENTRY(ce, "Directory", class_Directory_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);

zval property_path_default_value;
ZVAL_UNDEF(&property_path_default_value);
zend_string *property_path_name = zend_string_init("path", sizeof("path") - 1, 1);
zend_declare_typed_property(class_entry, property_path_name, &property_path_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
zend_string_release(property_path_name);

zval property_handle_default_value;
ZVAL_UNDEF(&property_handle_default_value);
zend_string *property_handle_name = zend_string_init("handle", sizeof("handle") - 1, 1);
zend_declare_typed_property(class_entry, property_handle_name, &property_handle_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY));
zend_string_release(property_handle_name);

return class_entry;
}
8 changes: 7 additions & 1 deletion ext/standard/tests/directory/DirectoryClass_basic_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ Class [ <internal%s> class Directory ] {
- Static methods [0] {
}

- Properties [0] {
- Properties [2] {
Property [ public readonly string $path ]
Property [ public readonly mixed $handle ]
}

- Methods [3] {
Expand Down Expand Up @@ -63,5 +65,9 @@ Class [ <internal%s> class Directory ] {
}
Cannot instantiate a valid Directory directly:
object(Directory)#%d (0) {
["path"]=>
uninitialized(string)
["handle"]=>
uninitialized(mixed)
}
Unable to find my handle property
65 changes: 0 additions & 65 deletions ext/standard/tests/directory/DirectoryClass_error_001-mb.phpt

This file was deleted.

58 changes: 15 additions & 43 deletions ext/standard/tests/directory/DirectoryClass_error_001.phpt
Original file line number Diff line number Diff line change
@@ -1,55 +1,27 @@
--TEST--
Directory class behaviour.
Changing Directory::$handle property
--FILE--
<?php

echo "\n--> Try all methods with bad handle:\n";
$d = new Directory(getcwd());
$d->handle = "Havoc!";
$d = dir(getcwd());
try {
var_dump($d->read());
} catch (TypeError $e) {
$d->handle = "Havoc!";
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump($d->rewind());
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump($d->close());
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}

echo "\n--> Try all methods with no handle:\n";
$d = new Directory(getcwd());
unset($d->handle);
var_dump($d->handle);

$d = dir(getcwd());
try {
var_dump($d->read());
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
try {
var_dump($d->rewind());
} catch (\Error $e) {
echo $e->getMessage() . "\n";
}
try {
var_dump($d->close());
} catch (\Error $e) {
echo $e->getMessage() . "\n";
unset($d->handle);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump($d->handle);

?>
--EXPECT--
--> Try all methods with bad handle:
Directory::read(): supplied argument is not a valid Directory resource
Directory::rewind(): supplied argument is not a valid Directory resource
Directory::close(): supplied argument is not a valid Directory resource

--> Try all methods with no handle:
Unable to find my handle property
Unable to find my handle property
Unable to find my handle property
--EXPECTF--
Cannot modify readonly property Directory::$handle
resource(%d) of type (stream)
Cannot unset readonly property Directory::$handle
resource(%d) of type (stream)

0 comments on commit 29c6eb6

Please sign in to comment.