Skip to content

Commit bd56046

Browse files
committed
try out @nielsdos suggestion, delaying free object_id at the end of the call.
1 parent fc4ef43 commit bd56046

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

ext/snmp/snmp.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,10 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
626626
}
627627
/* }}} */
628628

629+
static void php_snmp_zend_string_release_from_char_pointer(char *ptr) {
630+
zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val)));
631+
}
632+
629633
/* {{{ php_snmp_parse_oid
630634
*
631635
* OID parser (and type, value for SNMP_SET command)
@@ -682,7 +686,6 @@ static bool php_snmp_parse_oid(
682686
return false;
683687
}
684688
objid_query->vars[objid_query->count].oid = ZSTR_VAL(tmp);
685-
zend_string_release(tmp);
686689
if (st & SNMP_CMD_SET) {
687690
if (type_str) {
688691
pptr = ZSTR_VAL(type_str);
@@ -706,13 +709,17 @@ static bool php_snmp_parse_oid(
706709
}
707710
}
708711
if (idx_type < type_ht->nNumUsed) {
709-
convert_to_string(tmp_type);
710-
if (Z_STRLEN_P(tmp_type) != 1) {
712+
zend_string *tmp = zval_try_get_string(tmp_type);
713+
if (!tmp) {
714+
efree(objid_query->vars);
715+
return false;
716+
}
717+
if (ZSTR_LEN(tmp) != 1) {
711718
zend_value_error("Type must be a single character");
712719
efree(objid_query->vars);
713720
return false;
714721
}
715-
pptr = Z_STRVAL_P(tmp_type);
722+
pptr = ZSTR_VAL(tmp);
716723
objid_query->vars[objid_query->count].type = *pptr;
717724
idx_type++;
718725
} else {
@@ -743,8 +750,12 @@ static bool php_snmp_parse_oid(
743750
}
744751
}
745752
if (idx_value < value_ht->nNumUsed) {
746-
convert_to_string(tmp_value);
747-
objid_query->vars[objid_query->count].value = Z_STRVAL_P(tmp_value);
753+
zend_string *tmp = zval_try_get_string(tmp_value);
754+
if (!tmp) {
755+
efree(objid_query->vars);
756+
return false;
757+
}
758+
objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp);
748759
idx_value++;
749760
} else {
750761
php_error_docref(NULL, E_WARNING, "'%s': no value set", Z_STRVAL_P(tmp_oid));
@@ -761,13 +772,23 @@ static bool php_snmp_parse_oid(
761772
if (st & SNMP_CMD_WALK) {
762773
if (objid_query->count > 1) {
763774
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Multi OID walks are not supported!");
775+
for (int i = 0; i < objid_query->count; i ++) {
776+
snmpobjarg *arg = &objid_query->vars[i];
777+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
778+
}
779+
764780
efree(objid_query->vars);
765781
return false;
766782
}
767783
objid_query->vars[0].name_length = MAX_NAME_LEN;
768784
if (strlen(objid_query->vars[0].oid)) { /* on a walk, an empty string means top of tree - no error */
769785
if (!snmp_parse_oid(objid_query->vars[0].oid, objid_query->vars[0].name, &(objid_query->vars[0].name_length))) {
770786
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[0].oid);
787+
for (int i = 0; i < objid_query->count; i ++) {
788+
snmpobjarg *arg = &objid_query->vars[i];
789+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
790+
}
791+
771792
efree(objid_query->vars);
772793
return false;
773794
}
@@ -780,6 +801,11 @@ static bool php_snmp_parse_oid(
780801
objid_query->vars[objid_query->offset].name_length = MAX_OID_LEN;
781802
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))) {
782803
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[objid_query->offset].oid);
804+
for (int i = 0; i < objid_query->count; i ++) {
805+
snmpobjarg *arg = &objid_query->vars[i];
806+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
807+
}
808+
783809
efree(objid_query->vars);
784810
return false;
785811
}
@@ -1257,6 +1283,10 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12571283

12581284
if (session_less_mode) {
12591285
if (!netsnmp_session_init(&session, version, a1, a2, timeout, retries)) {
1286+
for (int i = 0; i < objid_query.count; i ++) {
1287+
snmpobjarg *arg = &objid_query.vars[i];
1288+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
1289+
}
12601290
efree(objid_query.vars);
12611291
netsnmp_session_free(&session);
12621292
RETURN_FALSE;
@@ -1273,6 +1303,10 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12731303
session = snmp_object->session;
12741304
if (!session) {
12751305
zend_throw_error(NULL, "Invalid or uninitialized SNMP object");
1306+
for (int i = 0; i < objid_query.count; i ++) {
1307+
snmpobjarg *arg = &objid_query.vars[i];
1308+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
1309+
}
12761310
efree(objid_query.vars);
12771311
RETURN_THROWS();
12781312
}
@@ -1299,15 +1333,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12991333

13001334
php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, session, &objid_query);
13011335

1302-
efree(objid_query.vars);
1303-
13041336
if (session_less_mode) {
13051337
netsnmp_session_free(&session);
13061338
} else {
13071339
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, glob_snmp_object.enum_print);
13081340
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, glob_snmp_object.quick_print);
13091341
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, glob_snmp_object.oid_output_format);
13101342
}
1343+
1344+
for (int i = 0; i < objid_query.count; i ++) {
1345+
snmpobjarg *arg = &objid_query.vars[i];
1346+
php_snmp_zend_string_release_from_char_pointer(arg->oid);
1347+
}
1348+
1349+
efree(objid_query.vars);
1350+
13111351
}
13121352
/* }}} */
13131353

0 commit comments

Comments
 (0)