File tree Expand file tree Collapse file tree 5 files changed +40
-2
lines changed
Symfony/Component/CssSelector Expand file tree Collapse file tree 5 files changed +40
-2
lines changed Original file line number Diff line number Diff line change 22
33This project adheres to [ Semantic Versioning] ( https://semver.org/spec/v2.0.0.html ) .
44
5+ ## [ 2.8.1] ( https://github.com/woocommerce/email-editor/releases/tag/2.8.1 ) - 2026-02-20
6+
7+ - Patch - Fix unbounded static cache memory leaks in vendor-prefixed CSS inlining dependencies (emogrifier and symfony/css-selector) for long-running processes. [ #63365 ]
8+
59## [ 2.8.0] ( https://github.com/woocommerce/email-editor/releases/tag/2.8.0 ) - 2026-02-17
610
711- Minor - Fix spacing issues in email editor product collection rendering. [ #63177 ]
Original file line number Diff line number Diff line change 55 "license" : " GPL-2.0-or-later" ,
66 "prefer-stable" : true ,
77 "minimum-stability" : " dev" ,
8- "version" : " 2.8.0 " ,
8+ "version" : " 2.8.1 " ,
99 "autoload" : {
1010 "classmap" : [
1111 " src/" ,
Original file line number Diff line number Diff line change @@ -389,6 +389,7 @@ private function clearAllCaches(): void
389389 self ::CACHE_KEY_SELECTOR => [],
390390 self ::CACHE_KEY_COMBINED_STYLES => [],
391391 ];
392+ DeclarationBlockParser::clearCache ();
392393 }
393394
394395 /**
Original file line number Diff line number Diff line change @@ -19,6 +19,17 @@ final class DeclarationBlockParser
1919 */
2020 private static $ cache = [];
2121
22+ /**
23+ * Clears the static declaration block cache.
24+ *
25+ * This should be called between processing separate HTML documents to prevent
26+ * unbounded memory growth in long-running processes.
27+ */
28+ public static function clearCache (): void
29+ {
30+ self ::$ cache = [];
31+ }
32+
2233 /**
2334 * CSS custom properties (variables) have case-sensitive names, so their case must be preserved.
2435 * Standard CSS properties have case-insensitive names, which are converted to lowercase.
Original file line number Diff line number Diff line change @@ -29,6 +29,13 @@ class CssSelectorConverter
2929 private $ translator ;
3030 private $ cache ;
3131
32+ /**
33+ * Maximum number of cached items per prefix before LRU eviction kicks in.
34+ *
35+ * @var int
36+ */
37+ public static $ maxCachedItems = 200 ;
38+
3239 private static $ xmlCache = [];
3340 private static $ htmlCache = [];
3441
@@ -64,6 +71,21 @@ public function __construct(bool $html = true)
6471 */
6572 public function toXPath (string $ cssExpr , string $ prefix = 'descendant-or-self:: ' )
6673 {
67- return $ this ->cache [$ prefix ][$ cssExpr ] ?? $ this ->cache [$ prefix ][$ cssExpr ] = $ this ->translator ->cssToXPath ($ cssExpr , $ prefix );
74+ if (isset ($ this ->cache [$ prefix ][$ cssExpr ])) {
75+ // Promote to most-recently-used position.
76+ $ value = $ this ->cache [$ prefix ][$ cssExpr ];
77+ unset($ this ->cache [$ prefix ][$ cssExpr ]);
78+
79+ return $ this ->cache [$ prefix ][$ cssExpr ] = $ value ;
80+ }
81+
82+ $ value = $ this ->translator ->cssToXPath ($ cssExpr , $ prefix );
83+
84+ if (\count ($ this ->cache [$ prefix ] ?? []) >= self ::$ maxCachedItems ) {
85+ // Evict least-recently-used entry.
86+ unset($ this ->cache [$ prefix ][\array_key_first ($ this ->cache [$ prefix ])]);
87+ }
88+
89+ return $ this ->cache [$ prefix ][$ cssExpr ] = $ value ;
6890 }
6991}
You can’t perform that action at this time.
0 commit comments