Security audit fixes: regex hardening, performance, and code quality (v1.1.2)
All checks were successful
Create Release Package / PHP Lint (push) Successful in 1m32s
Create Release Package / PHPUnit Tests (push) Successful in 2m35s
Create Release Package / Build Release (push) Successful in 2m36s

- WidgetRenderer: single regex for h2→h4 prevents mismatched tags
- ContextBuilder: O(n) comment tree with parent-indexed lookup map
- ContextBuilder: consolidated sidebar queries into single check
- ContextBuilder: transient caching for sidebar recent posts and tags
- functions.php: hex-to-RGB consolidation, type hints, ctype_xdigit validation
- Transient invalidation hooks for save_post and tag CRUD operations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 01:02:12 +01:00
parent ea2ccef5de
commit 17728e81d9
6 changed files with 110 additions and 44 deletions

View File

@@ -320,6 +320,24 @@ add_action( 'save_post_wp_global_styles', function () {
delete_transient( 'wp_bootstrap_variation_css_' . md5( get_stylesheet() ) );
} );
/**
* Invalidate sidebar transient caches when content changes.
*
* @since 1.2.0
*/
add_action( 'save_post', function () {
delete_transient( 'wp_bootstrap_sidebar_recent_4' );
} );
add_action( 'create_post_tag', function () {
delete_transient( 'wp_bootstrap_sidebar_tags_15' );
} );
add_action( 'edit_post_tag', function () {
delete_transient( 'wp_bootstrap_sidebar_tags_15' );
} );
add_action( 'delete_post_tag', function () {
delete_transient( 'wp_bootstrap_sidebar_tags_15' );
} );
/**
* Build Bootstrap surface CSS variables for a given background/foreground pair.
*
@@ -378,17 +396,12 @@ endif;
* @return string RGB triplet (e.g. "13,110,253") or empty string on failure.
*/
if ( ! function_exists( 'wp_bootstrap_hex_to_rgb' ) ) :
function wp_bootstrap_hex_to_rgb( $hex ) {
$hex = ltrim( $hex, '#' );
if ( strlen( $hex ) === 3 ) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
if ( strlen( $hex ) !== 6 ) {
function wp_bootstrap_hex_to_rgb( string $hex ): string {
$rgb = wp_bootstrap_hex_to_rgb_array( $hex );
if ( ! $rgb ) {
return '';
}
return hexdec( substr( $hex, 0, 2 ) ) . ','
. hexdec( substr( $hex, 2, 2 ) ) . ','
. hexdec( substr( $hex, 4, 2 ) );
return implode( ',', $rgb );
}
endif;
@@ -403,7 +416,7 @@ endif;
* @return string Resulting hex color.
*/
if ( ! function_exists( 'wp_bootstrap_mix_hex' ) ) :
function wp_bootstrap_mix_hex( $color1, $color2, $weight ) {
function wp_bootstrap_mix_hex( string $color1, string $color2, float $weight ): string {
$c1 = wp_bootstrap_hex_to_rgb_array( $color1 );
$c2 = wp_bootstrap_hex_to_rgb_array( $color2 );
if ( ! $c1 || ! $c2 ) {
@@ -425,12 +438,12 @@ endif;
* @return array|false Array of [r, g, b] or false on failure.
*/
if ( ! function_exists( 'wp_bootstrap_hex_to_rgb_array' ) ) :
function wp_bootstrap_hex_to_rgb_array( $hex ) {
function wp_bootstrap_hex_to_rgb_array( string $hex ): array|false {
$hex = ltrim( $hex, '#' );
if ( strlen( $hex ) === 3 ) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
if ( strlen( $hex ) !== 6 ) {
if ( strlen( $hex ) !== 6 || ! ctype_xdigit( $hex ) ) {
return false;
}
return array(
@@ -450,7 +463,7 @@ endif;
* @return float Relative luminance.
*/
if ( ! function_exists( 'wp_bootstrap_relative_luminance' ) ) :
function wp_bootstrap_relative_luminance( $hex ) {
function wp_bootstrap_relative_luminance( string $hex ): float {
$rgb = wp_bootstrap_hex_to_rgb_array( $hex );
if ( ! $rgb ) {
return 0.0;