From 087edeb2d5b36e52107e4ada31863748209c1dba Mon Sep 17 00:00:00 2001 From: Matthias Mullie Date: Wed, 25 Jan 2017 16:46:20 +0100 Subject: [PATCH] Stricter checks for not importing absolute paths Fixes #100 --- src/CSS.php | 73 +++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/src/CSS.php b/src/CSS.php index 117a1d8..2d24002 100644 --- a/src/CSS.php +++ b/src/CSS.php @@ -120,16 +120,7 @@ protected function combineImports($source, $content, $parents) (?P["\']?) # fetch path - (?P - - # do not fetch data uris, external sources or absolute paths - (?!( - ["\']? - (data:|https?:\\/\\/|\\/) - )) - - .+? - ) + (?P.+?) # (optional) close path enclosure (?P=quotes) @@ -164,16 +155,7 @@ protected function combineImports($source, $content, $parents) (?P["\']) # fetch path - (?P - - # do not fetch data uris, external sources or absolute paths - (?!( - ["\']? - (data:|https?:\\/\\/|\\/) - )) - - .+? - ) + (?P.+?) # close path enclosure (?P=quotes) @@ -211,33 +193,33 @@ protected function combineImports($source, $content, $parents) // only replace the import with the content if we can grab the // content of the file - if ($this->canImportFile($importPath)) { - // check if current file was not imported previously in the same - // import chain. - if (in_array($importPath, $parents)) { - throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.'); - } + if (!$this->canImportByPath($match['path']) || !$this->canImportFile($importPath)) { + continue; + } - // grab referenced file & minify it (which may include importing - // yet other @import statements recursively) - $minifier = new static($importPath); - $importContent = $minifier->execute($source, $parents); + // check if current file was not imported previously in the same + // import chain. + if (in_array($importPath, $parents)) { + throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.'); + } - // check if this is only valid for certain media - if (!empty($match['media'])) { - $importContent = '@media '.$match['media'].'{'.$importContent.'}'; - } + // grab referenced file & minify it (which may include importing + // yet other @import statements recursively) + $minifier = new static($importPath); + $importContent = $minifier->execute($source, $parents); - // add to replacement array - $search[] = $match[0]; - $replace[] = $importContent; + // check if this is only valid for certain media + if (!empty($match['media'])) { + $importContent = '@media '.$match['media'].'{'.$importContent.'}'; } + + // add to replacement array + $search[] = $match[0]; + $replace[] = $importContent; } // replace the import statements - $content = str_replace($search, $replace, $content); - - return $content; + return str_replace($search, $replace, $content); } /** @@ -253,18 +235,21 @@ protected function combineImports($source, $content, $parents) */ protected function importFiles($source, $content) { - $extensions = array_keys($this->importExtensions); - $regex = '/url\((["\']?)((?!["\']?data:).*?\.('.implode('|', $extensions).'))\\1\)/i'; - if ($extensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { + $regex = '/url\((["\']?)(.+?)\\1\)/i'; + if ($this->importExtensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { $search = array(); $replace = array(); // loop the matches foreach ($matches as $match) { + $extension = substr(strrchr($match[2], '.'), 1); + if ($extension && !array_key_exists($extension, $this->importExtensions)) { + continue; + } + // get the path for the file that will be imported $path = $match[2]; $path = dirname($source).'/'.$path; - $extension = $match[3]; // only replace the import with the content if we're able to get // the content of the file, and it's relatively small