Skip to content

Commit

Permalink
try out @nielsdos suggestion, delaying free object_id at the end of t…
Browse files Browse the repository at this point in the history
…he call.
  • Loading branch information
devnexen committed Nov 27, 2024
1 parent fc4ef43 commit 4eb9738
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
63 changes: 55 additions & 8 deletions ext/snmp/snmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
}
/* }}} */

static void php_snmp_zend_string_release_from_char_pointer(char *ptr) {
zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val)));
}

/* {{{ php_snmp_parse_oid
*
* OID parser (and type, value for SNMP_SET command)
Expand Down Expand Up @@ -682,7 +686,6 @@ static bool php_snmp_parse_oid(
return false;
}
objid_query->vars[objid_query->count].oid = ZSTR_VAL(tmp);
zend_string_release(tmp);
if (st & SNMP_CMD_SET) {
if (type_str) {
pptr = ZSTR_VAL(type_str);
Expand All @@ -706,13 +709,17 @@ static bool php_snmp_parse_oid(
}
}
if (idx_type < type_ht->nNumUsed) {
convert_to_string(tmp_type);
if (Z_STRLEN_P(tmp_type) != 1) {
zend_string *tmp = zval_try_get_string(tmp_type);
if (!tmp) {
efree(objid_query->vars);
return false;
}
if (ZSTR_LEN(tmp) != 1) {
zend_value_error("Type must be a single character");
efree(objid_query->vars);
return false;
}
pptr = Z_STRVAL_P(tmp_type);
pptr = ZSTR_VAL(tmp);
objid_query->vars[objid_query->count].type = *pptr;
idx_type++;
} else {
Expand Down Expand Up @@ -743,8 +750,12 @@ static bool php_snmp_parse_oid(
}
}
if (idx_value < value_ht->nNumUsed) {
convert_to_string(tmp_value);
objid_query->vars[objid_query->count].value = Z_STRVAL_P(tmp_value);
zend_string *tmp = zval_try_get_string(tmp_value);
if (!tmp) {
efree(objid_query->vars);
return false;
}
objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp);
idx_value++;
} else {
php_error_docref(NULL, E_WARNING, "'%s': no value set", Z_STRVAL_P(tmp_oid));
Expand All @@ -761,13 +772,23 @@ static bool php_snmp_parse_oid(
if (st & SNMP_CMD_WALK) {
if (objid_query->count > 1) {
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Multi OID walks are not supported!");
for (int i = 0; i < objid_query->count; i ++) {
snmpobjarg *arg = &objid_query->vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query->vars);
return false;
}
objid_query->vars[0].name_length = MAX_NAME_LEN;
if (strlen(objid_query->vars[0].oid)) { /* on a walk, an empty string means top of tree - no error */
if (!snmp_parse_oid(objid_query->vars[0].oid, objid_query->vars[0].name, &(objid_query->vars[0].name_length))) {
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[0].oid);
for (int i = 0; i < objid_query->count; i ++) {
snmpobjarg *arg = &objid_query->vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query->vars);
return false;
}
Expand All @@ -780,6 +801,11 @@ static bool php_snmp_parse_oid(
objid_query->vars[objid_query->offset].name_length = MAX_OID_LEN;
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))) {
php_snmp_error(object, PHP_SNMP_ERRNO_OID_PARSING_ERROR, "Invalid object identifier: %s", objid_query->vars[objid_query->offset].oid);
for (int i = 0; i < objid_query->count; i ++) {
snmpobjarg *arg = &objid_query->vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query->vars);
return false;
}
Expand Down Expand Up @@ -1257,11 +1283,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)

if (session_less_mode) {
if (!netsnmp_session_init(&session, version, a1, a2, timeout, retries)) {
for (int i = 0; i < objid_query.count; i ++) {
snmpobjarg *arg = &objid_query.vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query.vars);
netsnmp_session_free(&session);
RETURN_FALSE;
}
if (version == SNMP_VERSION_3 && !netsnmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) {
for (int i = 0; i < objid_query.count; i ++) {
snmpobjarg *arg = &objid_query.vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query.vars);
netsnmp_session_free(&session);
/* Warning message sent already, just bail out */
Expand All @@ -1273,6 +1309,11 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
session = snmp_object->session;
if (!session) {
zend_throw_error(NULL, "Invalid or uninitialized SNMP object");
for (int i = 0; i < objid_query.count; i ++) {
snmpobjarg *arg = &objid_query.vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query.vars);
RETURN_THROWS();
}
Expand All @@ -1299,15 +1340,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)

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

efree(objid_query.vars);

if (session_less_mode) {
netsnmp_session_free(&session);
} else {
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, glob_snmp_object.enum_print);
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, glob_snmp_object.quick_print);
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, glob_snmp_object.oid_output_format);
}

for (int i = 0; i < objid_query.count; i ++) {
snmpobjarg *arg = &objid_query.vars[i];
php_snmp_zend_string_release_from_char_pointer(arg->oid);
}

efree(objid_query.vars);

}
/* }}} */

Expand Down
2 changes: 1 addition & 1 deletion ext/snmp/tests/gh16959.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ array(4) {
int(0)
}

Warning: snmpget(): Invalid object identifier: -229 in %s on line %d
Warning: snmpget(): Invalid object identifier: -54 in %s on line %d
bool(true)
array(4) {
[63]=>
Expand Down

0 comments on commit 4eb9738

Please sign in to comment.