From 5984fefe47dde48f86268dc3e5a86b68241cdd15 Mon Sep 17 00:00:00 2001 From: Roman Karpenko Date: Tue, 16 Apr 2013 23:36:43 +0400 Subject: [PATCH 1/3] Added correct parsing of unicode symbols fixed exception in parsing symbols like em dash or cyrillic letters. Tests are included --- lessc.inc.php | 97 ++++++++++++++++++++++------------- tests/inputs/utf_symbols.less | 15 ++++++ tests/outputs/utf_symbols.css | 9 ++++ 3 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 tests/inputs/utf_symbols.less create mode 100644 tests/outputs/utf_symbols.css diff --git a/lessc.inc.php b/lessc.inc.php index aaa86930..2296c932 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -3,7 +3,7 @@ /** * lessphp v0.3.9 * http://leafo.net/lessphp - * + * фыв * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran @@ -1328,9 +1328,9 @@ protected function coerceColor($value) { case 'color': return $value; case 'raw_color': $c = array("color", 0, 0, 0); - $colorStr = substr($value[1], 1); + $colorStr = mb_substr($value[1], 1); $num = hexdec($colorStr); - $width = strlen($colorStr) == 3 ? 16 : 256; + $width = mb_strlen($colorStr) == 3 ? 16 : 256; for ($i = 3; $i > 0; $i--) { // 3 2 1 $t = $num % $width; @@ -2114,7 +2114,16 @@ public function parse($buffer) { $this->pushSpecialBlock("root"); $this->eatWhiteDefault = true; $this->seenComments = array(); - + + if($this->is_utf8($this->buffer)){ + $overload = ini_get('mbstring.func_overload'); + if($overload && (int)$overload < 2){ + ini_set('mbstring.func_overload', 2); + } + if(ini_get('mbstring.internal_encoding') !== 'UTF-8'){ + ini_set('mbstring.internal_encoding', 'UTF-8'); + } + } // trim whitespace on head // if (preg_match('/^\s+/', $this->buffer, $m)) { // $this->line += substr_count($m[0], "\n"); @@ -2126,7 +2135,7 @@ public function parse($buffer) { $lastCount = $this->count; while (false !== $this->parseChunk()); - if ($this->count != strlen($this->buffer)) + if ($this->count != mb_strlen($this->buffer)) $this->throwError(); // TODO report where the block was opened @@ -2386,7 +2395,7 @@ protected function expHelper($lhs, $minP) { while (true) { $whiteBefore = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); + ctype_space($this->char($this->buffer, $this->count - 1)); // If there is whitespace before the operator, then we require // whitespace after the operator for it to be an expression @@ -2404,7 +2413,7 @@ protected function expHelper($lhs, $minP) { $whiteAfter = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); + ctype_space($this->char($this->buffer, $this->count - 1)); if (!$this->value($rhs)) break; @@ -2454,7 +2463,7 @@ protected function parenValue(&$out) { $s = $this->seek(); // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") { + if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) != "(") { return false; } @@ -2479,7 +2488,7 @@ protected function value(&$value) { $s = $this->seek(); // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") { + if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) == "-") { // negation if ($this->literal("-", false) && (($this->variable($inner) && $inner = array("variable", $inner)) || @@ -2633,7 +2642,7 @@ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null $tok = $m[2]; - $this->count-= strlen($tok); + $this->count-= mb_strlen($tok); if ($tok == $end) { if ($nestingLevel == 0) { break; @@ -2653,11 +2662,12 @@ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null } if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) { + $ount = null; break; } $content[] = $tok; - $this->count+= strlen($tok); + $this->count+= mb_strlen($tok); } $this->eatWhiteDefault = $oldWhite; @@ -2695,11 +2705,11 @@ protected function string(&$out) { while ($this->match($patt, $m, false)) { $content[] = $m[1]; if ($m[2] == "@{") { - $this->count -= strlen($m[2]); + $this->count -= mb_strlen($m[2]); if ($this->interpolation($inter, false)) { $content[] = $inter; } else { - $this->count += strlen($m[2]); + $this->count += mb_strlen($m[2]); $content[] = "@{"; // ignore it } } elseif ($m[2] == '\\') { @@ -2708,7 +2718,7 @@ protected function string(&$out) { $content[] = $delim; } } else { - $this->count -= strlen($delim); + $this->count -= mb_strlen($delim); break; // delim } } @@ -2724,6 +2734,22 @@ protected function string(&$out) { return false; } + protected function char($string, $position){ + return mb_substr($string ,$position, 1, 'UTF-8'); + } + + protected function is_utf8($string) { + return preg_match('%(?: + [\xC2-\xDF][\x80-\xBF] + |\xE0[\xA0-\xBF][\x80-\xBF] + |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} + |\xED[\x80-\x9F][\x80-\xBF] + |\xF0[\x90-\xBF][\x80-\xBF]{2} + |[\xF1-\xF3][\x80-\xBF]{3} + |\xF4[\x80-\x8F][\x80-\xBF]{2} + )+%xs', $string); + } + protected function interpolation(&$out) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = true; @@ -2747,7 +2773,7 @@ protected function interpolation(&$out) { protected function unit(&$unit) { // speed shortcut if (isset($this->buffer[$this->count])) { - $char = $this->buffer[$this->count]; + $char = $this->char($this->buffer, $this->count); if (!ctype_digit($char) && $char != ".") return false; } @@ -2761,7 +2787,7 @@ protected function unit(&$unit) { // a # color protected function color(&$out) { if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) { - if (strlen($m[1]) > 7) { + if (mb_strlen($m[1]) > 7) { $out = array("string", "", array($m[1])); } else { $out = array("raw_color", $m[1]); @@ -2877,7 +2903,7 @@ protected function mixinTags(&$tags) { // a bracketed value (contained within in a tag definition) protected function tagBracket(&$value) { // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") { + if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) != "[") { return false; } @@ -2938,7 +2964,7 @@ protected function tag(&$tag, $simple = false) { continue; } - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") { + if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) == "@") { if ($this->interpolation($interp)) { $hasExpression = true; $interp[2] = true; // don't unescape @@ -3061,7 +3087,7 @@ protected function keyword(&$word) { protected function end() { if ($this->literal(';')) { return true; - } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') { + } elseif ($this->count == mb_strlen($this->buffer) || $this->buffer{$this->count} == '}') { // if there is end of file or a closing block next then we don't need a ; return true; } @@ -3129,10 +3155,9 @@ protected function guard(&$guard) { protected function literal($what, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; - // shortcut on single letter if (!isset($what[1]) && isset($this->buffer[$this->count])) { - if ($this->buffer[$this->count] == $what) { + if ($this->char($this->buffer, $this->count) == $what) { if (!$eatWhitespace) { $this->count++; return true; @@ -3146,7 +3171,6 @@ protected function literal($what, $eatWhitespace = null) { if (!isset(self::$literalCache[$what])) { self::$literalCache[$what] = lessc::preg_quote($what); } - return $this->match(self::$literalCache[$what], $m, $eatWhitespace); } @@ -3185,7 +3209,7 @@ protected function to($what, &$out, $until = false, $allowNewline = false) { $validChars = $allowNewline ? "." : "[^\n]"; } if (!$this->match('('.$validChars.'*?)'.lessc::preg_quote($what), $m, !$until)) return false; - if ($until) $this->count -= strlen($what); // give back $what + if ($until) $this->count -= mb_strlen($what); // give back $what $out = $m[1]; return true; } @@ -3194,9 +3218,10 @@ protected function to($what, &$out, $until = false, $allowNewline = false) { protected function match($regex, &$out, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; - $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais'; - if (preg_match($r, $this->buffer, $out, null, $this->count)) { - $this->count += strlen($out[0]); + $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Aisu'; + $buffer = mb_substr($this->buffer ,$this->count, mb_strlen($this->buffer), 'UTF-8'); + if (preg_match($r, $buffer, $out, null)) { + $this->count += mb_strlen($out[0]); if ($eatWhitespace && $this->writeComments) $this->whitespace(); return true; } @@ -3212,13 +3237,13 @@ protected function whitespace() { $this->append(array("comment", $m[1])); $this->commentsSeen[$this->count] = true; } - $this->count += strlen($m[0]); + $this->count += mb_strlen($m[0]); $gotWhite = true; } return $gotWhite; } else { $this->match("", $m); - return strlen($m[0]) > 0; + return mb_strlen($m[0]) > 0; } } @@ -3244,7 +3269,7 @@ public function throwError($msg = "parse error", $count = null) { $count = is_null($count) ? $this->count : $count; $line = $this->line + - substr_count(substr($this->buffer, 0, $count), "\n"); + mb_substr_count(mb_substr($this->buffer, 0, $count, 'UTF-8'), "\n"); if (!empty($this->sourceName)) { $loc = "$this->sourceName on line $line"; @@ -3307,7 +3332,7 @@ protected function removeComments($text) { while (true) { // find the next item foreach ($look as $token) { - $pos = strpos($text, $token); + $pos = mb_strpos($text, $token); if ($pos !== false) { if (!isset($min) || $pos < $min[1]) $min = array($token, $pos); } @@ -3321,27 +3346,27 @@ protected function removeComments($text) { switch ($min[0]) { case 'url(': if (preg_match('/url\(.*?\)/', $text, $m, 0, $count)) - $count += strlen($m[0]) - strlen($min[0]); + $count += mb_strlen($m[0]) - mb_strlen($min[0]); break; case '"': case "'": if (preg_match('/'.$min[0].'.*?'.$min[0].'/', $text, $m, 0, $count)) - $count += strlen($m[0]) - 1; + $count += mb_strlen($m[0]) - 1; break; case '//': - $skip = strpos($text, "\n", $count); - if ($skip === false) $skip = strlen($text) - $count; + $skip = mb_strpos($text, "\n", $count); + if ($skip === false) $skip = mb_strlen($text) - $count; else $skip -= $count; break; case '/*': if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) { - $skip = strlen($m[0]); + $skip = mb_strlen($m[0]); $newlines = substr_count($m[0], "\n"); } break; } - if ($skip == 0) $count += strlen($min[0]); + if ($skip == 0) $count += mb_strlen($min[0]); $out .= substr($text, 0, $count).str_repeat("\n", $newlines); $text = substr($text, $count + $skip); diff --git a/tests/inputs/utf_symbols.less b/tests/inputs/utf_symbols.less new file mode 100644 index 00000000..7ba46eaf --- /dev/null +++ b/tests/inputs/utf_symbols.less @@ -0,0 +1,15 @@ +ul { + li { + &:before { + content: "—"; + } + } + &:after { + content: "©—©"; + } +} +div { + &:before { + content: "Привет, мир!"; + } +} diff --git a/tests/outputs/utf_symbols.css b/tests/outputs/utf_symbols.css new file mode 100644 index 00000000..dead8390 --- /dev/null +++ b/tests/outputs/utf_symbols.css @@ -0,0 +1,9 @@ +ul li:before { + content: "—"; +} +ul:after { + content: "©—©"; +} +div:before { + content: "Привет, мир!"; +} From 0a9b3c90c0bb046e57fc6fd39d697e4f0b1e3d11 Mon Sep 17 00:00:00 2001 From: Roman Karpenko Date: Tue, 16 Apr 2013 23:42:21 +0400 Subject: [PATCH 2/3] removed typo --- lessc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lessc.inc.php b/lessc.inc.php index 2296c932..711bb18d 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -3,7 +3,7 @@ /** * lessphp v0.3.9 * http://leafo.net/lessphp - * фыв + * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran From b8c0fbba99d79ca00985319538de53268b044cb5 Mon Sep 17 00:00:00 2001 From: Roman Karpenko Date: Wed, 17 Apr 2013 23:14:06 +0400 Subject: [PATCH 3/3] more smart way for fixing utf-8 files parse error Parse error appears only if you had set mbstring.internal_encoding UTF-8 --- lessc.inc.php | 110 ++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 61 deletions(-) diff --git a/lessc.inc.php b/lessc.inc.php index 711bb18d..e66d300d 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -3,7 +3,7 @@ /** * lessphp v0.3.9 * http://leafo.net/lessphp - * + * * LESS css compiler, adapted from http://lesscss.org * * Copyright 2012, Leaf Corcoran @@ -1328,9 +1328,9 @@ protected function coerceColor($value) { case 'color': return $value; case 'raw_color': $c = array("color", 0, 0, 0); - $colorStr = mb_substr($value[1], 1); + $colorStr = substr($value[1], 1); $num = hexdec($colorStr); - $width = mb_strlen($colorStr) == 3 ? 16 : 256; + $width = strlen($colorStr) == 3 ? 16 : 256; for ($i = 3; $i > 0; $i--) { // 3 2 1 $t = $num % $width; @@ -1647,6 +1647,14 @@ public function compile($string, $name = null) { $locale = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, "C"); + $internal_encoding = NULL; + // only if mbstring installed + if (function_exists('mb_orig_strlen')) { + $internal_encoding = ini_get('mbstring.internal_encoding'); + if(!is_null($internal_encoding)){ + ini_set('mbstring.internal_encoding', NULL); + } + } $this->parser = $this->makeParser($name); $root = $this->parser->parse($string); @@ -1666,6 +1674,9 @@ public function compile($string, $name = null) { $this->formatter->block($this->scope); $out = ob_get_clean(); setlocale(LC_NUMERIC, $locale); + if(!is_null($internal_encoding)){ + ini_set('mbstring.internal_encoding', $internal_encoding); + } return $out; } @@ -2106,6 +2117,7 @@ public function __construct($lessc, $sourceName = null) { } public function parse($buffer) { + $this->count = 0; $this->line = 1; @@ -2114,16 +2126,7 @@ public function parse($buffer) { $this->pushSpecialBlock("root"); $this->eatWhiteDefault = true; $this->seenComments = array(); - - if($this->is_utf8($this->buffer)){ - $overload = ini_get('mbstring.func_overload'); - if($overload && (int)$overload < 2){ - ini_set('mbstring.func_overload', 2); - } - if(ini_get('mbstring.internal_encoding') !== 'UTF-8'){ - ini_set('mbstring.internal_encoding', 'UTF-8'); - } - } + // trim whitespace on head // if (preg_match('/^\s+/', $this->buffer, $m)) { // $this->line += substr_count($m[0], "\n"); @@ -2135,7 +2138,8 @@ public function parse($buffer) { $lastCount = $this->count; while (false !== $this->parseChunk()); - if ($this->count != mb_strlen($this->buffer)) + + if ($this->count != strlen($this->buffer)) $this->throwError(); // TODO report where the block was opened @@ -2395,7 +2399,7 @@ protected function expHelper($lhs, $minP) { while (true) { $whiteBefore = isset($this->buffer[$this->count - 1]) && - ctype_space($this->char($this->buffer, $this->count - 1)); + ctype_space($this->buffer[$this->count - 1]); // If there is whitespace before the operator, then we require // whitespace after the operator for it to be an expression @@ -2413,7 +2417,7 @@ protected function expHelper($lhs, $minP) { $whiteAfter = isset($this->buffer[$this->count - 1]) && - ctype_space($this->char($this->buffer, $this->count - 1)); + ctype_space($this->buffer[$this->count - 1]); if (!$this->value($rhs)) break; @@ -2463,7 +2467,7 @@ protected function parenValue(&$out) { $s = $this->seek(); // speed shortcut - if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) != "(") { + if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") { return false; } @@ -2488,7 +2492,7 @@ protected function value(&$value) { $s = $this->seek(); // speed shortcut - if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) == "-") { + if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") { // negation if ($this->literal("-", false) && (($this->variable($inner) && $inner = array("variable", $inner)) || @@ -2642,7 +2646,7 @@ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null $tok = $m[2]; - $this->count-= mb_strlen($tok); + $this->count-= strlen($tok); if ($tok == $end) { if ($nestingLevel == 0) { break; @@ -2662,12 +2666,11 @@ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null } if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) { - $ount = null; break; } $content[] = $tok; - $this->count+= mb_strlen($tok); + $this->count+= strlen($tok); } $this->eatWhiteDefault = $oldWhite; @@ -2705,11 +2708,11 @@ protected function string(&$out) { while ($this->match($patt, $m, false)) { $content[] = $m[1]; if ($m[2] == "@{") { - $this->count -= mb_strlen($m[2]); + $this->count -= strlen($m[2]); if ($this->interpolation($inter, false)) { $content[] = $inter; } else { - $this->count += mb_strlen($m[2]); + $this->count += strlen($m[2]); $content[] = "@{"; // ignore it } } elseif ($m[2] == '\\') { @@ -2718,7 +2721,7 @@ protected function string(&$out) { $content[] = $delim; } } else { - $this->count -= mb_strlen($delim); + $this->count -= strlen($delim); break; // delim } } @@ -2734,22 +2737,6 @@ protected function string(&$out) { return false; } - protected function char($string, $position){ - return mb_substr($string ,$position, 1, 'UTF-8'); - } - - protected function is_utf8($string) { - return preg_match('%(?: - [\xC2-\xDF][\x80-\xBF] - |\xE0[\xA0-\xBF][\x80-\xBF] - |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} - |\xED[\x80-\x9F][\x80-\xBF] - |\xF0[\x90-\xBF][\x80-\xBF]{2} - |[\xF1-\xF3][\x80-\xBF]{3} - |\xF4[\x80-\x8F][\x80-\xBF]{2} - )+%xs', $string); - } - protected function interpolation(&$out) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = true; @@ -2773,7 +2760,7 @@ protected function interpolation(&$out) { protected function unit(&$unit) { // speed shortcut if (isset($this->buffer[$this->count])) { - $char = $this->char($this->buffer, $this->count); + $char = $this->buffer[$this->count]; if (!ctype_digit($char) && $char != ".") return false; } @@ -2787,7 +2774,7 @@ protected function unit(&$unit) { // a # color protected function color(&$out) { if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) { - if (mb_strlen($m[1]) > 7) { + if (strlen($m[1]) > 7) { $out = array("string", "", array($m[1])); } else { $out = array("raw_color", $m[1]); @@ -2903,7 +2890,7 @@ protected function mixinTags(&$tags) { // a bracketed value (contained within in a tag definition) protected function tagBracket(&$value) { // speed shortcut - if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) != "[") { + if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") { return false; } @@ -2964,7 +2951,7 @@ protected function tag(&$tag, $simple = false) { continue; } - if (isset($this->buffer[$this->count]) && $this->char($this->buffer, $this->count) == "@") { + if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") { if ($this->interpolation($interp)) { $hasExpression = true; $interp[2] = true; // don't unescape @@ -3087,7 +3074,7 @@ protected function keyword(&$word) { protected function end() { if ($this->literal(';')) { return true; - } elseif ($this->count == mb_strlen($this->buffer) || $this->buffer{$this->count} == '}') { + } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') { // if there is end of file or a closing block next then we don't need a ; return true; } @@ -3155,9 +3142,10 @@ protected function guard(&$guard) { protected function literal($what, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; + // shortcut on single letter if (!isset($what[1]) && isset($this->buffer[$this->count])) { - if ($this->char($this->buffer, $this->count) == $what) { + if ($this->buffer[$this->count] == $what) { if (!$eatWhitespace) { $this->count++; return true; @@ -3171,6 +3159,7 @@ protected function literal($what, $eatWhitespace = null) { if (!isset(self::$literalCache[$what])) { self::$literalCache[$what] = lessc::preg_quote($what); } + return $this->match(self::$literalCache[$what], $m, $eatWhitespace); } @@ -3209,7 +3198,7 @@ protected function to($what, &$out, $until = false, $allowNewline = false) { $validChars = $allowNewline ? "." : "[^\n]"; } if (!$this->match('('.$validChars.'*?)'.lessc::preg_quote($what), $m, !$until)) return false; - if ($until) $this->count -= mb_strlen($what); // give back $what + if ($until) $this->count -= strlen($what); // give back $what $out = $m[1]; return true; } @@ -3218,10 +3207,9 @@ protected function to($what, &$out, $until = false, $allowNewline = false) { protected function match($regex, &$out, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; - $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Aisu'; - $buffer = mb_substr($this->buffer ,$this->count, mb_strlen($this->buffer), 'UTF-8'); - if (preg_match($r, $buffer, $out, null)) { - $this->count += mb_strlen($out[0]); + $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais'; + if (preg_match($r, $this->buffer, $out, null, $this->count)) { + $this->count += strlen($out[0]); if ($eatWhitespace && $this->writeComments) $this->whitespace(); return true; } @@ -3237,13 +3225,13 @@ protected function whitespace() { $this->append(array("comment", $m[1])); $this->commentsSeen[$this->count] = true; } - $this->count += mb_strlen($m[0]); + $this->count += strlen($m[0]); $gotWhite = true; } return $gotWhite; } else { $this->match("", $m); - return mb_strlen($m[0]) > 0; + return strlen($m[0]) > 0; } } @@ -3269,7 +3257,7 @@ public function throwError($msg = "parse error", $count = null) { $count = is_null($count) ? $this->count : $count; $line = $this->line + - mb_substr_count(mb_substr($this->buffer, 0, $count, 'UTF-8'), "\n"); + substr_count(substr($this->buffer, 0, $count), "\n"); if (!empty($this->sourceName)) { $loc = "$this->sourceName on line $line"; @@ -3332,7 +3320,7 @@ protected function removeComments($text) { while (true) { // find the next item foreach ($look as $token) { - $pos = mb_strpos($text, $token); + $pos = strpos($text, $token); if ($pos !== false) { if (!isset($min) || $pos < $min[1]) $min = array($token, $pos); } @@ -3346,27 +3334,27 @@ protected function removeComments($text) { switch ($min[0]) { case 'url(': if (preg_match('/url\(.*?\)/', $text, $m, 0, $count)) - $count += mb_strlen($m[0]) - mb_strlen($min[0]); + $count += strlen($m[0]) - strlen($min[0]); break; case '"': case "'": if (preg_match('/'.$min[0].'.*?'.$min[0].'/', $text, $m, 0, $count)) - $count += mb_strlen($m[0]) - 1; + $count += strlen($m[0]) - 1; break; case '//': - $skip = mb_strpos($text, "\n", $count); - if ($skip === false) $skip = mb_strlen($text) - $count; + $skip = strpos($text, "\n", $count); + if ($skip === false) $skip = strlen($text) - $count; else $skip -= $count; break; case '/*': if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) { - $skip = mb_strlen($m[0]); + $skip = strlen($m[0]); $newlines = substr_count($m[0], "\n"); } break; } - if ($skip == 0) $count += mb_strlen($min[0]); + if ($skip == 0) $count += strlen($min[0]); $out .= substr($text, 0, $count).str_repeat("\n", $newlines); $text = substr($text, $count + $skip);