Skip to content

Commit 87e4970

Browse files
committed
Declare SNMP properties
Additionally, convert them to typed properties. Closes GH-6742
1 parent 532c60c commit 87e4970

6 files changed

+186
-31
lines changed

ext/snmp/snmp.c

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,29 +1667,36 @@ zval *php_snmp_read_property(zend_object *object, zend_string *name, int type, v
16671667
}
16681668
/* }}} */
16691669

1670-
/* {{{ php_snmp_write_property(zval *object, zval *member, zval *value[, const zend_literal *key])
1671-
Generic object property writer */
1670+
/* {{{ Generic object property writer */
16721671
zval *php_snmp_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
16731672
{
1674-
php_snmp_object *obj;
1675-
php_snmp_prop_handler *hnd;
1673+
php_snmp_object *obj = php_snmp_fetch_object(object);
1674+
php_snmp_prop_handler *hnd = zend_hash_find_ptr(&php_snmp_properties, name);
16761675

1677-
obj = php_snmp_fetch_object(object);
1678-
hnd = zend_hash_find_ptr(&php_snmp_properties, name);
1676+
if (hnd) {
1677+
if (!hnd->write_func) {
1678+
zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
1679+
return &EG(error_zval);
1680+
}
16791681

1680-
if (hnd && hnd->write_func) {
1681-
hnd->write_func(obj, value);
1682-
/*
1683-
if (!PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) {
1684-
Z_ADDREF_P(value);
1685-
zval_ptr_dtor(&value);
1682+
zend_property_info *prop = zend_get_property_info(object->ce, name, /* silent */ true);
1683+
if (prop && ZEND_TYPE_IS_SET(prop->type)) {
1684+
zval tmp;
1685+
ZVAL_COPY(&tmp, value);
1686+
if (!zend_verify_property_type(prop, &tmp,
1687+
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) {
1688+
zval_ptr_dtor(&tmp);
1689+
return &EG(error_zval);
1690+
}
1691+
hnd->write_func(obj, &tmp);
1692+
zval_ptr_dtor(&tmp);
1693+
} else {
1694+
hnd->write_func(obj, value);
16861695
}
1687-
*/
1688-
} else {
1689-
value = zend_std_write_property(object, name, value, cache_slot);
1696+
return value;
16901697
}
16911698

1692-
return value;
1699+
return zend_std_write_property(object, name, value, cache_slot);
16931700
}
16941701
/* }}} */
16951702

@@ -1762,6 +1769,16 @@ static HashTable *php_snmp_get_properties(zend_object *object)
17621769
}
17631770
/* }}} */
17641771

1772+
static zval *php_snmp_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot)
1773+
{
1774+
php_snmp_prop_handler *hnd = zend_hash_find_ptr(&php_snmp_properties, name);
1775+
if (hnd == NULL) {
1776+
return zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
1777+
}
1778+
1779+
return NULL;
1780+
}
1781+
17651782
/* {{{ */
17661783
static int php_snmp_read_info(php_snmp_object *snmp_object, zval *retval)
17671784
{
@@ -1820,14 +1837,6 @@ PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(valueretrieval)
18201837
PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(oid_output_format)
18211838
PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(exceptions_enabled)
18221839

1823-
/* {{{ */
1824-
static int php_snmp_write_info(php_snmp_object *snmp_object, zval *newval)
1825-
{
1826-
zend_throw_error(NULL, "SNMP::$info property is read-only");
1827-
return FAILURE;
1828-
}
1829-
/* }}} */
1830-
18311840
/* {{{ */
18321841
static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval)
18331842
{
@@ -1841,7 +1850,7 @@ static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval)
18411850
lval = zval_get_long(newval);
18421851

18431852
if (lval <= 0) {
1844-
zend_value_error("max_oids must be greater than 0 or null");
1853+
zend_value_error("SNMP::$max_oids must be greater than 0 or null");
18451854
return FAILURE;
18461855
}
18471856
snmp_object->max_oids = lval;
@@ -1924,8 +1933,11 @@ static void free_php_snmp_properties(zval *el) /* {{{ */
19241933
#define PHP_SNMP_PROPERTY_ENTRY_RECORD(name) \
19251934
{ "" #name "", sizeof("" #name "") - 1, php_snmp_read_##name, php_snmp_write_##name }
19261935

1936+
#define PHP_SNMP_READONLY_PROPERTY_ENTRY_RECORD(name) \
1937+
{ "" #name "", sizeof("" #name "") - 1, php_snmp_read_##name, NULL }
1938+
19271939
const php_snmp_prop_handler php_snmp_property_entries[] = {
1928-
PHP_SNMP_PROPERTY_ENTRY_RECORD(info),
1940+
PHP_SNMP_READONLY_PROPERTY_ENTRY_RECORD(info),
19291941
PHP_SNMP_PROPERTY_ENTRY_RECORD(max_oids),
19301942
PHP_SNMP_PROPERTY_ENTRY_RECORD(valueretrieval),
19311943
PHP_SNMP_PROPERTY_ENTRY_RECORD(quick_print),
@@ -1961,6 +1973,7 @@ PHP_MINIT_FUNCTION(snmp)
19611973
memcpy(&php_snmp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
19621974
php_snmp_object_handlers.read_property = php_snmp_read_property;
19631975
php_snmp_object_handlers.write_property = php_snmp_write_property;
1976+
php_snmp_object_handlers.get_property_ptr_ptr = php_snmp_get_property_ptr_ptr;
19641977
php_snmp_object_handlers.has_property = php_snmp_has_property;
19651978
php_snmp_object_handlers.get_properties = php_snmp_get_properties;
19661979
php_snmp_object_handlers.get_gc = php_snmp_get_gc;

ext/snmp/snmp.stub.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ function snmp_read_mib(string $filename): bool {}
7575

7676
class SNMP
7777
{
78+
/** @readonly */
79+
public array $info;
80+
public ?int $max_oids;
81+
public int $valueretrieval;
82+
public bool $quick_print;
83+
public bool $enum_print;
84+
public int $oid_output_format;
85+
public bool $oid_increasing_check;
86+
public int $exceptions_enabled;
87+
7888
public function __construct(int $version, string $hostname, string $community, int $timeout = -1, int $retries = -1) {}
7989

8090
/** @return bool */

ext/snmp/snmp_arginfo.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 08192d87d2ac5d35092cfcf4a2cdcc50f7ec4ada */
2+
* Stub hash: 5258c5796aca15e369dd72c0a8ed4dc1df31ce9d */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_snmpget, 0, 3, stdClass, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_BOOL)
55
ZEND_ARG_TYPE_INFO(0, hostname, IS_STRING, 0)
@@ -249,6 +249,54 @@ static zend_class_entry *register_class_SNMP(void)
249249
INIT_CLASS_ENTRY(ce, "SNMP", class_SNMP_methods);
250250
class_entry = zend_register_internal_class_ex(&ce, NULL);
251251

252+
zval property_info_default_value;
253+
ZVAL_UNDEF(&property_info_default_value);
254+
zend_string *property_info_name = zend_string_init("info", sizeof("info") - 1, 1);
255+
zend_declare_typed_property(class_entry, property_info_name, &property_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
256+
zend_string_release(property_info_name);
257+
258+
zval property_max_oids_default_value;
259+
ZVAL_UNDEF(&property_max_oids_default_value);
260+
zend_string *property_max_oids_name = zend_string_init("max_oids", sizeof("max_oids") - 1, 1);
261+
zend_declare_typed_property(class_entry, property_max_oids_name, &property_max_oids_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL));
262+
zend_string_release(property_max_oids_name);
263+
264+
zval property_valueretrieval_default_value;
265+
ZVAL_UNDEF(&property_valueretrieval_default_value);
266+
zend_string *property_valueretrieval_name = zend_string_init("valueretrieval", sizeof("valueretrieval") - 1, 1);
267+
zend_declare_typed_property(class_entry, property_valueretrieval_name, &property_valueretrieval_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
268+
zend_string_release(property_valueretrieval_name);
269+
270+
zval property_quick_print_default_value;
271+
ZVAL_UNDEF(&property_quick_print_default_value);
272+
zend_string *property_quick_print_name = zend_string_init("quick_print", sizeof("quick_print") - 1, 1);
273+
zend_declare_typed_property(class_entry, property_quick_print_name, &property_quick_print_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
274+
zend_string_release(property_quick_print_name);
275+
276+
zval property_enum_print_default_value;
277+
ZVAL_UNDEF(&property_enum_print_default_value);
278+
zend_string *property_enum_print_name = zend_string_init("enum_print", sizeof("enum_print") - 1, 1);
279+
zend_declare_typed_property(class_entry, property_enum_print_name, &property_enum_print_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
280+
zend_string_release(property_enum_print_name);
281+
282+
zval property_oid_output_format_default_value;
283+
ZVAL_UNDEF(&property_oid_output_format_default_value);
284+
zend_string *property_oid_output_format_name = zend_string_init("oid_output_format", sizeof("oid_output_format") - 1, 1);
285+
zend_declare_typed_property(class_entry, property_oid_output_format_name, &property_oid_output_format_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
286+
zend_string_release(property_oid_output_format_name);
287+
288+
zval property_oid_increasing_check_default_value;
289+
ZVAL_UNDEF(&property_oid_increasing_check_default_value);
290+
zend_string *property_oid_increasing_check_name = zend_string_init("oid_increasing_check", sizeof("oid_increasing_check") - 1, 1);
291+
zend_declare_typed_property(class_entry, property_oid_increasing_check_name, &property_oid_increasing_check_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL));
292+
zend_string_release(property_oid_increasing_check_name);
293+
294+
zval property_exceptions_enabled_default_value;
295+
ZVAL_UNDEF(&property_exceptions_enabled_default_value);
296+
zend_string *property_exceptions_enabled_name = zend_string_init("exceptions_enabled", sizeof("exceptions_enabled") - 1, 1);
297+
zend_declare_typed_property(class_entry, property_exceptions_enabled_name, &property_exceptions_enabled_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
298+
zend_string_release(property_exceptions_enabled_name);
299+
252300
return class_entry;
253301
}
254302

ext/snmp/tests/snmp-object-error.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ $session = new SNMP(SNMP::VERSION_2c, $hostname, $community, $timeout, $retries)
7575
var_dump($session->max_oids);
7676
try {
7777
$session->max_oids = "ttt";
78-
} catch (\ValueError $e) {
78+
} catch (TypeError $e) {
7979
echo $e->getMessage() . \PHP_EOL;
8080
}
8181
try {
@@ -103,6 +103,6 @@ Closing session
103103
bool(true)
104104
Invalid or uninitialized SNMP object
105105
NULL
106-
max_oids must be greater than 0 or null
107-
max_oids must be greater than 0 or null
106+
Cannot assign string to property SNMP::$max_oids of type ?int
107+
SNMP::$max_oids must be greater than 0 or null
108108
NULL
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
--TEST--
2+
Test SNMP object property errors
3+
--SKIPIF--
4+
<?php
5+
require_once(__DIR__.'/skipif.inc');
6+
?>
7+
--FILE--
8+
<?php
9+
require_once(__DIR__.'/snmp_include.inc');
10+
11+
$session = new SNMP(SNMP::VERSION_1, $hostname, $community, $timeout, $retries);
12+
13+
try {
14+
$session->info = [];
15+
} catch (Error $exception) {
16+
echo $exception->getMessage() . "\n";
17+
}
18+
19+
try {
20+
$session->info += [];
21+
} catch (Error $exception) {
22+
echo $exception->getMessage() . "\n";
23+
}
24+
25+
try {
26+
$session->max_oids = [];
27+
} catch (TypeError $exception) {
28+
echo $exception->getMessage() . "\n";
29+
}
30+
31+
try {
32+
$session->max_oids = -1;
33+
} catch (ValueError $exception) {
34+
echo $exception->getMessage() . "\n";
35+
}
36+
37+
try {
38+
$session->valueretrieval = [];
39+
} catch (TypeError $exception) {
40+
echo $exception->getMessage() . "\n";
41+
}
42+
43+
try {
44+
$session->quick_print = [];
45+
} catch (TypeError $exception) {
46+
echo $exception->getMessage() . "\n";
47+
}
48+
49+
try {
50+
$session->enum_print = [];
51+
} catch (TypeError $exception) {
52+
echo $exception->getMessage() . "\n";
53+
}
54+
55+
try {
56+
$session->oid_output_format = [];
57+
} catch (TypeError $exception) {
58+
echo $exception->getMessage() . "\n";
59+
}
60+
61+
try {
62+
$session->oid_increasing_check = [];
63+
} catch (TypeError $exception) {
64+
echo $exception->getMessage() . "\n";
65+
}
66+
67+
try {
68+
$session->exceptions_enabled = [];
69+
} catch (TypeError $exception) {
70+
echo $exception->getMessage() . "\n";
71+
}
72+
73+
?>
74+
--EXPECT--
75+
Cannot write read-only property SNMP::$info
76+
Cannot write read-only property SNMP::$info
77+
Cannot assign array to property SNMP::$max_oids of type ?int
78+
SNMP::$max_oids must be greater than 0 or null
79+
Cannot assign array to property SNMP::$valueretrieval of type int
80+
Cannot assign array to property SNMP::$quick_print of type bool
81+
Cannot assign array to property SNMP::$enum_print of type bool
82+
Cannot assign array to property SNMP::$oid_output_format of type int
83+
Cannot assign array to property SNMP::$oid_increasing_check of type bool
84+
Cannot assign array to property SNMP::$exceptions_enabled of type int

ext/snmp/tests/snmp-object-properties.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,5 @@ NULL
192192
bool(false)
193193
SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT
194194
SNMP output print format must be an SNMP_OID_OUTPUT_* constant
195-
SNMP::$info property is read-only
195+
Cannot write read-only property SNMP::$info
196196
NULL

0 commit comments

Comments
 (0)