Open kolen opened 4 months ago
Maybe calling
Kernel#abort
in case of non-StandardError
is a better idea.
Tried it, it does not abort ruby process immediately, it also causes ffi callback function to return with null pointer. So first, error message is printed and then segfault still happens.
I don't know a proper way to abort inside ffi callbacks, so maybe just rescuing all exceptions with the same handler that returns error value is okay.
sassc-ruby
supports passing custom functions tolibsass
as ruby functions, for example it is used insassc-rails
to defineurl
. Generally, this mechanism is memory-safe, but if custom function raises an exception that is not a subclass ofStandardError
, such asSystemStackError
, segmentation fault happens.This example causes segmentation fault by causing custom function to raise
SystemStackError
by infinite recursive call:Function wrapper catches only
StandardError
. If non-StandardError
exception occurs,ffi
gem ignores exception inFFI::Function
's block and behaves like the function is returnednil
. https://github.com/sass/sassc-ruby/blob/4fce2b635ca5d616a8b1381c64846410bc785ea4/lib/sassc/functions_handler.rb#L22-L33libsass
requires return value from custom function to be a valid pointer toSass_Value
. This return value is then passed tosass_value_get_tag
, which tries to dereference null pointer. https://github.com/sass/libsass/blob/8d312a1c91bb7dd22883ebdfc829003f75a82396/src/eval.cpp#L1107-L1108https://github.com/sass/libsass/blob/8d312a1c91bb7dd22883ebdfc829003f75a82396/src/sass_values.cpp#L16-L17
This might be cause of #133, #197, #207 (unsure).
Maybe this can be fixed by just catching all exceptions:
It works for my case, catching "stack level too deep" and converting to sass compilation error, but I'm not sure if it's overall a good idea to catch non-
StandardError
exceptions and what consequences might it cause, especially when working near ffi boundaries. Maybe callingKernel#abort
in case of non-StandardError
is a better idea.