Repository navigation
perf(rrd): [1.2.x] reuse capability checks within calls - #8341
Conversation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
892201c to
00462f4
Compare
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
bmfmancini
left a comment
There was a problem hiding this comment.
Reviewed the full diff. The memoization is call-scoped ($supports_skip_past_updates / $supports_graph_formatters are locals initialized to null per function invocation), and get_rrdtool_version() is fixed for the process lifetime, so caching within rrdtool_function_update() and rrd_function_process_graph_options() cannot go stale. Verified on the diff that the only runtime semantics change is one fewer cacti_version_compare() per iteration; behavior for rrdtool < 1.5 is unchanged. The tokenization/eval usage is confined to the test fixture (tests/fixtures/UpdateCapabilities.php), not production code. All required checks pass (PHP 8.2/8.3/8.4 unit + RRDtool integration, changed-coverage >= 80%, POST guard, docker probe). Approving.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
a6e8f1a
Records merged 1.2.x fixes that deferred their entries: Cacti#8275, Cacti#8285, Cacti#8318, Cacti#8338, Cacti#8341 and Cacti#8350. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Records merged 1.2.x fixes that deferred their entries: Cacti#8275, Cacti#8285, Cacti#8318, Cacti#8338, Cacti#8341 and Cacti#8350. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Records merged 1.2.x fixes that deferred their entries: Cacti#8275, Cacti#8285, Cacti#8318, Cacti#8338, Cacti#8341 and Cacti#8350. Moves the unnumbered zoom entry from Cacti#8417 into the issue group. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Records merged 1.2.x fixes that deferred their entries: Cacti#8275, Cacti#8285, Cacti#8318, Cacti#8338, Cacti#8341 and Cacti#8350. Moves the unnumbered zoom entry from Cacti#8417 into the issue group. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(installer): [1.2.x] correct layout and test all shipped themes (Cacti#8325) * test(theme): cover shipped maintenance themes Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(installer): restore headings and fit narrow viewports Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(rrd): [1.2.x] recognize RRDtool 1.9 through 1.11 (Cacti#8354) * fix(rrd): recognize current RRDtool releases on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(security): record consolidated RRDtool version probe Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(graphs): clear empty query fields in rendered text (Cacti#8350) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(auth): escape the password-change username on 1.2.x (Cacti#8338) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(graphs): [1.2.x] preserve drilldown focus and bound SpikeKill mutations (Cacti#8316) * Graph drilldown: keep hamburger fixed, icons reachable, hide on graph leave The action-icon strip now slides down below the hamburger (flex column) instead of the hamburger dropping to the bottom of the icons. Closing is driven by leaving the whole graph rather than the small icon strip, so the mouse can move from the hamburger onto the icons without the strip closing. Leaving the graph also blurs the hamburger so it no longer lingers after interacting with it. * changelog: graph drilldown interaction fixes (Cacti#8316) * Graph drilldown: tolerate tooltip-induced mouseleave, drop hamburger title A native tooltip appearing over a drilldown icon fires a spurious mouseleave on the graph (relatedTarget null), which closed the strip. Defer the close and re-check the graph is genuinely not hovered first, so the icon tooltips no longer destabilize it. Also drop the hamburger's redundant title (its aria-label stays). * Graph drilldown: widen the close grace period to 500ms * Graph drilldown: tie hamburger visibility to the graph image Reveal the hamburger while the pointer is over the graph image (or the toggle overlaid on it) rather than anywhere in the graph cell, so moving off the image hides it after the grace period. Entering a different graph now immediately hides and closes any other graph's open strip. * Graph drilldown: lift the open graph so its strip clears thumbnails below With thumbnails a short graph's open icon strip overflows onto the graph below; sibling graphs paint in DOM order, so that graph rendered on top of the strip, making the icons unclickable and stealing the hover (which closed the strip). Raise the open graph (.graphDrillActive, position:relative; z-index) so its overflowing strip stays on top and the graph beneath is not hovered. * Graph drilldown: reveal via :focus-visible and stop blurring to preserve keyboard focus * fix(ui): preserve graph action focus during pointer navigation Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(ui): cover graph drilldown interactions and gate PR coverage Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: measure committed PR changes on a policy-compliant runner Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * feature#8316: label the graph drilldown strip as glyph+text rows When a graph's drilldown strip opens, initGraphDrilldown() rewrites it into one row per action - the glyph followed by its title as visible text - and removes the markup's <br> separators; graph_drilldown.css lays the rows out as a left-aligned menu below the hamburger. The transform runs lazily on open (only the single open strip, never all graphs at load) and once per strip, and derives each label from the inner <i title>, so plugin-contributed icons that follow the same .iconLink/<i title> convention are labelled without any plugin change. * test(e2e): cover drilldown label menu; simplify labelling; drop defensive br rule Widen the drilldown E2E fixture so the open labelled panel no longer overlaps the graph image centre (restoring the pointer/grace-period assertions), give its icons real glyphs+titles, and add a test asserting each action is labelled from its tooltip once (idempotent re-open). Fold the icon-label guard into a single branch so every rewritten line is exercised, and drop the defensive iconWrapper br display:none rule (the JS already removes the separators). * feature#8316: table-layout drilldown menu - text left, glyphs in a right column Render the open drilldown strip as a display:table menu: each action is a table-row with the label in a left-aligned cell and the glyph in a fixed-width right-hand cell, so the glyphs stack directly above one another. A few pixels of vertical cell padding separate the rows, and the row hover uses a theme-appropriate color-mix wash of the panel's text colour. The label is now prepended (left cell). * feature#8316: shorten core drilldown icon titles; cover full strip in markup probe Shorten the graph drilldown action titles so they read well as menu labels: Details, CSV Export, Time View, Realtime, Kill Spikes. Render the GraphDrilldownMarkup coverage probe with the realtime and spikekill realms enabled (and a second realtime-mode pass) so the now-changed conditional title lines keep 100% changed-line coverage. * feature#8316: label plugin glyphs lacking the drillDown class (fixes intropage eyeball) Core labelling only recognised glyphs with the drillDown class, so a plugin-contributed icon such as intropage's Add-to-Dashboard eye (a bare fa fa-eye with a title) rendered an empty, unlabelled row. Fall back to the first titled <i> in the link and style any glyph <i> as the right-hand table cell, so plugin icons are labelled and column-aligned without each plugin changing. * feature#8316: lower drilldown panel opacity, align glyph column, drop duplicate tooltip Make the open strip panel a touch more translucent (0.82 -> 0.6 alpha) so the graph shows through; nudge the glyph column's right padding so the glyphs line up directly under the hamburger; and strip the row/glyph title once the visible label is shown so no native/jQuery-UI tooltip duplicates the label text on hover. * feature#8316: make drilldown panel background more opaque (0.6 -> 0.85) * feature#8316: centre-align drilldown glyph column * feature#8316: nudge drilldown glyph column a few pixels left * feature#8316: theme-aware drilldown palette (per-theme fg/bg/accent, fix light-theme hamburger) Emit per-theme CSS custom properties (foreground, hamburger/panel backgrounds, hairline border and hover accent) as an inline style from graph_drilldown_icons(); graph_drilldown.css consumes them via var() with the prior dark values as fallback. Light themes now get a light pill with a dark glyph and a visible hairline border so the hamburger reads correctly, and the row highlight uses each theme's accent hue. * feature#8316: e2e assertion that the drilldown strip adopts the theme palette * feature#8316: move drilldown palette into theme CSS (:root vars); dos2unix theme main.css; add Time View/Realtime/Kill Spikes to pot * fix(spikekill): bind menu requests and protect mutations on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(spikekill): measure inline scripts and cover menu dismissal Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * perf(spikekill): skip disabled float debug formatting on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(spikekill): repair CLI dry-run statistics on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(spikekill): enforce RRA budgets and propagate failures on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(spikekill): cover zero-valued window boundaries on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: remove unused SpikeKill preference binding Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com> * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * security: batch 12 (1.2.x) - GHSA-5v3j data-input quoted-placeholder RCE + GHSA-vhh2 spikekill confirm (Cacti#8238) * security: batch 12 (1.2.x) - data-input quoted-placeholder RCE (GHSA-5v3j) + spikekill confirm (GHSA-vhh2) GHSA-5v3j-wcrr-jxjg: a Data Input template that wraps a <field> placeholder in a matched pair of quotes ("<arg1>") neutralized the value's own cacti_escapeshellarg() single-quoting, letting $(...) or backticks in a realm-3 user's field value execute on the next poll (bypassing the CVE-2026-39902 hardening). substitute_script_path() now consumes one matched pair of surrounding quotes when a token resolves, so the escaped value's quoting stays authoritative; unresolved tokens keep their literal form and the single-pass GHSA-fq9x behaviour holds. GHSA-vhh2-gghg-whjg: add a confirmation regression test that the spikekill poller escapes the --rrdfile path (fixed in Cacti#7235). Tests: tests/Unit/Security/DataInputQuotedPlaceholderTest.php (source + behavioral) and tests/Unit/Security/SpikekillRrdfileEscapeTest.php. Backport of the develop batch-12 fix (PR Cacti#8237). * security(batch12): update batch-11 fq9x regression test for quote-aware substitute_script_path The GHSA-5v3j quote-shedding changed substitute_script_path()'s regex and capture group, which the batch-11 fq9x test pinned verbatim. Update those two assertions to the quote-aware pattern marker and $matches[2]; the single-pass guarantee the test covers is unchanged. * security(batch12): drop the executable bit on the new security test files * security(batch12): make substitute_script_path fully quote-aware (GHSA-5v3j) Backport of the develop fix (Cacti#8237). The matched-pair quote shed only neutralised a token the template wrapped exactly ("<arg1>"). A token embedded in a larger quoted word ("prefix<arg1>", "<arg1>suffix", "<a><b>") kept the outer double quotes, so backticks/$(...) in the already-escaped value stayed live. Replace the regex with a single-pass shell-quote-state scanner: it still sheds an exact wrapping pair, but for any token inside a larger quoted word it briefly closes the template's quoting around the escaped value so it cannot be re-interpreted. Values are never re-scanned (single-pass, GHSA-fq9x retained). Updates the source assertions in DataInputQuotedPlaceholderTest and ShellInjection/ShellInjectionRegressionTest, and adds prefix/suffix/mixed regression cases. The eval-extract fallback is kept here because the 1.2.x unit bootstrap does not load lib/functions.php (unlike develop). * security: preserve template quoting for raw path tokens; relocate tests under ShellInjection/ Address review feedback on PR Cacti#8238: - substitute_script_path() now only sheds/closes template quotes for self-quoting (cacti_escapeshellarg) values. Trusted raw path_* tokens are substituted in place so a quoted "<path_php_binary>" keeps its quotes for shell_exec() and a bare <path_cacti>/scripts/x.php stays unquoted for the PHP script server, which realpath()s the first token. - Move DataInputQuotedPlaceholderTest and SpikekillRrdfileEscapeTest into tests/Unit/Security/ShellInjection/ and fix the repo-root lookup to dirname(__DIR__, 4). - Add a regression test asserting raw path tokens retain template quoting. * security: reword docblock to avoid sink-scanner false positive * security: keep substituting a token that follows a backslash in substitute_script_path * fix(security): protect script field quote boundaries on 1.2.x Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(security): cover script substitution and gate PR coverage Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: measure committed PR changes on a policy-compliant runner Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: model nested command substitution in substitute_script_path (GHSA-5v3j) Align the 1.2.x backport with the develop fix (Cacti#8237): replace the single quote-state scanner with a stack of parsing frames so a command substitution or backtick is scanned with its own fresh quoting context, exactly as /bin/sh re-parses it. A field placed inside a command substitution is judged against that nested (unquoted) context, so its own cacti_escapeshellarg() single quotes genuinely protect it and an outer double quote can no longer re-enable command substitution in the value. Brings the 1.2.x placeholder test to parity with develop, including the /bin/sh round-trip that proves each substituted word stays a safe literal and never expands. * test: cover nested command-substitution and backtick frames for changed-line coverage * test: cover $(...) and backtick template frames in changed-coverage fixture Mirror the develop ScriptSubstitutionMatrix nested-context cases so the pr-changed-coverage gate exercises the command-substitution and backtick frame handling in substitute_script_path(); revert the equivalent Pest addition to keep DataInputQuotedPlaceholderTest at parity with develop. * fix(security): reject unsupported nested shell syntax Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com> * test(poller): [1.2.x] add scoped regressions and weekly performance checks (Cacti#8285) * test(poller): add scoped regression gate and weekly performance backstop Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(poller): satisfy workflow policy and bound cold-cache queries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(poller): retry failed template metadata reads Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): defer release entries to final backlog PR Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(ci): include PHP 8.2 in polling release validation Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(poller): support acknowledged drains and stateful exclusions Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Repair maintenance unit collection without database bootstrap Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover empty poller mapping cache and failed read retries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: preserve shared source fixture exception boundaries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> * perf(rrd): [1.2.x] reuse capability checks within calls (Cacti#8341) * perf(rrd): [1.2.x] reuse capability checks within calls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(rrd): cover maintenance capability checks with native commands Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: preserve shared source fixture exception boundaries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(plugins): load poller.php before replicate_out in api_plugin_replicate_config (Cacti#8364) api_plugin_replicate_config() calls replicate_out(), which lives in lib/poller.php, but that library is not loaded during the early plugin config_arrays hook bootstrap. Commit aa1faf3 (Cacti#7235) removed the include_once that guarded this. With a remote poller present, enabling/replicating a plugin fatals with 'Call to undefined function replicate_out()'. Restore the include_once, matching api_plugin_drop_remote_table(). * security(1.2): pin Actions and isolate release signing (Cacti#8346) * security: pin maintenance Actions and isolate release signing Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): move release-signing entry to end of security section as -security#8346 --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> * Cross-filter Device and Graph Template on Preview and List views (Cacti#8362) * Cross-filter Device and Graph Template on Preview and List views On the Preview and List graph views, selecting a Device now narrows the Graph Template dropdown to the templates present on that device, and selecting a Graph Template narrows the Device list to the devices that have graphs of that template. * Make Tree view Graph Template dropdown sensitive to selected device On the Tree view, the Graph Template filter now lists only the templates present on the device selected in the tree, matching the Preview and List view behavior. * fix(test): drive CSP getCspMode tests via config_options_array bootstrap-unit.php (since Cacti#8285) loads lib/functions.php, which defines the real read_config_option and bypasses this test's function_exists-guarded stub, so getCspMode/isNonceMode read '' and failed. Inject the flag through config_options_array (the non-web cached-option seam read_config_option uses) so the tests pass under the shared bootstrap. * Address review: fix Graph Template multiselect reload and gate 'Not Templated' Remove the per-selection change handlers on #graph_template_id (Preview and List); the shared select2:close.graphTemplateSentinel handler already reloads once on close. Route that close-time reload to applyFilter() on the List view so site_id/location/rows are preserved and the in-flight request is not aborted. Only offer the 'Not Templated' sentinel when the current device filter has an allowed untemplated graph, so no empty device/template combination is presented. * Revert Cacti#7863 on 1.2.x: package_public_keys table does not exist (Cacti#8369) The backport introduced a package_public_keys trust store, but that table is not part of the 1.2.x schema (it is created by the 1.3.0 upgrade). Remove package_public_key_is_trusted() and its two call sites. The SHA-1 verification fallback is intentionally not restored; package_file_get_contents() now verifies with SHA-256 only. Signed-off-by: TheWitness <thewitness@cacti.net> * test: move maintenance PHPUnit configuration under tests (Cacti#8375) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: pull 1.2.x service images from GHCR (Cacti#8378) - Requires the develop change that adds ci-images.yml to merge and run first, so the GHCR copies exist. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: normalize maintenance configuration paths for Pest discovery (Cacti#8380) (cherry picked from commit 6fbf949) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Scope the tree Graph Templates filter to the drilled Device Template (Cacti#8371) * Scope the tree Graph Templates filter to the drilled Device Template When drilling a Site Branch into a Device Template (host_id=-1, host_template_id set), graph_view_template_host_where() applied no device restriction, so the tree Graph Templates filter listed every template. Scope it to the Graph Templates present on that Device Template's devices (within the Site when set). Only the tree view passes host_template_id, so the Preview/List callers are unaffected. * docs(CHANGELOG): add issue#8371 entry * Detect and repair RRDfile Data Source count mismatches via RRDtune (Cacti#8367) * Detect and repair RRDfile Data Source count mismatches via RRDtune Report when a Graph requires more or fewer Data Sources than its RRDfile contains, generate the rrdtool tune DS:/DEL: command to correct it, and run it when the RRDfile is writable. Applies to data_debug (rrdtool_cacti_compare) and the RRDchecker batch process (do_rrdcheck). The decision logic lives in pure helpers (rrdtool_cacti_compare_ds, rrdcheck_ds_findings) with unit tests. Resolves Cacti#8366 * rrdcheck: only probe local writability for local storage Under the storage proxy the RRDfile is remote, so is_resource_writable() checks the wrong filesystem. Skip the local probe when using the proxy and let it enforce remote permissions and report failures via its response. * rrdcheck: validate tune args, enforce RRA containment, fix failure detection Validate every tune specification against RRDtool's documented DS grammar (ds-name 1-19 [a-zA-Z0-9_], known DST, integer heartbeat, numeric-or-U min/max) and escape it before use. For local storage require the RRDfile to resolve inside the RRA directory via data_source_path_within_rra(). Detect failures from the real return value (false/null/empty or missing OK) instead of casting to string, so a failed tune is no longer logged as success. * rrd: normalize a 0/0 data source range to 0:U when building a tune add spec rrdtool_function_info_from_ds() passes min/max through unchanged, so a source stored as 0/0 produced DS:name:type:hb:0:0 which RRDtool rejects. Mirror RRD creation and emit 0:U so the repair paths can restore those sources. --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com> * fix: reject dangling symlinks in validate_relative_path_within (Cacti#8390) * fix: reject dangling symlinks in validate_relative_path_within Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs: add changelog entry for dangling symlink fix Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: pull the 1.2.x CDEF coverage MariaDB service from GHCR (Cacti#8385) - The anonymous Docker Hub pull fails with toomanyrequests before any test step runs. Requires the ci-images.yml change already on develop. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * themes: make search-result highlight readable on deepness and dark (Cacti#8397) Both themes set the .filteredValue search highlight to a neon yellow (#F8D93D) background with no text color. On these dark themes the light link/row text rendered on bright yellow was effectively unreadable. - deepness: use a warm gold that complements the emerald palette with a near-black (--dp-page) text color. - dark: match the develop branch (olive background with black text). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: allow configuration-only changes without a Clover report (Cacti#8384) * test: normalize maintenance configuration paths for Pest discovery Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> (cherry picked from commit 6fbf949) * test: keep maintenance bootstrap paths portable and allow XML-only coverage changes Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> * fix(security): restore maintenance package imports and guard script contexts (Cacti#8372) * fix(security): restore maintenance package trust checks and reject unsafe script contexts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: preserve trusted configured paths inside backticks Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci(tests): keep 1.2.x-only coverage configs off unrelated PRs Revert the incidental path normalization of tests/phpunit-poller-mapping.xml and tests/phpunit-rrd-capabilities.xml. Editing these two files triggered the poller-mapping and rrd-capability "Changed PHP lines >= 80%" coverage workflows (which key on those config paths). Once triggered, those gates require >=80% coverage of every changed production line, so the unrelated lib/functions.php and package_import.php security changes reported 0% and the gates failed. Both path forms resolve identically through prepare_config and nothing else consumes these configs, so reverting them is a no-op for the poller.php/rrd.php coverage checks while removing the spurious triggers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(security): reject ambiguous shell expansion contexts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: TheWitness <thewitness@cacti.net> * Add one-click RRDfile repair (Apply Suggested Fixes) to Data Source Info mode (Cacti#8400) * Add one-click RRDfile repair to Data Source Info mode The Data Source Info mode already compares the RRDfile against the Cacti definition and prints the rrdtool tune recommendations (add a missing Data Source with DS:name:type:heartbeat:min:max, remove an extra one with DEL:name, and correct the type, heartbeat, minimum and maximum). It did not, however, offer a way to apply them from the page the way data_debug.php does. - Add an "Apply Suggested Fixes" link to the "RRDtool Tune Info" box header when the web server can write the RRDfile; when it cannot, the header falls back to "Run Fix from Command Line" and the commands remain listed for manual use. - Add a ds_repair action that runs the same tune recommendations server-side (gated on data_source_authorized() and on the RRDfile being writable, and skipping any recommendation carrying control characters), logs each command to DSDEBUG, then reloads the Data Source so the result is visible. This mirrors data_debug.php's run_repair / "Apply Suggested Fixes". - Harden the Info-mode guard so a missing/unreadable RRDfile (rrdtool info returning false) no longer triggers an array-offset warning. * Address review: POST-guard ds_repair and harden repair result check - Route the "Apply Suggested Fixes" action through a CSRF-protected POST: the link now uses the cactiPostAction handler (href="#", data-url) instead of a GET navigation, and ds_repair is added to the $bad_actions guard in include/global.php so a tokenless request fails closed with 405. ds_repair is added to the curated CSRF action test for regression coverage. - Use a strict comparison on the rrdtool_execute() result: it can return null on a failed exec/proxy connection, and null == '' would have reported a failed repair as "All RRDfile repairs succeeded." - Refresh the sink inventory baseline. This adds the new header redirects in ds_repair and also absorbs pre-existing line-number drift (lib/functions.php and others) that already failed the sink guard on 1.2.x HEAD. * Address review: drop undefined helper and detect proxy repair success - Replace the undefined cacti_has_control_chars() check with an inline control-character test so a tune recommendation carrying control chars is skipped without a fatal undefined-function error. - Accept both an empty local result and the RRDtool proxy's raw 'OK u:...' status as success so repairs over the proxy are not misreported as failed. - Add the new translatable strings to locales/po/cacti.pot and reuse the existing failure msgid. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Co-authored-by: Weblate <noreply@weblate.org> Translate-URL: https://translate.cacti.net/projects/cacti/core-v1-2-x/ Translation: Cacti/core (v1.2.x) * Fix console content area right/bottom margins hiding scrollbar column and Save button (Cacti#8402) The console content area (.cactiConsoleContentArea / #navigation_right) is an internal scroll region whose height is set to fill the viewport by keepWindowSize() in layout.js. It had no right padding, so the vertical scrollbar sat flush against the right-aligned cells (for example the Data Source Info mode numbers on data_sources.php ds_edit), and no bottom padding, so the last element - the Save button - was flush against the scroll edge and could not be scrolled fully into view. Add box-sizing: border-box so the JS-set height absorbs the padding, then give the area a right scrollbar gutter and a bottom clearance in every bundled theme (classic, dark, deepness, modern, paper-plane, paw, sunrise). * ci(deps): bump actions/upload-artifact from 4.6.2 to 7.0.2 (Cacti#8407) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v4.6.2...cf430e0) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(deps): bump the github-actions-1-2-x group with 2 updates (Cacti#8406) Bumps the github-actions-1-2-x group with 2 updates: [shivammathur/setup-php](https://github.com/shivammathur/setup-php) and [actions/setup-node](https://github.com/actions/setup-node). Updates `shivammathur/setup-php` from 2.37.2 to 2.40.0 - [Release notes](https://github.com/shivammathur/setup-php/releases) - [Commits](shivammathur/setup-php@f3e473d...eb7c497) Updates `actions/setup-node` from 7.0.0 to 7.1.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v7...949feb2) --- updated-dependencies: - dependency-name: shivammathur/setup-php dependency-version: 2.40.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-1-2-x - dependency-name: actions/setup-node dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-1-2-x ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix return navigation from Time Graph View (Cacti#8414) * Fix return navigation from Time Graph View * Reference navigation fix in changelog * Render RRDtool Tune Info as balanced div boxes and POST the Data Source repair actions (Cacti#8413) * data_sources: render RRDtool Tune Info as balanced div boxes rrdtool_tune() emitted an unbalanced mix of html_header() and html_end_box() calls wrapped around raw table rows inside the single box opened by data_sources.php. The premature and extra closing tags corrupted the DOM, which (depending on theme) clipped the Save button at the bottom of the Data Source edit page while in Data Source Info mode. - Separate the execute, CLI and HTML code paths in rrdtool_tune() and, for HTML, render each section as a self contained, balanced div box. - Extract the nested print_leaves() definition into a standalone rrdtool_tune_print_leaves() function, matching the rrdtool_tune_* naming convention, and emit div rows instead of table rows. - Switch the data_sources.php wrapper box to div mode to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * data_debug: require POST for the Data Source repair actions Applying RRDfile repairs and rerunning the debugger are state changing operations, so they should not be reachable with a GET. Driving them through loadPage() GET requests also meant the follow up redirect was pulled into the content area, losing the theme and navigation on rerender. Convert the Apply Suggested Fixes and Rerun Analysis links to the existing cactiPostAction/data-url idiom (as data_sources.php already does for ds_repair) so they submit a token-bearing POST, add the matching csrf_require_post() guards on the run_repair and run_debug actions, and drop the now redundant click handlers. The read-only reloadquery refresh stays a GET. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * rrd: split rrdtool_tune into testable render and execute helpers Break rrdtool_tune() into small single-purpose helpers so each path can be exercised directly by unit tests (the web display path is otherwise unreachable under CACTI_CLI): - rrdtool_tune_print_leaves() takes an explicit $html flag instead of branching on CACTI_CLI, so both the div and plain-text branches are testable. - rrdtool_tune_execute() applies the tune/resize commands for a repair, keeping the control-character guards and storage_location handling. - rrdtool_tune_print_cli() prints the source commands as plain text. - rrdtool_tune_print_html() renders the balanced div boxes. - rrdtool_tune() becomes a thin dispatcher over the three. Add tests/Unit/Core/Rrd/RrdTuneRenderTest.php to the RRDtool capability coverage suite, covering the leaf printer, the HTML and CLI printers, the execute path (both storage_location branches) and the dispatcher, asserting the output is balanced div markup with no table rows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * review: add an executor test seam to rrdtool_tune_execute Address PR review feedback carried over from the develop PR: give rrdtool_tune_execute() an optional $executor parameter (matching rrdtool_dump_document) so the unit tests assert the tune and resize commands are actually executed, producing resize.rrd only when the resize command runs, instead of passing on the unconditional rename alone. The control-character guard retains dedicated coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * review: inject box renderers into rrdtool_tune_print_html Address the PR review finding that the test's global html_start_box / html_end_box stubs would redeclare the real helpers when the full Unit suite loads lib/html.php. Give rrdtool_tune_print_html() optional $open_box / $close_box seams (defaulting to html_start_box / html_end_box) so the unit test injects recording renderers instead of defining conflicting global functions. The test now asserts each section opens and closes a balanced box with the expected title, with no global helper declarations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refresh automatic graph end times after polling advances (Cacti#8415) * Refresh last poll when choosing automatic graph end time * Number the CHANGELOG entry and order the 1.2.x section Add the PR reference (-issue#8415) and apply the section order: security fixes first (sorted), then issues and features, each sorted by number ascending. This moves the issue entries that had been added above the security block (Cacti#8371, Cacti#8390, Cacti#8414) and puts out-of-order issue and feature entries into place. No entry text changes; the stray trailing space on the Cacti#8257 line is dropped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Measure automatic graph timing coverage in the real renderer --------- Co-authored-by: TheWitness <thewitness@cacti.net> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * tests: make the full unit suite runnable in one process (Cacti#8416) The shared unit bootstrap (tests/bootstrap-unit.php) skips global.php, so a couple of load-time prerequisites that library files expect were missing. Running the whole tests/Unit tree in a single process therefore aborted with fatals before completing: - Including lib/snmp.php reads $config['php_snmp_support'] at load time. The bootstrap never set it, so the strict test error handler turned the "Undefined array key" warning into a fatal, taking down every test that loads lib/snmp.php (much of Security/ and all of Scripts/). Mirror global.php and set the flag from class_exists('SNMP'). - lib/html.php declares html_escape() (and other helpers) unguarded. A test that defines a function_exists()-guarded stub for one of these ran first and defined it, then a later test that included lib/html.php hit a redeclaration fatal. Load lib/html.php in the bootstrap (like lib/functions.php) so the real helpers exist first and the guarded stubs become no-ops. With these two changes the full Unit suite runs to completion instead of crashing. Remaining individual test failures are pre-existing and unrelated to the harness. All targeted phpunit-*.xml configs that use this bootstrap still pass unchanged. Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix archive zoom targeting and graph refresh scroll jumps (Cacti#8417) * Keep zoom overlays on graphs with archive ID zero * Preserve graph dimensions during zoom refreshes * fix: Update the deepness favicon (Cacti#8418) * fix: Update the deepness favicon * QA: If the SVG is present, it's all we need. * Fix restrictive graph permission labels on 1.2.x (Cacti#8421) Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * feature: Add modern favicons svg images (Cacti#8423) This change aligns the other themes with the latest favicon enhancement * deps(deps): bump phpseclib/phpseclib (Cacti#8433) Bumps the composer-1-2-x group with 1 update: [phpseclib/phpseclib](https://github.com/phpseclib/phpseclib). Updates `phpseclib/phpseclib` from 4.0.1 to 4.0.2 - [Release notes](https://github.com/phpseclib/phpseclib/releases) - [Changelog](https://github.com/phpseclib/phpseclib/blob/master/CHANGELOG.md) - [Commits](phpseclib/phpseclib@4.0.1...4.0.2) --- updated-dependencies: - dependency-name: phpseclib/phpseclib dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: composer-1-2-x ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(layout): define spike removal URL locally Co-authored-by: Thomas Vincent <341181+somethingwithproof@users.noreply.github.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Signed-off-by: TheWitness <thewitness@cacti.net> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: TheWitness <thewitness@cacti.net> Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Muris <27321443+alcatron@users.noreply.github.com> Co-authored-by: Gitar <noreply@gitar.ai> Co-authored-by: Thomas Vincent <341181+somethingwithproof@users.noreply.github.com>
* docs(changelog): [1.2.x] consolidate backlog release notes Records merged 1.2.x fixes that deferred their entries: #8275, #8285, #8318, #8338, #8341 and #8350. Moves the unnumbered zoom entry from #8417 into the issue group. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): use associated issues for maintenance fixes Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net>
RRDtool update batches repeat the same 1.5 capability comparison for every timestamp; graph construction repeats the same 1.4 comparison for four options. Reuse the result within each call, including false, and recompute it on the next call. Public interfaces, command text and validation remain unchanged.
The regression executes the maintenance update body with instrumented process boundaries: two files, six timestamps, old/new RRDtool versions and a return to the old version. It fails before the change and passes afterward with 42 assertions. Native PHP 8.2.31 validates both production capability expressions and the update fixture; the focused existing Pest runner also passes. Full command/reference comparisons against the pre-change maintenance source remain identical. No dependency or CI changes.
This is the 1.2.x companion to the develop optimization, also carried in #8012. Release notes remain in the final changelog PR #8319.
Development companion: #8340.