sprockets icon indicating copy to clipboard operation
sprockets copied to clipboard

File paths with square brackets are not handled correctly when precompiling assets

Open dcroper opened this issue 9 years ago • 9 comments

When precompiling assets, if the directory path to the asset contains square brackets (or any other special character I assume) uri_utils.rb raises an error stating the URI is invalid. Modifying uri_utils.rb to escape square brackets using URI.escape(uri, '[]') in split_file_uri allows the precompile to succeed (unfortunately URI.escape(uri) does not escape square brackets). As I am not familiar with the sprockets code I am not sure if this is the best place to escape the special characters or what other special characters should be escaped.

dcroper avatar Mar 11 '16 23:03 dcroper

i have the same issue, image with square brackets on name.

leftis avatar Apr 11 '16 13:04 leftis

Can you please send a link to a minimal example? That would help to diagnose the issue.

michaelherold avatar May 15 '16 20:05 michaelherold

All you have to do is give an image file the name "[squarebracket].png" or put an image file in a directory called "[squarebracket]" and try and pre-compile that asset. If you do that the precompile command will fail.

dcroper avatar May 17 '16 17:05 dcroper

If you've got a minute to make an example app it will save us a minute and get this issue looked at faster https://speakerdeck.com/schneems/saving-sprockets?slide=143

schneems avatar May 17 '16 18:05 schneems

I have an issue in a Rails 5 application with a filename containing a "+" sign. The asset 404s on the URL generated by Sprockets but works if I replace the "+" with "%2B".

@schneems Why was this issue closed? Was it fixed?

speckins avatar Nov 02 '16 11:11 speckins

No example app

schneems avatar Nov 02 '16 14:11 schneems

@schneems https://github.com/speckins/sprockets-example-app/tree/issue-263

speckins avatar Nov 02 '16 15:11 speckins

Sorry for the extreme delay here. I'm not able to reproduce with the given app:

$ bundle exec rake assets:precompile
/Users/rschneeman/.gem/ruby/2.4.2/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:206: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/activesupport-5.0.0.1/lib/active_support/xml_mini.rb:51: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/activesupport-5.0.0.1/lib/active_support/xml_mini.rb:52: warning: constant ::Bignum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/sprockets-3.7.0/lib/sprockets/digest_utils.rb:47: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/sprockets-3.7.0/lib/sprockets/digest_utils.rb:51: warning: constant ::Bignum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/sprockets-3.7.0/lib/sprockets/processor_utils.rb:110: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/sprockets-3.7.0/lib/sprockets/processor_utils.rb:111: warning: constant ::Bignum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:230: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:230: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/activesupport-5.0.0.1/lib/active_support/core_ext/numeric/conversions.rb:138: warning: constant ::Fixnum is deprecated
/Users/rschneeman/.gem/ruby/2.4.2/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:230: warning: constant ::Fixnum is deprecated
I, [2017-11-17T09:35:46.367992 #39680]  INFO -- : Writing /private/tmp/sprockets-example-app/public/assets/application-55f48944fac4481b6a511d280489f354b5580ae1c3ac721f69a05d6ca37c784e.js
I, [2017-11-17T09:35:46.372286 #39680]  INFO -- : Writing /private/tmp/sprockets-example-app/public/assets/application-55f48944fac4481b6a511d280489f354b5580ae1c3ac721f69a05d6ca37c784e.js.gz
I, [2017-11-17T09:35:46.374063 #39680]  INFO -- : Writing /private/tmp/sprockets-example-app/public/assets/application-af04b226fd7202dfc532ce7aedb95a0128277937e90d3b3a3d35e1cce9e16886.css
I, [2017-11-17T09:35:46.374173 #39680]  INFO -- : Writing /private/tmp/sprockets-example-app/public/assets/application-af04b226fd7202dfc532ce7aedb95a0128277937e90d3b3a3d35e1cce9e16886.css.gz

schneems avatar Nov 17 '17 15:11 schneems

@schneems I've updated the example app to include a demonstration of OP's original issue. It will fail to precompile assets with the following error:

~/git/sprockets-example-app (issue-263) $ bundle exec rake assets:precompile
I, [2017-11-17T10:06:17.742579 #84123]  INFO -- : Writing /Users/speckins/git/sprockets-example-app/public/assets/image-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.png
rake aborted!
URI::InvalidURIError: bad URI(is not URI?): file:///Users/speckins/git/sprockets-example-app/app/assets/images/image[with-brackets].png?type=image/png
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/uri_utils.rb:45:in `split_file_uri'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/uri_utils.rb:91:in `parse_asset_uri'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/unloaded_asset.rb:134:in `load_file_params'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/unloaded_asset.rb:64:in `params'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/loader.rb:34:in `load'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/cached_environment.rb:20:in `block in initialize'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/cached_environment.rb:47:in `load'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/base.rb:66:in `find_asset'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/base.rb:73:in `find_all_linked_assets'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/manifest.rb:142:in `block in find'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/legacy.rb:114:in `block (2 levels) in logical_paths'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/path_utils.rb:228:in `block in stat_tree'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/path_utils.rb:212:in `block in stat_directory'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/path_utils.rb:209:in `each'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/path_utils.rb:209:in `stat_directory'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/path_utils.rb:227:in `stat_tree'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/legacy.rb:105:in `each'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/legacy.rb:105:in `block in logical_paths'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/legacy.rb:104:in `each'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/legacy.rb:104:in `logical_paths'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/manifest.rb:140:in `find'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/sprockets/manifest.rb:185:in `compile'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-rails-3.2.0/lib/sprockets/rails/task.rb:68:in `block (3 levels) in define'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-3.7.0/lib/rake/sprocketstask.rb:147:in `with_logger'
/Users/speckins/.gem/ruby/2.3.1/gems/sprockets-rails-3.2.0/lib/sprockets/rails/task.rb:67:in `block (2 levels) in define'
/Users/speckins/.gem/ruby/2.3.1/gems/rake-11.3.0/exe/rake:27:in `<top (required)>'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
/Users/speckins/.gem/ruby/2.3.1/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
/Users/speckins/.gem/ruby/2.3.1/bin/bundle:23:in `load'
/Users/speckins/.gem/ruby/2.3.1/bin/bundle:23:in `<main>'

The issue I was reporting is different, but I think related. I was seeing 404s with assets containing a "+" sign in the filename. If you checkout commit 3b1b081747acafcfd20ac9c381382b71ddc57aa3, run rails server, and visit the index, you can see that even though the a+b.js asset exists in the filesystem, it is not found (404). See below (from Rails server log):

ActionController::RoutingError (No route matches [GET] "/assets/a+b.self-bd733e4d5c8c0181df562860fc49ed96ace0d1832063146e2e4044a4148a91af.js"):

actionpack (5.0.0.1) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call'
web-console (3.4.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.4.0) lib/web_console/middleware.rb:28:in `block in call'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `catch'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `call'
actionpack (5.0.0.1) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.0.0.1) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `block in tagged'
activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `tagged'
railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.0) lib/sprockets/rails/quiet_assets.rb:11:in `block in call'
activesupport (5.0.0.1) lib/active_support/logger_silence.rb:20:in `silence'
activesupport (5.0.0.1) lib/active_support/logger.rb:63:in `block (3 levels) in broadcast'
activesupport (5.0.0.1) lib/active_support/logger_silence.rb:20:in `silence'
activesupport (5.0.0.1) lib/active_support/logger.rb:61:in `block (2 levels) in broadcast'
sprockets-rails (3.2.0) lib/sprockets/rails/quiet_assets.rb:11:in `call'
actionpack (5.0.0.1) lib/action_dispatch/middleware/request_id.rb:24:in `call'
rack (2.0.1) lib/rack/method_override.rb:22:in `call'
rack (2.0.1) lib/rack/runtime.rb:22:in `call'
activesupport (5.0.0.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.0.1) lib/action_dispatch/middleware/static.rb:136:in `call'
rack (2.0.1) lib/rack/sendfile.rb:111:in `call'
railties (5.0.0.1) lib/rails/engine.rb:522:in `call'
puma (3.6.0) lib/puma/configuration.rb:225:in `call'
puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
puma (3.6.0) lib/puma/server.rb:415:in `process_client'
puma (3.6.0) lib/puma/server.rb:275:in `block in run'
puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'

It seems that both the square brackets issue and the "+" issue are related to the translation of special URI characters in filenames.

speckins avatar Nov 17 '17 16:11 speckins