Compare commits

...

2 Commits

Author SHA1 Message Date
Andy Miller
15cb068f95 fix for grav not picking up config + page changes
Signed-off-by: Andy Miller <rhuk@mac.com>
2025-12-12 16:29:43 -07:00
Andy Miller
d34213232b avoid mail in twig content trigger security error
Signed-off-by: Andy Miller <rhuk@mac.com>
2025-12-12 16:20:35 -07:00
3 changed files with 52 additions and 17 deletions

View File

@@ -41,21 +41,13 @@ trait CompiledFile
$file = PhpFile::instance(CACHE_DIR . "compiled/files/{$key}{$this->extension}.php");
$cacheFilename = $file->filename();
// Improved support for opcache
// Do not check timestamp if opcache.validate_timestamps = 0
// https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.validate-timestamps
$modified = false;
// Always check file modification time for cache invalidation.
// This respects Grav's cache.check.method setting and user expectations.
// filemtime() is cheap and ensures changes are detected.
$modified = $this->modified();
if (!filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) ||
filter_var(ini_get('opcache.validate_timestamps'), \FILTER_VALIDATE_BOOLEAN)) {
$modified = $this->modified();
}
// Improved support for opcache
//
// If not modified and file exists in opcache
// This requires opcache.enable_file_override = 1
// https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.enable-file-override
// If file hasn't been modified and cache exists, load from compiled cache.
// When opcache is enabled, this benefits from bytecode caching.
if (!$modified && is_file($cacheFilename)) {
try {
// Include the file directly to trigger loading from opcache

View File

@@ -379,7 +379,8 @@ class Security
];
// Build combined patterns (compile once, use many times)
$quotedFunctions = array_map(fn($f) => preg_quote($f, '/'), $bad_twig_functions);
// Use word boundaries to avoid false positives (e.g., 'mail' matching 'email')
$quotedFunctions = array_map(fn($f) => '\b' . preg_quote($f, '/') . '\b', $bad_twig_functions);
$functionsPattern = implode('|', $quotedFunctions);
// Pattern for functions in Twig blocks

View File

@@ -103,6 +103,12 @@ class ConfigServiceProvider implements ServiceProviderInterface
// Save file list cache for next request
static::saveCachedFileList($locator, $cache, 'blueprints', $setup->environment, $files);
// Also invalidate the compiled blueprints cache to force rebuild
$masterBlueprints = "{$cache}/master-{$setup->environment}.php";
if (file_exists($masterBlueprints)) {
@unlink($masterBlueprints);
}
}
$blueprints = new CompiledBlueprints($cache, $files, GRAV_ROOT);
@@ -139,6 +145,12 @@ class ConfigServiceProvider implements ServiceProviderInterface
// Save file list cache for next request
static::saveCachedFileList($locator, $cache, 'config', $setup->environment, $files);
// Also invalidate the compiled config cache to force rebuild
$masterConfig = "{$cache}/master-{$setup->environment}.php";
if (file_exists($masterConfig)) {
@unlink($masterConfig);
}
}
$compiled = new CompiledConfig($cache, $files, GRAV_ROOT);
@@ -185,6 +197,12 @@ class ConfigServiceProvider implements ServiceProviderInterface
// Save file list cache for next request
static::saveCachedFileList($locator, $cache, 'languages', $setup->environment, $files);
// Also invalidate the compiled languages cache to force rebuild
$masterLanguages = "{$cache}/master-{$setup->environment}.php";
if (file_exists($masterLanguages)) {
@unlink($masterLanguages);
}
}
}
@@ -226,7 +244,7 @@ class ConfigServiceProvider implements ServiceProviderInterface
}
/**
* Load cached file list if still valid (based on directory mtimes).
* Load cached file list if still valid (based on directory and file mtimes).
*
* @param UniformResourceLocator $locator
* @param string $cacheDir
@@ -257,11 +275,21 @@ class ConfigServiceProvider implements ServiceProviderInterface
}
}
// Validate cache by checking individual file mtimes
if (isset($cache['file_mtimes'])) {
foreach ($cache['file_mtimes'] as $file => $mtime) {
$currentMtime = @filemtime($file);
if ($currentMtime === false || $currentMtime !== $mtime) {
return null;
}
}
}
return $cache['files'];
}
/**
* Save file list to cache with directory mtimes for validation.
* Save file list to cache with directory and file mtimes for validation.
*
* @param UniformResourceLocator $locator
* @param string $cacheDir
@@ -275,6 +303,19 @@ class ConfigServiceProvider implements ServiceProviderInterface
// Collect all directories that were scanned based on type
$directories = [];
// Collect mtimes for all individual config files
$fileMtimes = [];
foreach ($files as $group) {
foreach ($group as $item) {
if (isset($item['file'])) {
$filePath = GRAV_ROOT . '/' . $item['file'];
if (file_exists($filePath)) {
$fileMtimes[$filePath] = filemtime($filePath);
}
}
}
}
// Type-specific base directories
if ($type === 'config') {
$basePaths = $locator->findResources('config://');
@@ -337,6 +378,7 @@ class ConfigServiceProvider implements ServiceProviderInterface
'environment' => $environment,
'timestamp' => time(),
'directories' => $directories,
'file_mtimes' => $fileMtimes,
'files' => $files,
];