Skip to content

snmp.php shadows six core lib/snmp.php functions with incompatible signatures #45

Description

@somethingwithproof

snmp.php defines six functions and four constants under the same names Cacti core uses in lib/snmp.php:

Function hmib core
cacti_snmp_get snmp.php:43 lib/snmp.php:127
cacti_snmp_getnext snmp.php:163 lib/snmp.php:308
cacti_snmp_walk snmp.php:271 lib/snmp.php:745
format_snmp_string snmp.php:425 lib/snmp.php:934
snmp_escape_string snmp.php:568 lib/snmp.php:1122
snmp_get_method snmp.php:576 lib/snmp.php:1150

Plus REGEXP_SNMP_TRIM, SNMP_METHOD_PHP, SNMP_METHOD_BINARY and SNMP_ESCAPE_CHARACTER, all bare define() with no defined() check.

This does not fire today. Core loads lib/snmp.php only from inside update_reindex_cache() and query_snmp_host(), never at file scope, and the two entry points stay apart: poller_hmib.php includes plugins/hmib/snmp.php, poller_graphs.php includes lib/snmp.php, and poller_hmib.php:524 launches the latter through exec_background(), so they are separate processes. Each process consistently sees one implementation.

It is filed as a hazard rather than a bug. Any change to that include graph turns it into a fatal, and the failure modes differ:

function: PHP Fatal error: Cannot redeclare snmp_get_method()
constant: PHP Warning: Constant SNMP_METHOD_PHP already defined   (keeps the first value)

The constant case is worse than it looks. It does not stop execution, so whichever file loaded first silently wins, and SNMP_ESCAPE_CHARACTER decides how community strings are quoted for the shell.

A function_exists() guard would be the wrong fix. The signatures are not compatible:

// core
cacti_snmp_get(..., $port = 161, $timeout_ms = 500, $retries = 0,
               $environ = 'SNMP', $engineid = '', $value_output_format, ?$native_get)
// hmib
cacti_snmp_get(..., $port = 161, $timeout = 500, $retries = 0,
               $max_oids = 10, $method = SNMP_VALUE_LIBRARY, $environ = SNMP_POLLER)

Core's fourteenth parameter is $environ; hmib's is $max_oids. Guarding would bind hmib's callers to core's function with positional arguments that mean something else, which is quieter and worse than the redeclare. Deleting the copies has the same problem.

Suggested fix. Rename the six to an hmib_ prefix and give the four constants defined() guards. The change is contained: all seven external call sites are in poller_hmib.php (cacti_snmp_walk x4, cacti_snmp_get x3), and the other three functions are only called from within snmp.php itself. cacti_snmp_getnext has no callers at all and could go.

That is behaviour-preserving. Adopting core's implementations instead would be the better end state, but it is a real behaviour change and wants its own testing against live devices.

Found while surveying duplicated helpers across the Cacti plugins; hmib is the only one shadowing core function names.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions