* feat(rendering): add view renderer abstraction
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* isolate renderer traversal test file
* Standardize renderer headers and endpoint guard
* style(renderer): use standard unit-test header in CactiRendererTest
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): reject null-byte paths before realpath
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: refresh sink and hotspot baselines for line shifts
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): guard root base path and template-dir redirect
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): canonicalize both paths in index.php direct-access guard
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening: normalize renderer base path to one separator
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): reject filesystem root as template path
A /-rooted renderer collapsed the containment prefix to /, which
str_starts_with() matches for every absolute path, so any file was
includable. Fail closed by refusing a root template path.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening: reject windows drive-root template path
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* refactor: adopt PHP 8.4 idioms in view renderer
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover renderer abstraction to full coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening(renderer): reject UNC template names and fix sink baselines
Refuse a leading-backslash (UNC) template name the same way absolute
POSIX paths are refused, skip the direct-request redirect when
SCRIPT_FILENAME carries a null byte, and correct the renderer include
and views redirect line numbers in the security baselines.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style: apply php-cs-fixer
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): use PHP 8.1-compatible readonly property in CactiRenderer
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening(rendering): drop template context array before include
Unset the internal context array after extract so an included template
only sees the extracted variables, not the full context.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: refresh security baselines for renderer line shift
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(renderer): simplify containment check and drain nested output buffers
The redundant real_path !== template_path comparison in
validateTemplateFile() can never be false once is_file()/is_dir() have
run, so drop it and keep the str_starts_with() prefix check as the
actual containment guard. renderFile() also only unwound a single
output buffer, so a template that opens (and leaves) its own buffer
could leak an ob level or drop its content; unwind every buffer opened
during rendering and reassemble them in the order they were written.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: refresh security baselines for renderer buffer/containment fix
The dynamic_include line for lib/renderer.php's include shifted again
after adding drainOutputBuffers().
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* feat(htmx): vendor htmx 2.0.6 and add opt-in filter loader
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover htmx filter loader
Add missing-vendored-file case for htmx_script_tag and mark the pre-bootstrap read_config_option guard as uncoverable.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: harden htmx loader harness and tighten enable check
Skip anything but an exact 'on' for htmx_enabled, reject 4xx/5xx fixture
responses, fail fast when the fixture base path is unresolved, pin
setup-php to a commit SHA, and reindent the e2e specs to tabs.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style: apply php-cs-fixer to htmx test files
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(htmx): drop duplicate script-tag src assertion
The subdir-install test repeated the preceding assertion; CACTI_PATH_URL is
fixed at bootstrap so it could not exercise a distinct scenario.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(e2e): drop sqlite3 from docker-php-ext-install
php:8.2-apache already ships sqlite3 built in, and its ext/sqlite3
source only carries config0.m4 (not config.m4), so building it
standalone always fails with "Cannot find config.m4", breaking the
e2e image build before Playwright ever runs.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(htmx): clear stat cache around version-file rename
Earlier tests already stat the version file via file_exists()/
file_get_contents(), so PHP's stat cache can report it present right
after these tests rename it away, making the assertions flaky.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(htmx): recompute script-tag cache-buster per call
The md5 cache-buster was cached in a static, so FPM/script_server
processes kept serving a stale ?v=... hash after an htmx.min.js
upgrade. Recompute it per call, matching get_md5_include_js() and
get_theme_paths() in lib/functions.php, and drop the 'v=' parameter
name to match their path + '?' + hash shape.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(e2e): drop obsolete MariaDB options
* ci(htmx): run the htmx integration test by path instead of a testsuite filter
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* build: vendor htmx unminified
Debian rejects minified sources. The file is the htmx 2.0.6 dist source; its
minified sibling hashes identically to what was committed, and the pinned SRI
is recomputed over the unminified file.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: address htmx review feedback
* test(e2e): resolve Cacti version through PHP
* test(htmx): harden portable server cleanup
* ci(actions): update checkout action pins
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>