Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

--- develop ---

* bug: Guard the pre-1.3 report compatibility shims (reports_run/reports_queue/reports_log_and_notify) behind a function_exists() check instead of a CACTI_VERSION string comparison, so a develop build that reports a version comparing < 1.3 no longer fatally redeclares those now-native functions
* security: Move the plugin's remaining inline event handlers to CSP-safe bindings so the pages no longer trip Cacti's Content-Security-Policy script-src-attr directive: confirmation Cancel buttons use the `cactiReturnTo` class, the database/filter selects are bound via change() in their ready blocks, and the main filter's sort/report selects and time-shift icons are bound in flowview_display_filter's ready block
* dev: Replace the translation-template CI check that regenerated locales/po/cacti.pot and compared it with a diff-based gate (tests/bin/check-i18n-pot.php) requiring cacti.pot to be updated only when a pull request adds, removes, or modifies an i18n function call
* issue: Prevent flow-capture from fatally erroring (TypeError in spl_object_hash) when flowview_db_check_reconnect() held a null shared-database handle; normalize a non-object connection to false so db_check_reconnect() checks and reconnects the default connection instead
Expand Down
6 changes: 5 additions & 1 deletion includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
+-------------------------------------------------------------------------+
*/

if (version_compare(CACTI_VERSION, '1.3', '<')) {
// reports_run()/reports_queue()/reports_log_and_notify() are native in Cacti
// 1.3+. Load the compat shims only when they are actually missing: a develop
// build can report a version that compares < 1.3 while already defining them
// natively, and unconditionally including the shims would fatally redeclare them.
if (!function_exists('reports_run')) {
Comment thread
TheWitness marked this conversation as resolved.
require_once(__DIR__ . '/functions-pre13.php');
}

Expand Down
50 changes: 50 additions & 0 deletions tests/Unit/ReportsShimGuardTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
*/

/*
* Regression guard for includes/functions.php. On Cacti 1.3 the report helpers
* are native, so loading the plugin file must not redeclare them. CI checks out
* Cacti 1.2.x (helpers absent) and the bootstrap has already required
* functions.php, so this exercises the develop-only "natives present" path in a
* clean child process where the three functions are defined up front.
*/

it('loads functions.php without redeclaring the native report helpers', function () {
$functions = dirname(__DIR__, 2) . '/includes/functions.php';

expect(is_readable($functions))->toBeTrue();

$script = <<<'CHILD'
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Simulate Cacti 1.3, where these are defined natively before the plugin loads.
function reports_run($id) { return true; }
function reports_queue($name, $request_type, $source, $source_id, $command, $notification) {}
function reports_log_and_notify($id, $start_time, $report_type, $source, $source_id, $subject, &$raw_data, &$oput_raw, &$oput_html, &$oput_text, $attachments = [], $headers = []) {}

require $argv[1];

echo '<<<LOADED_OK>>>';
CHILD;

$tmp = tempnam(sys_get_temp_dir(), 'pre13_');
expect($tmp)->not->toBeFalse();

try {
file_put_contents($tmp, $script);

$command = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($tmp) . ' ' . escapeshellarg($functions);
$output = (string) shell_exec($command);

expect($output)->toContain('<<<LOADED_OK>>>');
expect($output)->not->toContain('redeclare');
} finally {
@unlink($tmp);
}
});
Loading