sass / libsass

A C/C++ implementation of a Sass compiler
https://sass-lang.com/libsass
Other
4.34k stars 463 forks source link

node-sass crashes when a parent selector is referenced but not included #1569

Closed slyoldfox closed 9 years ago

slyoldfox commented 9 years ago

When testing the latest node-sass@3.4.0-beta1 on our code base, node-sass plain crashes.

I traced it to the following (invalid code):

$common-border: "foo";
.nihilo & {
  .dijitMenu {
    border: $common-border;
    .dijitMenuItem {
      color: getColor('text-dark-main');
    }
  }
}

This seems to happen when a parent selector is referenced (the ampersand behind the .nihilo), but the parent node does not exist. node-sass/libsass should at least throw some kind of error. Now the process just seems to crash.

Following is the output on my system:

c:\Code\site2014\static\gulpfile.js build:scss --source file.scss [15:49:13] Using gulpfile gulpfile.js [15:49:13] Starting 'scss:options'... [15:49:13] Using version: node-sass 3.4.0-beta1 (Wrapper) [JavaScript] libsass 3.3.0-beta2 (Sass Compiler) [C/C++] [15:49:13] Finished 'scss:options' after 1.19 ms [15:49:13] Starting 'scss:compile'... [15:49:13] [scss] : sync / expanded mode. [15:49:13] [scss:compile] [1] [c:\file.scss]

Process finished with exit code -1073741819 (0xC0000005)

slyoldfox commented 9 years ago

@xzyfer would love if this could make it in the 3.3 release

slyoldfox commented 9 years ago

The following is a more complex example with a mixin

$tablet-portrait:                 768px;
$tablet-landscape:                980px;
$desk-normal:                     1120px;
$desk-big:                        1280px;
$grid-breakpoints-immobile: (
        'tablet-portrait':   '(min-width: ' + $tablet-portrait + ') and (max-width: ' + $tablet-landscape + ')',
        'tablet-landscape':  '(min-width: ' +  $tablet-landscape + ') and (max-width: ' + $desk-normal + ')',
        'desk-normal':       '(min-width: ' +  $desk-normal + ') and (max-width: ' + $desk-big + ')',
        'desk-big':          '(min-width: ' +  $desk-big + ')'
);
@mixin grid-media-query($media-query, $breakpointDefinitions) {
  $breakpoint-found: false;

  @each $breakpoint, $breakpointvalue in $breakpointDefinitions{
    $name: $breakpoint;
    $declaration: $breakpointvalue;

    @if $media-query == $name and $declaration{
      $breakpoint-found: true;

      @media only screen and #{$declaration} {
        @content;
      }
    }
  }
}

@each $name in map-keys($grid-breakpoints-immobile) {
  @include grid-media-query($name, $grid-breakpoints-immobile) {
    body.immobile & {
      margin-bottom: 0;
    }
  }
}

Output on 3.3.3:

$ node-sass file.scss
@media only screen and (min-width: 768px) and (max-width: 980px) {
  body.immobile {
    margin-bottom: 0; } }

@media only screen and (min-width: 980px) and (max-width: 1120px) {
  body.immobile {
    margin-bottom: 0; } }

@media only screen and (min-width: 1120px) and (max-width: 1280px) {
  body.immobile {
    margin-bottom: 0; } }

@media only screen and (min-width: 1280px) {
  body.immobile {
    margin-bottom: 0; } }

On 3.4.0

$ node-sass -v
node-sass       3.4.0-beta1     (Wrapper)       [JavaScript]
libsass         3.3.0-beta2     (Sass Compiler) [C/C++]
$ node-sass file.scss
/c/Users/marc/AppData/Roaming/npm/node-sass: line 14:  7024 Segmentation fault      node "$basedir/node_modules/node-sass/bin/node-sass" "$@"
saper commented 9 years ago

Here's what I got with the brand new libsass:

m> ~/sw/sassc/bin/sassc -v
sassc: 3.3.0-beta1
libsass: 3.3.0-beta2-1-g1efd
sass2scss: 1.0.3
m> ~/sw/sassc/bin/sassc spec/libsass-todo-issues/issue_1569/input.scss
Error: Base-level rules cannot contain the parent-selector-referencing character '&'.

       Backtrace:
                spec/libsass-todo-issues/issue_1569/input.scss:2
        on line 2 of spec/libsass-todo-issues/issue_1569/input.scss
>> .nihilo & {
   --------^
saper commented 9 years ago

Crash backtrace for the complex case:

Program received signal SIGSEGV, Segmentation fault.
0x000000000047af9d in Sass::Complex_Selector::skip_empty_reference (this=0x801c502e0) at src/ast.hpp:2128
2128            tail_->has_line_feed_ = this->has_line_feed_;
(gdb) bt
#0  0x000000000047af9d in Sass::Complex_Selector::skip_empty_reference (this=0x801c502e0) at src/ast.hpp:2128
#1  0x0000000000463433 in Sass::Complex_Selector::parentize (this=0x801c36020, parents=0x0, ctx=...) at src/ast.cpp:955
#2  0x00000000004626bd in Sass::Complex_Selector::parentize (this=0x801c34f60, parents=0x0, ctx=...) at src/ast.cpp:890
#3  0x0000000000528a8c in Sass::Eval::operator() (this=0x7fffffffde20, s=0x801c34f60) at src/eval.cpp:1426
#4  0x0000000000528624 in Sass::Eval::operator() (this=0x7fffffffde20, s=0x801c31200) at src/eval.cpp:1399
#5  0x0000000000481ae1 in Sass::Selector_List::perform (this=0x801c31200, op=0x7fffffffde20) at src/ast.hpp:2275
#6  0x000000000053f511 in Sass::Expand::operator() (this=0x7fffffffde10, r=0x801c34ec0) at src/expand.cpp:117
#7  0x000000000047cc1e in Sass::Ruleset::perform (this=0x801c34ec0, op=0x7fffffffde10) at src/ast.hpp:413
#8  0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c31140) at src/expand.cpp:644
#9  0x0000000000548d69 in Sass::Expand::operator() (this=0x7fffffffde10, c=0x801c4c540) at src/expand.cpp:613
#10 0x000000000054f161 in Sass::Mixin_Call::perform (this=0x801c4c540, op=0x7fffffffde10) at src/ast.hpp:779
#11 0x00000000005494a5 in Sass::Expand::operator() (this=0x7fffffffde10, c=0x801c1c980) at src/expand.cpp:628
#12 0x000000000065b651 in Sass::Content::perform (this=0x801c1c980, op=0x7fffffffde10) at src/ast.hpp:789
#13 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30e40) at src/expand.cpp:644
#14 0x000000000053e58d in Sass::Expand::operator() (this=0x7fffffffde10, b=0x801c30e40) at src/expand.cpp:78
#15 0x00000000004faf8e in Sass::Block::perform (this=0x801c30e40, op=0x7fffffffde10) at src/ast.hpp:378
#16 0x00000000005409fd in Sass::Expand::operator() (this=0x7fffffffde10, m=0x801c347e0) at src/expand.cpp:182
#17 0x000000000047cebe in Sass::Media_Block::perform (this=0x801c347e0, op=0x7fffffffde10) at src/ast.hpp:457
#18 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30b40) at src/expand.cpp:644
#19 0x00000000005429b1 in Sass::Expand::operator() (this=0x7fffffffde10, i=0x801c34a60) at src/expand.cpp:352
#20 0x000000000065b471 in Sass::If::perform (this=0x801c34a60, op=0x7fffffffde10) at src/ast.hpp:624
#21 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30900) at src/expand.cpp:644
#22 0x0000000000544b13 in Sass::Expand::operator() (this=0x7fffffffde10, e=0x801c30f00) at src/expand.cpp:457
#23 0x000000000065b081 in Sass::Each::perform (this=0x801c30f00, op=0x7fffffffde10) at src/ast.hpp:654
#24 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30780) at src/expand.cpp:644
#25 0x0000000000548d69 in Sass::Expand::operator() (this=0x7fffffffde10, c=0x801c31080) at src/expand.cpp:613
#26 0x000000000054f161 in Sass::Mixin_Call::perform (this=0x801c31080, op=0x7fffffffde10) at src/ast.hpp:779
#27 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30fc0) at src/expand.cpp:644
#28 0x00000000005453c0 in Sass::Expand::operator() (this=0x7fffffffde10, e=0x801c31740) at src/expand.cpp:489
#29 0x000000000065b081 in Sass::Each::perform (this=0x801c31740, op=0x7fffffffde10) at src/ast.hpp:654
#30 0x00000000005495c6 in Sass::Expand::append_block (this=0x7fffffffde10, b=0x801c30180) at src/expand.cpp:644
#31 0x000000000053e58d in Sass::Expand::operator() (this=0x7fffffffde10, b=0x801c30180) at src/expand.cpp:78
#32 0x00000000004faf8e in Sass::Block::perform (this=0x801c30180, op=0x7fffffffde10) at src/ast.hpp:378
#33 0x00000000004c44d4 in Sass::Context::parse_file (this=0x801c23280) at src/context.cpp:352
#34 0x00000000004226c0 in sass_parse_block (compiler=0x801c060e0) at src/sass_context.cpp:481
#35 0x0000000000422501 in sass_compiler_parse (compiler=0x801c060e0) at src/sass_context.cpp:637
#36 0x0000000000421fc5 in sass_compile_context (c_ctx=0x801c1f100, cpp_opt=...) at src/sass_context.cpp:519
#37 0x0000000000422389 in sass_compile_file_context (file_ctx=0x801c1f100) at src/sass_context.cpp:624
#38 0x0000000000419f3f in compile_file (options=0x801c1c080, input_path=0x7fffffffeacf "spec/libsass-todo-tests/parent-selector/missing/input.scss", 
    outfile=0x0) at sassc.c:107
slyoldfox commented 9 years ago

Thanks for checking up on this and adding the test cases. I'm AWAL next week for two weeks. If you need someone to test this on our .scss files, @HeadOnAPlate might be able to run those while I'm gone.