{$key} ) ) { return $ablocks_settings->{$key}; } return $default; } /** * Responsive breakpoint widths (px) for the whole plugin. User-configurable * via Settings; defaults preserve the historical 800/480 values. Every CSS * generator and the block editor reads these so breakpoints stay in sync. */ /** * Make one CSS property or declaration value safe to write into a stylesheet. * * Block attributes reach the compiled CSS verbatim and that CSS is echoed * inside a `` closes the * element and everything after it is parsed as HTML — a stored XSS * available to anyone who can set a block attribute, which includes a * Contributor editing their own draft. `{` and `}` are the same problem one * level down: they close the rule and let the value choose its own * selector. * * Only those four characters are removed. A declaration value never needs * them, and everything a real one does need survives: data URIs (which * carry `;`), gradients, `calc()` and `var()` (parentheses and commas), * font stacks (quotes), `content` escapes (backslashes), and shorthand * slashes such as `font: 12px/1.5`. * * `;` is deliberately kept. With the braces gone, an injected `;` can only * add declarations to the same rule — which targets the block's own * element, exactly what its style controls already allow — so removing it * would break data URIs to buy nothing. * * @param mixed $value A CSS property name or declaration value. * @return string The value with the escape characters removed. */ public static function esc_css_value( $value ) { if ( ! is_scalar( $value ) ) { return ''; } return str_replace( [ '<', '>', '{', '}' ], '', (string) $value ); } /** * Strip the characters a CSS selector must never contain when it is about * to be emitted inside an inline ``, `{`, `}` or `;` would break out of the style * block and run as HTML (CVE-2026-40804). Every block author is expected * to `sanitize_html_class()` their attribute first — this is a sink-side * safety net so that forgetting it cannot be exploited. * * The grammar left intact covers everything an aBlocks block legitimately * writes: whitespace / descendant combinator, child / sibling combinators * (`>` `+` `~`), class and id markers (`.` `#`), the `[attr=value]` * attribute selector, pseudo-class / pseudo-element colons (`:` `::`), * commas for selector lists, parentheses for `:is()` / `:not()`, dashes * and underscores inside identifiers, and the `{{WRAPPER}}` placeholder. * Angle brackets, braces, semicolons, backslashes, backticks and newlines * are stripped — none of them are needed in a selector and all of them * are the characters that let an attacker escape the surrounding `