33 Commits
Author SHA1 Message Date
TheWitnessandTheWitness 3ab4c69fb7 PHPStan Level 8 - Phase 1 Conversion (#8135)
* PHPStan Level 8 - Phase 1 Conversion

Reduces the real (no-baseline) PHPStan level 8 error count from ~2,724 to 425
and regenerates phpstan-baseline.neon accordingly (8,941 -> 1,921 lines).

Core type-safety changes
- lib/database.php: narrow db_fetch_row()/db_fetch_row_prepared() to return
  array (was bool|array) and db_fetch_assoc()/db_fetch_assoc_prepared() to
  return array (was mixed); the _prepared workers coerce the connection-failure
  path to an empty array so the declared type is honest. empty()/cacti_sizeof()
  checks are unaffected.
- lib/database.php: narrow $db_conn guards from is_object() to instanceof PDO in
  the transaction/quote/insert-id helpers so the PDO calls resolve.
- lib/mib_cache.php: the fluent MibCache methods mib()/object()/table()/row()
  now return self instead of a bare object so chained calls type-check.

Type-safety casts and guards (mechanical, behaviour-preserving)
- Cast string|false/|null builtin results feeding string parameters
  (json_decode, base64_encode, trim, htmle, preg_replace, explode, etc.).
- Cast int|string / int|false values feeding int id/pid parameters.
- Guard resource|false fopen()/popen() handles before fwrite/fclose/fread, and
  wrap foreach over array|false/list|false results with `?: []`.

Genuine bugs found and fixed
- cli/add_tree.php / lib/api_tree.php: site tree nodes could not be created via
  the CLI - the --site-id option was never parsed, $nodeTypes had no 'site'
  entry (passing null to api_tree_item_save(int $type) -> TypeError), and
  api_tree_item_save() never persisted site_id. All three fixed.
- tree.php: leaves_exist() is typed : int but returned db_fetch_assoc_prepared()
  (an array of rows) for a SELECT COUNT(*); now uses db_fetch_cell_prepared()
  and returns the scalar count.
- lib/mib_cache.php: $entries_per_object was a float (division / ceil) used as
  an array key (PHP 8.1 implicit float-to-int key deprecation); now cast to int.

Config
- .phpstan.neon: add notIdentical.alwaysTrue and booleanAnd.alwaysFalse to the
  existing always-true/false ignore family (same "PHPStan gets confused"
  dynamic-constant cause already covered by identical.alwaysTrue,
  notEqual.alwaysTrue, booleanAnd.leftAlwaysTrue, etc.).
- phpstan-baseline.neon: regenerated; the remaining 425 entries are the
  untouched long tail for Phase 2.

* Remove redundant @phpstan-ignore comments

Follow-up cleanup for the level 8 Phase 1 work. Removes 14 inline
@phpstan-ignore comments that no longer suppress any reported error:

- cli/repair_database.php: `@phpstan-ignore booleanAnd.alwaysFalse` is now
  covered by the global booleanAnd.alwaysFalse ignore added to .phpstan.neon.
- 13 others (host.php, include/global.php, include/session.php,
  lib/api_automation.php x2, lib/functions.php x2, lib/html_utility.php x2,
  lib/installer.php, lib/package.php, lib/reports.php, lib/rrd.php) no longer
  match any reported error after the type-safety fixes (e.g. the
  db_fetch_row_prepared() return-type narrowing removed the offset-assign
  errors the api_automation ignores were suppressing).

Verified with reportUnmatchedIgnoredErrors enabled: 0 unmatched ignores
remain and the full level 8 run still reports 0 errors.

* ci: satisfy validator ratchet and refresh security sink baselines

- lib/api_tree.php: give the new tree-item site_id a real numeric
  constraint ('^[-0-9]+$', matching html_reports.php) instead of an
  empty regex, so the validator constraint ratchet passes without
  bumping its baseline.
- tests/security/baselines: refresh the three sink/hotspot signatures
  whose code text changed from the (string) casts added in this branch
  (lib/poller.php setsid, cli/rrdresize.php json_encode, lib/import.php
  simplexml_load_string).

* ci(js): allow DOMPurify 3.4.16 and update sync_js pin test

The dependabot bump (#8134) moved package.json/package-lock.json to
DOMPurify 3.4.16 on develop but left tests/js/sync_js.test.mjs pinned to
3.4.15, so the PR merge commit fails the 'DOMPurify is pinned' contract.
Bring package.json/package-lock.json to 3.4.16 (matching develop) and
update the pin test to expect 3.4.16.

* test: update sql.php null-handling assertion for the (string) cast

This branch changed scripts/sql.php from trim(\ ?? '') to
trim((string) \) (the phpstan-safe form that coerces both null and
false from shell_exec()). Update SqlScriptsTest's null-return assertion
to match the new cast instead of the removed '?? ''.

* fix: address Copilot review - ownership IDs, fopen guards, mib_cache bound

- chown()/chgrp(): pass integer UID/GID from fileowner()/filegroup()
  (guarding the false lookup) instead of string-casting them, which made
  them resolve account/group names like '1001' and fail. Covers
  lib/api_device.php, lib/boost.php and poller_maintenance.php (x2).
- fopen() failure now short-circuits instead of reporting success:
  lib/package.php returns false, lib/clog_webapi.php and utilities.php
  render an error, and snmpagent_mibcachechild.php skips the cache write
  and sentinel unlink so a concurrent writer's lock is preserved.
- lib/mib_cache.php: keep the float quotient as the loop bound and cast
  only the array offset, so a non-even entries/columns split no longer
  truncates the loop and drops a cached row.

* revert: keep db_fetch_* returning false on error; baseline Level 8 instead

Per review, restoring the intentional fail-safe: db_fetch_row[_prepared]()
return bool|array and db_fetch_assoc[_prepared]() return mixed again, so a
genuine SQL error (not just a missing connection) is signalled as false and
the === false checks in cdef_is_in_use(), boost_process_* and aggregate.php
work as before. Dropped the is_array() ? : [] coercion.

Level 8 stays green by regenerating phpstan-baseline.neon to capture the
re-introduced bool|array/mixed call-site errors (the ~1,850 the narrowing
had eliminated). Tightening those callers to drop them from the baseline is
Phase 2 work.

---------

Co-authored-by: TheWitness <copilot@users.noreply.github.com>
2026-10-02 10:08:56 -04:00
Thomas VincentandTheWitness 891017ea2c fix: use gmp for Counter32/Counter64 wrap math in ss_net_snmp_disk_* (#7142)
* fix: use gmp for Counter32/Counter64 wrap math in ss_net_snmp_disk_*

The wrap-correction expressions in ss_net_snmp_disk_bytes.php embedded
the literal 18446744073709551616 (2^64), which exceeds PHP_INT_MAX on
every supported runtime and is silently promoted to float. Each Counter64
wrap therefore lost ~3 decimal digits of precision, producing spurious
zero, negative, or NaN deltas on busy storage arrays.

ss_net_snmp_disk_io.php used intval() on Counter32 values, which
saturates at 2^31-1 on 32-bit PHP and on the wrap branch silently
truncates legitimate values into negative deltas.

Both scripts now route every wrap correction through a small
ss_counter_step() helper that uses ext-gmp (already required in
composer.json) for arbitrary-precision arithmetic, and falls back to
float when gmp is missing. Same control flow, same accumulator
semantics, no behavioural change on the no-wrap branch.

Test plan: smoke-checked the helper against synthetic Counter64 wrap
(current=100, previous=18446744073709551500) and confirmed the delta
returns the expected 216 byte difference instead of a float collapse.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* style: document disk counter running value

* ci: update phpstan baseline

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
2026-05-13 10:21:15 -04:00
Thomas VincentandCopilot 78e4644f9f fix: harden data collection scripts — SQL injection, counter math, column allow-listing (#6651)
* cleanup: remove unreachable defensive error logs in aggregate graph item validation

* fix: harden data collection scripts with correct SNMP retry parameter

Replace $host['ping_retries'] with $host['snmp_retries'] across all
SNMP data collection scripts. Add column allow-lists for MikroTik
scripts to prevent SQL injection via column name interpolation.

Add Pest tests verifying column allow-lists reject injection attempts
and all scripts reference snmp_retries instead of ping_retries.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix: consolidate disk device detection with preg_match

Replace 8 str_starts_with() calls with a single preg_match() in
ss_net_snmp_disk_io.php for readability. Align ss_net_snmp_disk_bytes.php
with the same device prefixes (xvd, vd, hd, md, dm-) and improved
nvme-aware partition filter.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore: drop unrelated lib/api_aggregate changes

Keep PR scope focused on the issue for this branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-05 20:09:08 -05:00
TheWitnessandCopilot fb1d7ea006 Put the Scripts Directory in Scope for Quality Checks (#6584)
* Allow form_selectable_cell to more easily port

* Removing exclusion for scripts directory

* More fixes for scripts

* Some issues with ss_host_disk.php that passed locally

* More issues not detected locally

* Issues with typing in cacti_snmp_walk

* Adding base files for non-savy composer users

* One more try on ss_host_disk.php

* Aparantly I have to add the lock file

* More changes to lib/snmp.php after testing

* More changes to lib/snmp.php after testing

* Fix number script from Copilot review

* More Composer reviews

* Update scripts/ss_apache_stats.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update scripts/motorola_surfboard_SB6141.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update scripts/motorola_surfboard_SB6141.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Changing syntax of PHP requirement

* Updating composer

* Attempt to quiet some warnings

* Add Syntax Check

* Wrong file name

* Wrong file name

* Better to report before and after

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-30 08:04:27 -05:00
TheWitness 27919c50d7 Updating Copyrights to 2026 (#6578) 2026-01-28 16:11:10 -05:00
TheWitnessandCopilot b993471579 Fix #6539 - Allow Standard Cacti Log Files to be Rotated on Demand,PHPdoc, and Typing (#6540)
* Fix #6539 - Allow Standard Cacti Log Files to be Rotated on Demand from the Cacti UI

* QA: php-cs-fixer updates and documentation for lib/database.php

* QA: Update .gitignore for composer files

* QA: Update .gitignore for composer files

* QA: Back off .gitignore change its duplicated

* QA: Fix typing of db_has_permissions

* QA: Fixing typing issue in db_format_index_create

* Update lib/clog_webapi.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* QA: Fix additional code issues

* QA: Applying more defaults to add device

* QA: Fix at the database layer

* QA: Fixes based upon automated testing

* QA: Fix at the database layer

* QA: After new SQL checking

* QA: Skip MacTrack oui database download warnings

* QA: Fixing type issue

* QA: Recommendation from Copilot

* QA: Recommendation from Copilot

* QA: Recommendation from Copilot

* QA: Recommendation from Copilot

* QA: Some minor changes to avoid errors in testing

* QA: Unused variable

* QA: Recommendation from Copilot

* QA: Recommendation from Copilot

* QA: Recommendation from Copilot

* QA: Minor introduced code defect

* QA: Adding some unifying space around concatination

* QA: Consistent comments and new function alias'

* QA: Multi-line comment corrections

* QA: Fix SQL Style

* QA: Missed one function alias

* QA: PHPStan Level 2 and PHPDoc fixes

* QA: PHPStan Level 2 and PHPDoc Fixes

* QA: PHPStan Level 6 Fixes

* QA: Fix lib/xml.php to PHPStan Level 6

* QA: Wrong grep -v

* PHPStan Level 6 for lib/vdef.php

* PHPStan Level 8 for lib/time.php

* QA: Raise PHPStan to Level 6 for lib/database.php

* QA: Remove @deprecated tag from grv()

* QA: Switch to htmle() alias over html_escape()

* QA: More addressing PHPStan issues at Level 6

* QA: Change recommended by Copilot for Readability

* QA: More PHPStan fixes

* QA: More PHPStan fixes

* QA: More PHPStan fixes for lib/utility.php

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: Raise PHPStan to Level 6 More Functions

* QA: More PHPStan fixes at Level 6

* QA: Some phpseclib3 fixups to update to latest

* QA: More fixups for graphing for magic strings

* QA: More PHPStan fixes at Level 6

* QA: Fixing order string type on get_allowed_graphs()

* QA: Fixing improper use of print

* QA: Optimization of color_templates

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Copilot recommendation

* QA: Raise PHPStan to Level 6 More Functions

* QA: Issues insalling Cacti

* QA: Issues insalling Cacti

* QA: Issues insalling Cacti

* QA: Issues insalling Cacti

* QA: Issues insalling Cacti

* QA: Issues testing Cacti

* QA: Copilot recommendation

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: More PHPStan fixes at Level 6

* QA: Installer failing

* Undo ownership changes to remove tar errors

* QA: Updates after php-cs-fixer

* QA: Adding code checks to syntax checking

* QA Change syntax flow language

* QA: Reduce the number of cures

* QA: Use sequentional option

* Change runner to self-hosted for check job

* Fix typo in OS version in workflow file

* Add Git installation step in workflow

Added step to install Git if not already installed.

* Add '-y' flag to apt-get install and update commands

Updated apt-get commands to include '-y' for automatic confirmation.

* Change workflow OS version to 'ubuntu-latest'

Updated the workflow to use 'ubuntu-latest' instead of 'ubuntu:latest' and modified the 'runs-on' configuration.

* Remove sequential option from phpcsfixer script

* Remove PHPCS fixer step from workflow

Removed PHP coding standards check from workflow.

* Move code checks to before plugins

Moving these core checks to before the plugins are installed as we really want to check only the base Cacti here.

* Add Composer validation and caching to start of workflow

* QA: Addressing PHPStan additional

* QA: Restore composer lock file

* QA: Addressing PHPStan additional

* QA: Addressing PHPStan additional

* QA: Complete LDAP Project

* QA: php-cs-fixer doing it's thing

* QA: Syntax is already happening in PHPStan

* QA: The md5 function no longer exists

* QA: Update after ldap changes

* QA: Undo that last password hack

* QA: Attempting to switch to MariaDB 11.8

* QA: Attempting to switch to MariaDB 11.8

* QA: Resolving some issues with PHP8.4

* QA: Resolving some issues with PHP8.4

* QA: Add PHP8.5 to the matrix

* QA: Removing PHP8.5 due to dependency issues

* QA: Add the DB version to the testing output

* QA: Switch back to MySQL for the moment

* QA: More fidelity in reporting

* QA: The pipe must be mixed

* QA: Moving audit_schema.php changes from 1.2.x

* QA: Moving audit_schema.php changes from 1.2.x

* QA: Restore mysql monitoring

* QA: php-cs-fixer issues

* QA: Attempt to roll back to MariaDB 10.6

* QA: Attempt to fix check_all_pages.sh

* QA: Make installer functional again

* QA: Fix installer php-cs-fixer issues

* QA: Type to a string

* QA: Get the database version correctly

* QA: Fix issue with reports in check_all_pages.sh

* QA: Check the server version in the right place

* Feature: Support SHA256 as a new hash for passwords

* QA: Function definition and return typing audit

* QA: Refinement of form types

* QA: Refinement of form types

* QA: Consistency of comments

* QA: Issues with php-cs-fixer and more comments

* QA: More typing issues

* QA: php-cs-fixer on merge conflict resolution

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-25 10:13:56 -05:00
TheWitness 2c779273f9 Copyright Updates and PHP-CS-Fixer updates 2025-03-09 14:34:19 -04:00
Jimmy ConnerandTheWitness 65ab16f5cf Start converting to newer PHP Syntax and Functions (#6103)
* Add Rector

* Add Rector

* Fix "Cashed" misspelling

Also harmonize the phrase with the one below it

* Fix implode error in db_table_create

Only relevant when multiple primary keys

* Fix auth issue, parentheses in the wrong location

Was causing too many arguments to be sent to cacti_sizeof which only take 1, instead of get_allowed_devices.

* Fix issue with session_var not properly using class variable

* Fix pass by reference error in get_allowed_devices

get_allowed_devices has a pass by reference on the "total_rows" field.  It is used in several places to pass the total_rows back to a counter.  Here though, we are passing a number directly to the function, which errors out with "Uncaught Error: get_allowed_devices(): Argument #4 ($total_rows) cannot be passed by reference".  So we will just place a dummy variable in front to catch the pass.

This wasn't caught before because the previous parentheses issue.

* Fix undefined variable "field_array" in html_filter

* Fix undefined function 'get_nfilter_filter_request_var'

* Fix undefined variable 'resizable'

I corrected the function parameter, as that was technically the incorrect spelling

* Fix invalid variable $user_id

* Fix undefined vars in spikekill class

* Fix copy and paste error

Oops

* Forgot to use the dummy variables

* Add missing $

Oops

* Start converting to newer PHP Syntax and Functions

* Test fixing the workflow by install composer

* Lets not valid the composer file right now
Seems we have a few things to fix it in

* Validate composer

* Lite formating changes

* lite formatting

* lite formatting

* lite format changes

* lite format changes

* lite format changes

* lite format changes

* lite format changes

* lite format changes

* lite format changes

* lite format changes

---------

Co-authored-by: TheWitness <thewitness@cacti.net>
2025-02-23 15:14:54 -05:00
TheWitness 0058fef482 QA: Merging Security Updates from 1.2.x into develop 2025-01-26 13:43:37 -05:00
TheWitness 1c8ba30e7a QA: Fix: #5990 - SQL Errors on upgrade 2024-12-13 08:59:23 -05:00
TheWitness afcd847639 Revert "QA: Don't use CRLF. Use LF"
This reverts commit 60d42af89c.
2024-12-11 22:47:42 -05:00
TheWitness 60d42af89c QA: Don't use CRLF. Use LF 2024-12-11 22:42:45 -05:00
TheWitness 22b85e1622 Fix: #5966 - Add snmp retries at the device level
* This covers all the built in scripts.  Several packages will need rebuild
2024-12-06 23:07:32 -05:00
TheWitness 1aa72d24c9 QA: Update Copyright to 2024 2024-02-03 14:18:57 -05:00
TheWitness 36320c49a3 Fixing #5264 - Net-SNMP Disk I/O Templates are not Cluster Aware
If you Cacti poller can fail from hostA or hostB, you need this capability.
2023-04-02 15:00:43 -04:00
TheWitness ca7a352286 QA: Porting 1.2.24 Changes back to the Develop Branch (#5246) 2023-02-24 03:48:31 +00:00
Mark Brugnoli-Vinten e4d60297fd Update copyright year for 2023 2023-01-04 13:36:25 +00:00
Mark Brugnoli-Vinten 8b29d12cc9 Define cacti system paths as constants for better code checking (#5120)
This also provides a full run of src-fixer against all files to
ensure all code is now in alignment.

Closes #5120
2023-01-01 01:03:15 +00:00
TheWitness 66030b6090 QA: If the hostname does not exist, just return no data 2022-08-07 16:40:09 -04:00
TheWitness bbe899a731 QA: Two issues with ss_net_snmp_disk_*.php scripts 2022-02-20 13:09:47 -05:00
TheWitness df556a6cce QA: Support NVME and Virtual Disks 2022-02-19 13:39:53 -05:00
TheWitness b4405c1707 Some PSR for ss_fping and add missing copyrights and mark executable 2022-02-13 09:55:08 -05:00
TheWitness e6f918e11f Fixing Issue #3847
Cacti 1.2.14 Real-Time Graphs not working
2020-10-17 11:06:48 -04:00
cigamit fb45855912 Correct two issues from the latest script cleanup 2019-02-18 22:39:48 -06:00
cigamit 33d99b73ff Update scripts to be more consistent 2019-02-18 07:57:04 -06:00
netniV 89f0a06216 Resolving issue #2304 and #2311
This commit corrects a previous unseen issue where the PHP environment at command line level is being populated with environment variables normally only seen when called from a web server.

issue#2304: Installation progress stays at 0%
issue#2311: Unable to update PHP location during installation due to incorrect CLI environment

The new check uses the php_sapi_name() function to verify that we are indeed at 'cli' level.  All other values returned by php_sapi_name are considered non-cli including 'cli-server' which is for client/server scenarios.

Most checks have now been replaced by a single defintion ('CACTI_CLI') to define whether in CLI mode.  If a script is only to be called from CLI it must either defined 'CACTI_CLI_ONLY' or include include/cli_check.php instead of include/global.php.
2019-01-15 13:57:50 +00:00
Mark Brugnoli-Vinten 1ca32862a9 Resolving issue #1920 (#1922)
* Resolving issue #1920

* Minor QA issue
2018-09-14 20:59:52 -05:00
cigamit 7737c01115 Audit of PHP Collection Scripts
- Double to single quotes
- Prepared Statements
- "\n" to PHP_EOL
2018-04-07 10:41:09 -05:00
Tony Roman 8a179d7d7f Fix up to move if elseif else blocks to PSR 2017-05-07 19:57:36 -04:00
cigamit 9b4e1c542f Resolving Issue #225 2017-01-20 09:11:39 -06:00
cigamit 4184558663 Correct for first poll undefined index and make compatible with either host_id or hostname as input 2016-12-28 15:29:27 -06:00
cigamit 0f36a9dbed debugging errors in collectors 2016-09-10 15:23:12 -05:00
cigamit b0940967c8 updating net-snmp scripts 2016-09-10 12:32:21 -05:00