Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 917e120

Browse files
committed
Merge branch 'PHP-8.4'
2 parents 51aee38 + 6419ae4 commit 917e120

File tree

2 files changed

+129
-20
lines changed

2 files changed

+129
-20
lines changed

‎ext/snmp/snmp.c‎

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,31 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
629629
}
630630
/* }}} */
631631

632+
static void php_snmp_zend_string_release_from_char_pointer(char *ptr) {
633+
if (ptr) {
634+
zend_string *pptr = (zend_string *)(ptr - XtOffsetOf(zend_string, val));
635+
zend_string_release(pptr);
636+
}
637+
}
638+
639+
static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid_ht, const HashTable *value_ht, int st) {
640+
if (oid_ht) {
641+
uint32_t count = zend_hash_num_elements(oid_ht);
642+
643+
for (uint32_t i = 0; i < count; i ++) {
644+
snmpobjarg *arg = &objid_query->vars[i];
645+
if (!arg->oid) {
646+
break;
647+
}
648+
if (value_ht) {
649+
php_snmp_zend_string_release_from_char_pointer(arg->value);
650+
}
651+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
652+
}
653+
}
654+
efree(objid_query->vars);
655+
}
656+
632657
/* {{{ php_snmp_parse_oid
633658
*
634659
* OID parser (and type, value for SNMP_SET command)
@@ -677,10 +702,15 @@ static bool php_snmp_parse_oid(
677702
return false;
678703
}
679704
objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0);
705+
memset(objid_query->vars, 0, sizeof(snmpobjarg) * zend_hash_num_elements(oid_ht));
680706
objid_query->array_output = (st & SNMP_CMD_SET) == 0;
681707
ZEND_HASH_FOREACH_VAL(oid_ht, tmp_oid) {
682-
convert_to_string(tmp_oid);
683-
objid_query->vars[objid_query->count].oid = Z_STRVAL_P(tmp_oid);
708+
zend_string *tmp = zval_try_get_string(tmp_oid);
709+
if (!tmp) {
710+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
711+
return false;
712+
}
713+
objid_query->vars[objid_query->count].oid = ZSTR_VAL(tmp);
684714
if (st & SNMP_CMD_SET) {
685715
if (type_str) {
686716
pptr = ZSTR_VAL(type_str);
@@ -704,18 +734,24 @@ static bool php_snmp_parse_oid(
704734
}
705735
}
706736
if (idx_type < type_ht->nNumUsed) {
707-
convert_to_string(tmp_type);
708-
if (Z_STRLEN_P(tmp_type) != 1) {
737+
zend_string *type = zval_try_get_string(tmp_type);
738+
if (!type) {
739+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
740+
return false;
741+
}
742+
size_t len = ZSTR_LEN(type);
743+
char ptype = *ZSTR_VAL(type);
744+
zend_string_release(type);
745+
if (len != 1) {
709746
zend_value_error("Type must be a single character");
710-
efree(objid_query->vars);
747+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
711748
return false;
712749
}
713-
pptr = Z_STRVAL_P(tmp_type);
714-
objid_query->vars[objid_query->count].type = *pptr;
750+
objid_query->vars[objid_query->count].type = ptype;
715751
idx_type++;
716752
} else {
717-
php_error_docref(NULL, E_WARNING, "'%s': no type set", Z_STRVAL_P(tmp_oid));
718-
efree(objid_query->vars);
753+
php_error_docref(NULL, E_WARNING, "'%s': no type set", ZSTR_VAL(tmp));
754+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
719755
return false;
720756
}
721757
}
@@ -741,12 +777,16 @@ static bool php_snmp_parse_oid(
741777
}
742778
}
743779
if (idx_value < value_ht->nNumUsed) {
744-
convert_to_string(tmp_value);
745-
objid_query->vars[objid_query->count].value = Z_STRVAL_P(tmp_value);
780+
zend_string *tmp = zval_try_get_string(tmp_value);
781+
if (!tmp) {
782+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
783+
return false;
784+
}
785+
objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp);
746786
idx_value++;
747787
} else {
748-
php_error_docref(NULL, E_WARNING, "'%s': no value set", Z_STRVAL_P(tmp_oid));
749-
efree(objid_query->vars);
788+
php_error_docref(NULL, E_WARNING, "'%s': no value set", ZSTR_VAL(tmp));
789+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
750790
return false;
751791
}
752792
}
@@ -759,14 +799,14 @@ static bool php_snmp_parse_oid(
759799
if (st & SNMP_CMD_WALK) {
760800
if (objid_query->count > 1) {
761801
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Multi OID walks are not supported!");
762-
efree(objid_query->vars);
802+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
763803
return false;
764804
}
765805
objid_query->vars[0].name_length = MAX_NAME_LEN;
766806
if (strlen(objid_query->vars[0].oid)) { /* on a walk, an empty string means top of tree - no error */
767807
if (!snmp_parse_oid(objid_query->vars[0].oid, objid_query->vars[0].name, &(objid_query->vars[0].name_length))) {
768808
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[0].oid);
769-
efree(objid_query->vars);
809+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
770810
return false;
771811
}
772812
} else {
@@ -778,7 +818,7 @@ static bool php_snmp_parse_oid(
778818
objid_query->vars[objid_query->offset].name_length = MAX_OID_LEN;
779819
if (!snmp_parse_oid(objid_query->vars[objid_query->offset].oid, objid_query->vars[objid_query->offset].name, &(objid_query->vars[objid_query->offset].name_length))) {
780820
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[objid_query->offset].oid);
781-
efree(objid_query->vars);
821+
php_free_objid_query(objid_query, oid_ht, value_ht, st);
782822
return false;
783823
}
784824
}
@@ -1250,12 +1290,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12501290

12511291
if (session_less_mode) {
12521292
if (!netsnmp_session_init(&session, version, a1, a2, timeout, retries)) {
1253-
efree(objid_query.vars);
1293+
php_free_objid_query(&objid_query, oid_ht, value_ht, st);
12541294
netsnmp_session_free(&session);
12551295
RETURN_FALSE;
12561296
}
12571297
if (version == SNMP_VERSION_3 && !netsnmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) {
1258-
efree(objid_query.vars);
1298+
php_free_objid_query(&objid_query, oid_ht, value_ht, st);
12591299
netsnmp_session_free(&session);
12601300
/* Warning message sent already, just bail out */
12611301
RETURN_FALSE;
@@ -1266,7 +1306,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12661306
session = snmp_object->session;
12671307
if (!session) {
12681308
zend_throw_error(NULL, "Invalid or uninitialized SNMP object");
1269-
efree(objid_query.vars);
1309+
php_free_objid_query(&objid_query, oid_ht, value_ht, st);
12701310
RETURN_THROWS();
12711311
}
12721312

@@ -1292,7 +1332,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12921332

12931333
php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, session, &objid_query);
12941334

1295-
efree(objid_query.vars);
1335+
php_free_objid_query(&objid_query, oid_ht, value_ht, st);
12961336

12971337
if (session_less_mode) {
12981338
netsnmp_session_free(&session);

‎ext/snmp/tests/gh16959.phpt‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--TEST--
2+
snmpget() modifies object_id array source
3+
--EXTENSIONS--
4+
snmp
5+
--SKIPIF--
6+
<?php
7+
require_once(__DIR__.'/skipif.inc');
8+
?>
9+
--FILE--
10+
<?php
11+
require_once(__DIR__.'/snmp_include.inc');
12+
13+
$bad_object_ids = array (
14+
077 => 077, -066 => -066, -0345 => -0345, 0 => 0
15+
);
16+
var_dump($bad_object_ids);
17+
var_dump(snmpget($hostname, "", $bad_object_ids) === false);
18+
// The array should remain unmodified
19+
var_dump($bad_object_ids);
20+
try {
21+
snmpget($hostname, "", [0 => new stdClass()]);
22+
} catch (Throwable $e) {
23+
echo $e->getMessage() . PHP_EOL;
24+
}
25+
26+
try {
27+
snmp2_set($hostname, $communityWrite, $bad_object_ids, array(new stdClass()), array(null));
28+
} catch (Throwable $e) {
29+
echo $e->getMessage() . PHP_EOL;
30+
}
31+
try {
32+
snmp2_set($hostname, $communityWrite, $bad_object_ids, array("toolongtype"), array(null));
33+
} catch (Throwable $e) {
34+
echo $e->getMessage() . PHP_EOL;
35+
}
36+
try {
37+
snmp2_set($hostname, $communityWrite, $bad_object_ids, array(str_repeat("onetoomuch", random_int(1, 1))), array(null));
38+
} catch (Throwable $e) {
39+
echo $e->getMessage();
40+
}
41+
?>
42+
--EXPECTF--
43+
array(4) {
44+
[63]=>
45+
int(63)
46+
[-54]=>
47+
int(-54)
48+
[-229]=>
49+
int(-229)
50+
[0]=>
51+
int(0)
52+
}
53+
54+
Warning: snmpget(): Invalid object identifier: -54 in %s on line %d
55+
bool(true)
56+
array(4) {
57+
[63]=>
58+
int(63)
59+
[-54]=>
60+
int(-54)
61+
[-229]=>
62+
int(-229)
63+
[0]=>
64+
int(0)
65+
}
66+
Object of class stdClass could not be converted to string
67+
Object of class stdClass could not be converted to string
68+
Type must be a single character
69+
Type must be a single character

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /