Skip to content

Sass::Rails::CssCompressor tries to compile already compiled Scss #63

Closed
sidonath opened this Issue Sep 30, 2011 · 4 comments

3 participants

@sidonath

Some background: We upgraded our app from Rails 3.0 (with Compass and Jammit) to Rails 3.1 with Asset Pipeline and made it work with Compass master branch (without Jammit). We still need Compass because we use bunch of helpers and sprite generation AP. Specs are passing and the app works in development environment perfectly fine (all our assets are loading).

After running the bundle exec rake assets:precompile I got the "regexp buffer overflow" error.

Some investigation showed that the error occurs because Sass compressor (Sass::Rails::CssCompressor#compressor) receives already compiled CSS file. Our CSS is pretty large, so it seemed plausible that a complex regex chokes.

I'm not sure why is the CSS already compiled. It can be Compass' fault, but I couldn't find any proof to that. I've amended the compress method with this:

puts "First 1024 chars of compiled thing: #{css[0..1023]}"
raise

And here's the output (obviously compiled and compressed):

First 1024 chars of compiled thing: html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,dialog,figure,footer,header,hgroup,nav,section{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}article,aside,dialog,figure,footer,header,hgroup,nav,section{display:block}...

And stack trace:

from gems/sass-rails-3.1.2/lib/sass/rails/compressor.rb:8:in `compress'
from gems/actionpack-3.1.1.rc1/lib/sprockets/compressors.rb:18:in `compress'
from gems/sprockets-2.0.0/lib/sprockets/processing.rb:243:in `css_compressor='
from gems/sprockets-2.0.0/lib/sprockets/processor.rb:29:in `call'
from gems/sprockets-2.0.0/lib/sprockets/processor.rb:29:in `evaluate'
from gems/tilt-1.3.3/lib/tilt/template.rb:76:in `render'
from gems/sprockets-2.0.0/lib/sprockets/context.rb:175:in `evaluate'
from gems/sprockets-2.0.0/lib/sprockets/context.rb:172:in `each'
from gems/sprockets-2.0.0/lib/sprockets/context.rb:172:in `evaluate'
from gems/sprockets-2.0.0/lib/sprockets/bundled_asset.rb:242:in `build_source'
from gems/sprockets-2.0.0/lib/sprockets/caching.rb:26:in `cache_hash'
from gems/sprockets-2.0.0/lib/sprockets/bundled_asset.rb:235:in `build_source'
from gems/sprockets-2.0.0/lib/sprockets/bundled_asset.rb:71:in `digest'
from gems/sprockets-2.0.0/lib/sprockets/asset.rb:143:in `inspect'

Additionally, the format of the css parameter changes based on the Compass configuration of output_style (a reason to suspect Compass is the culprit).

We worked around the problem by setting the config.asset.css_compressor to nil in after_initialize block. That solves our symptoms, but if I'm right, many more could have their css compiled twice without errors (if their CSS output is simpler or smaller).

I'm not really sure whose "fault" this is (maybe we're doing something wrong?), but I needed to start the discussion somewhere :)

UPDATE: when I deployed to the staging server, I discovered that the CSS is not compressed at all. However I still get the same error when I enable compression, which probably just means that Compass does not compress CSS for staging environment. I'll double-check and update the issue.

UPDATE 2: Compass was just not compressing for staging environment, that was fixed in compass config.

@chriseppstein

This should be fixed by 25ce4ef

@afeld
afeld commented Nov 16, 2011

Was running into the same problem using Rails 3.1.1 and sass-rails 3.1.4 - I tried using the 25ce4ef version of the gem that @chriseppstein mentioned above, but that didn't help. After too many hours I was able to get SASS and JS minification with the following:

# ---- Gemfile ----

# this needed to be outside the :assets group to work with 'rake assets:precompile'
gem 'sass-rails',   '~> 3.1.0'

group :assets do
  ...
end

# ---- app/environments/production.rb ----

config.assets.compress = true

config.after_initialize do
  config.assets.css_compressor = nil
end
config.sass.style = :compressed
@chriseppstein

shouldn't be necessary. that patch avoids minification on a second pass, was it your experience that minification was happening twice or not at all?

@sidonath

@chriseppstein that patch avoids two passes of minification, but doesn't prevent minification of already compiled source. Most developers won't notice a difference since compass will minify CSS for production and sass-rails won't try to minify CSS for develop env.

However, for some non-trivial scenarios (eg. minifying code in develop with sass-rails; using compass config to prevent minification by compass in production...), sass-rails may be fed with a non-compressed compiled Sass (a huge CSS file) and the regex would choke.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.