madskristensen / LessCompiler

A Visual Studio extension
Other
15 stars 8 forks source link

Exception when using a[href^="tel:"] as css selector #5

Open djkrose opened 7 years ago

djkrose commented 7 years ago

Installed product versions

Description

The selector a[href^="tel:"] in an inline-imported css file can cause LessCompiler to fail with the following exception:

09.10.2017 18:14:13: System.NotSupportedException: The given path's format is not supported.
   at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath)
   at System.Security.Permissions.FileIOPermission.QuickDemand(FileIOPermissionAccess access, String fullPath, Boolean checkForDuplicates, Boolean needFullPath)
   at System.IO.FileInfo.Init(String fileName, Boolean checkHost)
   at System.IO.FileInfo..ctor(String fileName)
   at LessCompiler.ProjectMap.<AddOption>d__11.MoveNext() in C:\projects\lesscompiler\src\Compiler\ProjectMap.cs:line 96
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at LessCompiler.ProjectMap.<AddFile>d__10.MoveNext() in C:\projects\lesscompiler\src\Compiler\ProjectMap.cs:line 86
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at LessCompiler.ProjectMap.<AddOption>d__11.MoveNext() in C:\projects\lesscompiler\src\Compiler\ProjectMap.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at LessCompiler.ProjectMap.<AddFile>d__10.MoveNext() in C:\projects\lesscompiler\src\Compiler\ProjectMap.cs:line 86
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at LessCompiler.ProjectMap.<BuildMap>d__7.MoveNext() in C:\projects\lesscompiler\src\Compiler\ProjectMap.cs:line 43
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at LessCompiler.LessCatalog.<EnsureCatalog>d__6.MoveNext() in C:\projects\lesscompiler\src\Compiler\LessCatalog.cs:line 38

Steps to recreate

  1. Create a less file with the name main.less with content:
    // no-minify lessc --source-map
    @import (inline) "style.css";
  2. Create a css file with the name style.css with content:
    
    a[href^="tel:"] {
    color: inherit;
    text-decoration: none;
    }

3. Save the less file triggering a compile
4. Open LESS Compiler output window to show exception

Removing the colon (":") after "tel" and letting the less file recompile lets the exception disappear and the less file compile.

The error only happens when the steps are done right after start of Visual Studio. When the compilation worked once and the colon is re-added, the error doesn't reappear until restart.

I found out about the causing selector when I repeatedly got the exception and then debugged into the LessCompiler.dll to see the problem first-hand:

![Debugging Screenshot](https://abload.de/img/debug5hq8o.png)

Assumingly during discovery of Less options in the file, the LessCompiler tries to create a FileInfo object for `D:\Entwicklung\Zaehne2\www\css\tel:` which fails with tthe beforementioned exception.

### Current behavior
Exception during compiling; nothing gets compiled.

### Expected behavior
No exception, files should compile.
In fact, the content of an inlined css shouldn't matter at all and should not cause the compiler to check assumed file paths.

### Workaround
Remove the problematic selector, compile, re-add the problematic selector, recompile.
Repeat after every VS restart.
djkrose commented 7 years ago

Looking at LessCompiler/src/Compiler/ProjectMap.cs, it seems like there is just a try-catch neccessary to ignore incorrect paths:

private async Task AddOption(CompilerOptions options, string lessContent = null)
{
    lessContent = lessContent ?? File.ReadAllText(options.InputFilePath);
    string lessDir = Path.GetDirectoryName(options.InputFilePath);

    foreach (Match match in _import.Matches(lessContent))
    {
        try
        {
            string childFilePath = new FileInfo(Path.Combine(lessDir, match.Groups["url"].Value)).FullName;
        }
        catch (Exception)
        {
            continue; // This isn't even a valid path so there are certainly no Less options to find
        }
[...]