@@ -626,6 +626,31 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
626
626
}
627
627
/* }}} */
628
628
629
+ static void php_snmp_zend_string_release_from_char_pointer (char * ptr ) {
630
+ if (ptr ) {
631
+ zend_string * pptr = (zend_string * )(ptr - XtOffsetOf (zend_string , val ));
632
+ zend_string_release (pptr );
633
+ }
634
+ }
635
+
636
+ static void php_free_objid_query (struct objid_query * objid_query , HashTable * oid_ht , const HashTable * value_ht , int st ) {
637
+ if (oid_ht ) {
638
+ uint32_t count = zend_hash_num_elements (oid_ht );
639
+
640
+ for (uint32_t i = 0 ; i < count ; i ++ ) {
641
+ snmpobjarg * arg = & objid_query -> vars [i ];
642
+ if (!arg -> oid ) {
643
+ break ;
644
+ }
645
+ if (value_ht ) {
646
+ php_snmp_zend_string_release_from_char_pointer (arg -> value );
647
+ }
648
+ php_snmp_zend_string_release_from_char_pointer (arg -> oid );
649
+ }
650
+ }
651
+ efree (objid_query -> vars );
652
+ }
653
+
629
654
/* {{{ php_snmp_parse_oid
630
655
*
631
656
* OID parser (and type, value for SNMP_SET command)
@@ -674,10 +699,15 @@ static bool php_snmp_parse_oid(
674
699
return false;
675
700
}
676
701
objid_query -> vars = (snmpobjarg * )safe_emalloc (sizeof (snmpobjarg ), zend_hash_num_elements (oid_ht ), 0 );
702
+ memset (objid_query -> vars , 0 , sizeof (snmpobjarg ) * zend_hash_num_elements (oid_ht ));
677
703
objid_query -> array_output = (st & SNMP_CMD_SET ) == 0 ;
678
704
ZEND_HASH_FOREACH_VAL (oid_ht , tmp_oid ) {
679
- convert_to_string (tmp_oid );
680
- objid_query -> vars [objid_query -> count ].oid = Z_STRVAL_P (tmp_oid );
705
+ zend_string * tmp = zval_try_get_string (tmp_oid );
706
+ if (!tmp ) {
707
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
708
+ return false;
709
+ }
710
+ objid_query -> vars [objid_query -> count ].oid = ZSTR_VAL (tmp );
681
711
if (st & SNMP_CMD_SET ) {
682
712
if (type_str ) {
683
713
pptr = ZSTR_VAL (type_str );
@@ -701,18 +731,24 @@ static bool php_snmp_parse_oid(
701
731
}
702
732
}
703
733
if (idx_type < type_ht -> nNumUsed ) {
704
- convert_to_string (tmp_type );
705
- if (Z_STRLEN_P (tmp_type ) != 1 ) {
734
+ zend_string * type = zval_try_get_string (tmp_type );
735
+ if (!type ) {
736
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
737
+ return false;
738
+ }
739
+ size_t len = ZSTR_LEN (type );
740
+ char ptype = * ZSTR_VAL (type );
741
+ zend_string_release (type );
742
+ if (len != 1 ) {
706
743
zend_value_error ("Type must be a single character" );
707
- efree (objid_query -> vars );
744
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
708
745
return false;
709
746
}
710
- pptr = Z_STRVAL_P (tmp_type );
711
- objid_query -> vars [objid_query -> count ].type = * pptr ;
747
+ objid_query -> vars [objid_query -> count ].type = ptype ;
712
748
idx_type ++ ;
713
749
} else {
714
- php_error_docref (NULL , E_WARNING , "'%s': no type set" , Z_STRVAL_P ( tmp_oid ));
715
- efree (objid_query -> vars );
750
+ php_error_docref (NULL , E_WARNING , "'%s': no type set" , ZSTR_VAL ( tmp ));
751
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
716
752
return false;
717
753
}
718
754
}
@@ -738,12 +774,16 @@ static bool php_snmp_parse_oid(
738
774
}
739
775
}
740
776
if (idx_value < value_ht -> nNumUsed ) {
741
- convert_to_string (tmp_value );
742
- objid_query -> vars [objid_query -> count ].value = Z_STRVAL_P (tmp_value );
777
+ zend_string * tmp = zval_try_get_string (tmp_value );
778
+ if (!tmp ) {
779
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
780
+ return false;
781
+ }
782
+ objid_query -> vars [objid_query -> count ].value = ZSTR_VAL (tmp );
743
783
idx_value ++ ;
744
784
} else {
745
- php_error_docref (NULL , E_WARNING , "'%s': no value set" , Z_STRVAL_P ( tmp_oid ));
746
- efree (objid_query -> vars );
785
+ php_error_docref (NULL , E_WARNING , "'%s': no value set" , ZSTR_VAL ( tmp ));
786
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
747
787
return false;
748
788
}
749
789
}
@@ -756,14 +796,14 @@ static bool php_snmp_parse_oid(
756
796
if (st & SNMP_CMD_WALK ) {
757
797
if (objid_query -> count > 1 ) {
758
798
php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Multi OID walks are not supported!" );
759
- efree (objid_query -> vars );
799
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
760
800
return false;
761
801
}
762
802
objid_query -> vars [0 ].name_length = MAX_NAME_LEN ;
763
803
if (strlen (objid_query -> vars [0 ].oid )) { /* on a walk, an empty string means top of tree - no error */
764
804
if (!snmp_parse_oid (objid_query -> vars [0 ].oid , objid_query -> vars [0 ].name , & (objid_query -> vars [0 ].name_length ))) {
765
805
php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Invalid object identifier: %s" , objid_query -> vars [0 ].oid );
766
- efree (objid_query -> vars );
806
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
767
807
return false;
768
808
}
769
809
} else {
@@ -775,7 +815,7 @@ static bool php_snmp_parse_oid(
775
815
objid_query -> vars [objid_query -> offset ].name_length = MAX_OID_LEN ;
776
816
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 ))) {
777
817
php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Invalid object identifier: %s" , objid_query -> vars [objid_query -> offset ].oid );
778
- efree (objid_query -> vars );
818
+ php_free_objid_query (objid_query , oid_ht , value_ht , st );
779
819
return false;
780
820
}
781
821
}
@@ -1252,12 +1292,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1252
1292
1253
1293
if (session_less_mode ) {
1254
1294
if (!netsnmp_session_init (& session , version , a1 , a2 , timeout , retries )) {
1255
- efree ( objid_query . vars );
1295
+ php_free_objid_query ( & objid_query , oid_ht , value_ht , st );
1256
1296
netsnmp_session_free (& session );
1257
1297
RETURN_FALSE ;
1258
1298
}
1259
1299
if (version == SNMP_VERSION_3 && !netsnmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL )) {
1260
- efree ( objid_query . vars );
1300
+ php_free_objid_query ( & objid_query , oid_ht , value_ht , st );
1261
1301
netsnmp_session_free (& session );
1262
1302
/* Warning message sent already, just bail out */
1263
1303
RETURN_FALSE ;
@@ -1268,7 +1308,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1268
1308
session = snmp_object -> session ;
1269
1309
if (!session ) {
1270
1310
zend_throw_error (NULL , "Invalid or uninitialized SNMP object" );
1271
- efree ( objid_query . vars );
1311
+ php_free_objid_query ( & objid_query , oid_ht , value_ht , st );
1272
1312
RETURN_THROWS ();
1273
1313
}
1274
1314
@@ -1294,7 +1334,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1294
1334
1295
1335
php_snmp_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU , st , session , & objid_query );
1296
1336
1297
- efree ( objid_query . vars );
1337
+ php_free_objid_query ( & objid_query , oid_ht , value_ht , st );
1298
1338
1299
1339
if (session_less_mode ) {
1300
1340
netsnmp_session_free (& session );
0 commit comments