@@ -627,20 +627,34 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
627627/* }}} */
628628
629629static void php_snmp_zend_string_release_from_char_pointer (char * ptr ) {
630- zend_string * pptr = (zend_string * )(ptr - XtOffsetOf (zend_string , val ));
631- zend_string_release (pptr );
630+ if (ptr ) {
631+ zend_string * pptr = (zend_string * )(ptr - XtOffsetOf (zend_string , val ));
632+ if (GC_REFCOUNT (pptr )) {
633+ zend_string_release (pptr );
634+ }
635+ }
632636}
633637
634- static void php_free_objid_query (struct objid_query * objid_query , zend_string * oid_str , zend_string * value_str , HashTable * value_ht , int st ) {
635- if (!oid_str ) {
636- for (int i = 0 ; i < objid_query -> count ; i ++ ) {
638+ static void php_free_objid_query (struct objid_query * objid_query , HashTable * oid_ht , zend_string * value_str , HashTable * value_ht , int st ) {
639+ #define PHP_FREE_OBJID_VAL (arg ) \
640+ do { \
641+ if (value_str) { \
642+ php_snmp_zend_string_release_from_char_pointer(arg->value); \
643+ } \
644+ php_snmp_zend_string_release_from_char_pointer(&arg->type); \
645+ php_snmp_zend_string_release_from_char_pointer(arg->oid); \
646+ } while (0)
647+
648+ if (oid_ht ) {
649+ uint32_t i = 0 , count = zend_hash_num_elements (oid_ht );
650+
651+ while (i < count ) {
637652 snmpobjarg * arg = & objid_query -> vars [i ];
638- if (st & SNMP_CMD_SET ) {
639- if (!value_str && value_ht ) {
640- php_snmp_zend_string_release_from_char_pointer (arg -> value );
641- }
653+ if (!arg -> oid ) {
654+ break ;
642655 }
643- php_snmp_zend_string_release_from_char_pointer (arg -> oid );
656+ PHP_FREE_OBJID_VAL (arg );
657+ i ++ ;
644658 }
645659 }
646660 efree (objid_query -> vars );
@@ -694,11 +708,12 @@ static bool php_snmp_parse_oid(
694708 return false;
695709 }
696710 objid_query -> vars = (snmpobjarg * )safe_emalloc (sizeof (snmpobjarg ), zend_hash_num_elements (oid_ht ), 0 );
711+ memset (objid_query -> vars , 0 , sizeof (snmpobjarg ) * zend_hash_num_elements (oid_ht ));
697712 objid_query -> array_output = (st & SNMP_CMD_SET ) == 0 ;
698713 ZEND_HASH_FOREACH_VAL (oid_ht , tmp_oid ) {
699714 zend_string * tmp = zval_try_get_string (tmp_oid );
700715 if (!tmp ) {
701- efree (objid_query -> vars );
716+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
702717 return false;
703718 }
704719 objid_query -> vars [objid_query -> count ].oid = ZSTR_VAL (tmp );
@@ -725,23 +740,23 @@ static bool php_snmp_parse_oid(
725740 }
726741 }
727742 if (idx_type < type_ht -> nNumUsed ) {
728- zval new ;
729- ZVAL_COPY_VALUE (& new , tmp_type );
730- if (!try_convert_to_string (& new )) {
731- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
743+ zend_string * type = zval_try_get_string (tmp_type );
744+ if (!type ) {
745+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
732746 return false;
733747 }
734- if (Z_STRLEN ( new ) != 1 ) {
748+ if (ZSTR_LEN ( type ) != 1 ) {
735749 zend_value_error ("Type must be a single character" );
736- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
750+ zend_string_release (type );
751+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
737752 return false;
738753 }
739- pptr = Z_STRVAL ( new );
754+ pptr = ZSTR_VAL ( type );
740755 objid_query -> vars [objid_query -> count ].type = * pptr ;
741756 idx_type ++ ;
742757 } else {
743- php_error_docref (NULL , E_WARNING , "'%s': no type set" , Z_STRVAL_P ( tmp_oid ));
744- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
758+ php_error_docref (NULL , E_WARNING , "'%s': no type set" , ZSTR_VAL ( tmp ));
759+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
745760 return false;
746761 }
747762 }
@@ -769,14 +784,14 @@ static bool php_snmp_parse_oid(
769784 if (idx_value < value_ht -> nNumUsed ) {
770785 zend_string * tmp = zval_try_get_string (tmp_value );
771786 if (!tmp ) {
772- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
787+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
773788 return false;
774789 }
775790 objid_query -> vars [objid_query -> count ].value = ZSTR_VAL (tmp );
776791 idx_value ++ ;
777792 } else {
778- php_error_docref (NULL , E_WARNING , "'%s': no value set" , Z_STRVAL_P ( tmp_oid ));
779- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
793+ php_error_docref (NULL , E_WARNING , "'%s': no value set" , ZSTR_VAL ( tmp ));
794+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
780795 return false;
781796 }
782797 }
@@ -789,14 +804,14 @@ static bool php_snmp_parse_oid(
789804 if (st & SNMP_CMD_WALK ) {
790805 if (objid_query -> count > 1 ) {
791806 php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Multi OID walks are not supported!" );
792- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
807+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
793808 return false;
794809 }
795810 objid_query -> vars [0 ].name_length = MAX_NAME_LEN ;
796811 if (strlen (objid_query -> vars [0 ].oid )) { /* on a walk, an empty string means top of tree - no error */
797812 if (!snmp_parse_oid (objid_query -> vars [0 ].oid , objid_query -> vars [0 ].name , & (objid_query -> vars [0 ].name_length ))) {
798813 php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Invalid object identifier: %s" , objid_query -> vars [0 ].oid );
799- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
814+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
800815 return false;
801816 }
802817 } else {
@@ -808,7 +823,7 @@ static bool php_snmp_parse_oid(
808823 objid_query -> vars [objid_query -> offset ].name_length = MAX_OID_LEN ;
809824 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 ))) {
810825 php_snmp_error (object , PHP_SNMP_ERRNO_OID_PARSING_ERROR , "Invalid object identifier: %s" , objid_query -> vars [objid_query -> offset ].oid );
811- php_free_objid_query (objid_query , oid_str , value_str , value_ht , st );
826+ php_free_objid_query (objid_query , oid_ht , value_str , value_ht , st );
812827 return false;
813828 }
814829 }
@@ -1285,12 +1300,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12851300
12861301 if (session_less_mode ) {
12871302 if (!netsnmp_session_init (& session , version , a1 , a2 , timeout , retries )) {
1288- php_free_objid_query (& objid_query , oid_str , value_str , value_ht , st );
1303+ php_free_objid_query (& objid_query , oid_ht , value_str , value_ht , st );
12891304 netsnmp_session_free (& session );
12901305 RETURN_FALSE ;
12911306 }
12921307 if (version == SNMP_VERSION_3 && !netsnmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL )) {
1293- php_free_objid_query (& objid_query , oid_str , value_str , value_ht , st );
1308+ php_free_objid_query (& objid_query , oid_ht , value_str , value_ht , st );
12941309 netsnmp_session_free (& session );
12951310 /* Warning message sent already, just bail out */
12961311 RETURN_FALSE ;
@@ -1301,7 +1316,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13011316 session = snmp_object -> session ;
13021317 if (!session ) {
13031318 zend_throw_error (NULL , "Invalid or uninitialized SNMP object" );
1304- php_free_objid_query (& objid_query , oid_str , value_str , value_ht , st );
1319+ php_free_objid_query (& objid_query , oid_ht , value_str , value_ht , st );
13051320 RETURN_THROWS ();
13061321 }
13071322
@@ -1327,15 +1342,15 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13271342
13281343 php_snmp_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU , st , session , & objid_query );
13291344
1345+ php_free_objid_query (& objid_query , oid_ht , value_str , value_ht , st );
1346+
13301347 if (session_less_mode ) {
13311348 netsnmp_session_free (& session );
13321349 } else {
13331350 netsnmp_ds_set_boolean (NETSNMP_DS_LIBRARY_ID , NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM , glob_snmp_object .enum_print );
13341351 netsnmp_ds_set_boolean (NETSNMP_DS_LIBRARY_ID , NETSNMP_DS_LIB_QUICK_PRINT , glob_snmp_object .quick_print );
13351352 netsnmp_ds_set_int (NETSNMP_DS_LIBRARY_ID , NETSNMP_DS_LIB_OID_OUTPUT_FORMAT , glob_snmp_object .oid_output_format );
13361353 }
1337-
1338- php_free_objid_query (& objid_query , oid_str , value_str , value_ht , st );
13391354}
13401355/* }}} */
13411356
0 commit comments