@@ -629,6 +629,31 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
629
629
}
630
630
/* }}} */
631
631
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
+
632
657
/* {{{ php_snmp_parse_oid
633
658
*
634
659
* OID parser (and type, value for SNMP_SET command)
@@ -677,10 +702,15 @@ static bool php_snmp_parse_oid(
677
702
return false;
678
703
}
679
704
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 ));
680
706
objid_query -> array_output = (st & SNMP_CMD_SET ) == 0 ;
681
707
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 );
684
714
if (st & SNMP_CMD_SET ) {
685
715
if (type_str ) {
686
716
pptr = ZSTR_VAL (type_str );
@@ -704,18 +734,24 @@ static bool php_snmp_parse_oid(
704
734
}
705
735
}
706
736
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 ) {
709
746
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 );
711
748
return false;
712
749
}
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 ;
715
751
idx_type ++ ;
716
752
} 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 );
719
755
return false;
720
756
}
721
757
}
@@ -741,12 +777,16 @@ static bool php_snmp_parse_oid(
741
777
}
742
778
}
743
779
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 );
746
786
idx_value ++ ;
747
787
} 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 );
750
790
return false;
751
791
}
752
792
}
@@ -759,14 +799,14 @@ static bool php_snmp_parse_oid(
759
799
if (st & SNMP_CMD_WALK ) {
760
800
if (objid_query -> count > 1 ) {
761
801
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 );
763
803
return false;
764
804
}
765
805
objid_query -> vars [0 ].name_length = MAX_NAME_LEN ;
766
806
if (strlen (objid_query -> vars [0 ].oid )) { /* on a walk, an empty string means top of tree - no error */
767
807
if (!snmp_parse_oid (objid_query -> vars [0 ].oid , objid_query -> vars [0 ].name , & (objid_query -> vars [0 ].name_length ))) {
768
808
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 );
770
810
return false;
771
811
}
772
812
} else {
@@ -778,7 +818,7 @@ static bool php_snmp_parse_oid(
778
818
objid_query -> vars [objid_query -> offset ].name_length = MAX_OID_LEN ;
779
819
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 ))) {
780
820
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 );
782
822
return false;
783
823
}
784
824
}
@@ -1250,12 +1290,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1250
1290
1251
1291
if (session_less_mode ) {
1252
1292
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 );
1254
1294
netsnmp_session_free (& session );
1255
1295
RETURN_FALSE ;
1256
1296
}
1257
1297
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 );
1259
1299
netsnmp_session_free (& session );
1260
1300
/* Warning message sent already, just bail out */
1261
1301
RETURN_FALSE ;
@@ -1266,7 +1306,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1266
1306
session = snmp_object -> session ;
1267
1307
if (!session ) {
1268
1308
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 );
1270
1310
RETURN_THROWS ();
1271
1311
}
1272
1312
@@ -1292,7 +1332,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
1292
1332
1293
1333
php_snmp_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU , st , session , & objid_query );
1294
1334
1295
- efree ( objid_query . vars );
1335
+ php_free_objid_query ( & objid_query , oid_ht , value_ht , st );
1296
1336
1297
1337
if (session_less_mode ) {
1298
1338
netsnmp_session_free (& session );
0 commit comments