-
Notifications
You must be signed in to change notification settings - Fork 461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stack overflow with massive character substitution #1823
Comments
I don't see much we can do here, as the implementation of the custom function @function str-replace($string, $search, $replace: '') {
@if $search == '' {
@return $string;
}
$remainder: $string;
$string: '';
$index: str-index($remainder, $search);
@while $index {
$string: $string + str-slice($remainder, 1, $index - 1) + $replace;
$remainder: str-slice($remainder, $index + str-length($search));
$index: str-index($remainder, $search);
}
@return $string + $remainder;
} I have not really tested this much, but seems to yield the same results as the recursive implementation. |
To repeat: this would have been much easier to implement if ruby sass would accept an optional offset for |
It's worth creating an issue there to discuss.
|
Opened sass/sass#1955. Closing this as no action will be taken from our side. |
@saper – I had the same problem solved by chunking up the string (2000 characters each) //
// Function to create an optimized svg url
//
@function svg-url($svg){
//
// Add missing namespace
//
@if not str-index($svg, xmlns) {
$svg: str-replace($svg, '<svg','<svg xmlns="http://www.w3.org/2000/svg"');
}
//
// Chunk up string in order to avoid
// "stack level too deep" error
//
$encoded:'';
$slice: 2000;
$index: 0;
$loops: ceil(str-length($svg)/$slice);
@for $i from 1 through $loops {
$chunk: str-slice($svg, $index, $index + $slice - 1);
//
// Encode (may need a few extra replacements)
//
$chunk: str-replace($chunk,'"','\'');
$chunk: str-replace($chunk,'<','%3C');
$chunk: str-replace($chunk,'>','%3E');
$chunk: str-replace($chunk,'&','%26');
$chunk: str-replace($chunk,'#','%23');
$encoded: #{$encoded}#{$chunk};
$index: $index + $slice;
}
@return url("data:image/svg+xml;charset=utf8,#{$encoded}");
}
// Helper function to replace characters in a string
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace +
str-replace(str-slice($string, $index +
str-length($search)), $search, $replace);
}
@return $string;
}
// Use It
.class {
background-image: svg-url('<svg xmlns="http://www.w3.org/2000/svg">.....</svg>');
} |
@jakob-e It's an edge case, but if the string gets split exactly where a theoretical match of a substring would be, that match won't be replaced. Fixing that needs some creativity 😁 |
@matthias-vogt |
@jakob-e Just for anyone looking for a generic string-replace function. I wouldn't want anyone to have to debug that :P |
(from sass/node-sass#1289)
If we try do perform large character substitution on the 1688 byte SVG file (https://gist.github.com/xzyfer/2cc0fcfc3c7c0fdc061e) we consume more than 512 kilobytes on stack, which hits thread stack size limit on Mac OS X.
The backtrace is here: https://gist.github.com/saper/4cae7f96bd4bacb61d3d
To reproduce on other platforms one needs to limit the stack for the process (using
limit stacksize 512
on C shells orulimit -s 512
on Bourne shells).The problem is the number of recursed calls to
Sass::Eval::operator()
- the topmost function usually fails when trying to access its own local variable space freshly allocated on the stack.The text was updated successfully, but these errors were encountered: