ExCSS icon indicating copy to clipboard operation
ExCSS copied to clipboard

Can't parse this code, waiting for a long, long time

Open colindcli opened this issue 3 years ago • 5 comments
trafficstars

                var str = @"
:root {
    --layout: {
    }
    --layout-horizontal: {
        @apply (--layout);
    }
}";
                var parser = new StylesheetParser();
                //Can't parse this code, waiting for a long, long time
                var parse = parser.Parse(str);

colindcli avatar Aug 10 '22 09:08 colindcli

Another piece of code has the same problem

                var str = @"
@media (max-width: 991px) {
    body {
        background-color: #013668;
    }
    ;
}

@media (max-width: 991px) {
    body {
        background: #FFF;
    }
}";

colindcli avatar Aug 10 '22 10:08 colindcli

Temporarily use a simple solution to solve this bug https://github.com/TylerBrinks/ExCSS/commit/fb89279dca696ee641eca3f4a9255701cb1df490#diff-7baec944edc72b3a373cea418d177eb296a1662f54a80b5de1e626441e5cd55b

colindcli avatar Aug 11 '22 04:08 colindcli

Here is another example (simplified from a much larger CSS) I just ran into:

    var str = @"      
    h3 {color: yellow; 
    @media print {
        h3 {color: black; }
        }        
    ";

Granted, this is malformed because of the missing } after the first selector, but I wouldn't expect an endless loop. It seems to manifest when the following structure has nested braces, like the @media selector. For example, this seems to work just fine even with the missing brace:

    var str = @"      
    h3 {color: yellow; 
    h2 {color: black; }
    ";

My use case is processing crappy HTML embedded in old emails, so I have no choice but to try and deal with this malformed junk. I'm going to try using the ParseAsync version, so I can bail after a few milliseconds if it seems to be stuck.


Well, this is disappointing, the ParseAsync gets hung up just like the Parse Function:

        var str = @"
          h3 {color: yellow; 
          @media print {
              h3 {color: black; }
              }
           ";
          
            var parser = new StylesheetParser();
            var stylesheetTask = parser.ParseAsync(str);
            stylesheetTask.Wait(700);
            var stylesheet = stylesheetTask.Result;

            Assert.IsNotNull(stylesheet);

For anyone else who just needs to get past this, log the error and keep going, here is a (possibly very bad) way:

        var parser = new StylesheetParser();

        var questionableCSS = @"
            h3 {color: yellow;
            @media print {
                h3 {color: black; }
                }
            ";

        var stylesheetTask = Task.Run<Stylesheet>(() => parser.Parse(questionableCSS ));
        var done = stylesheetTask.Wait(700);
        if (done)
            {
            var stylesheet = stylesheetTask.Result;
            //process the CSS like normal
            }
         else
             {
             // log the error, skip the bad data, and move onto the next thing
             }

My concern with the above is that after the timeout, the Parse task will continue to run in the background forever until your app stops, so use caution, especially if many instances of this task might be spun up and never finish .....

thabing avatar Mar 23 '23 17:03 thabing

It shouldn't run forever given you only have so many stack frames before the process will overflow. Regardless, I'll look at whether the depth guard can be used in this scenario.

TylerBrinks avatar Mar 28 '23 13:03 TylerBrinks

Made a Pull Request that Fixes this Because I experienced it too.

inforithmics avatar Aug 30 '23 22:08 inforithmics