From d355d1f796fdee37dd1f3810454645d2080f2e7a Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 13 May 2014 18:43:21 +0100 Subject: [PATCH] MDL-45535 CSS chunking breaks media rules if CSS invalid (IE) Invalid CSS with extra } symbols, which previously (by fluke) worked, was broken by recent chunking improvements. This change makes the chunking code robust against this (stupid) situation. --- lib/csslib.php | 6 ++++++ lib/tests/csslib_test.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/csslib.php b/lib/csslib.php index 03fcb15629f..19a7088d494 100644 --- a/lib/csslib.php +++ b/lib/csslib.php @@ -222,6 +222,12 @@ function css_chunk_by_selector_count($css, $importurl, $maxselectors = 4095, $bu } } else { $inrule--; + // Handle stupid broken CSS where there are too many } brackets, + // as this can cause it to break (with chunking) where it would + // coincidentally have worked otherwise. + if ($inrule < 0) { + $inrule = 0; + } } // We are not in a media query, and there is no pending rule, it is safe to split here. diff --git a/lib/tests/csslib_test.php b/lib/tests/csslib_test.php index a27749af32f..7b0aedbaed0 100644 --- a/lib/tests/csslib_test.php +++ b/lib/tests/csslib_test.php @@ -1229,6 +1229,23 @@ CSS; $this->assertCount(2, $chunks); $this->assertSame('a,b{}', $chunks[0]); $this->assertSame("@import url(styles.php?type=test&chunk=1);\n nav a:hover:after { content: \"↓\"; } b{ color:test;}", $chunks[1]); + + // Test that if there is broken CSS with too many close brace symbols, + // media rules after that point are still kept together. + $mediarule = '@media (width=480) {a{}b{}}'; + $css = 'c{}}' . $mediarule . 'd{}'; + $chunks = css_chunk_by_selector_count($css, 'styles.php?type=test', 2); + $this->assertCount(3, $chunks); + $this->assertEquals($mediarule, $chunks[1]); + + // Test that this still works even with too many close brace symbols + // inside a media query (note: that broken media query may be split + // after the break, but any following ones should not be). + $brokenmediarule = '@media (width=480) {c{}}d{}}'; + $css = $brokenmediarule . 'e{}' . $mediarule . 'f{}'; + $chunks = css_chunk_by_selector_count($css, 'styles.php?type=test', 2); + $this->assertCount(4, $chunks); + $this->assertEquals($mediarule, $chunks[2]); } /**