mirror of
				https://github.com/mastodon/mastodon.git
				synced 2025-10-31 05:11:33 +00:00 
			
		
		
		
	Fix $ not being escaped in .env.production file generated by mastodon:setup (#23012)
				
					
				
			* Fix `$` not being escaped in `.env.production` file generated by `mastodon:setup` * Improve robustness of dotenv escaping
This commit is contained in:
		
							parent
							
								
									2ba14097ff
								
							
						
					
					
						commit
						a65f86ae55
					
				|  | @ -395,18 +395,11 @@ namespace :mastodon do | ||||||
|         incompatible_syntax = false |         incompatible_syntax = false | ||||||
| 
 | 
 | ||||||
|         env_contents = env.each_pair.map do |key, value| |         env_contents = env.each_pair.map do |key, value| | ||||||
|           if value.is_a?(String) && value =~ /[\s\#\\"]/ |           value = value.to_s | ||||||
|             incompatible_syntax = true |           escaped = dotenv_escape(value) | ||||||
|  |           incompatible_syntax = true if value != escaped | ||||||
| 
 | 
 | ||||||
|             if value =~ /[']/ |           escaped | ||||||
|               value = value.to_s.gsub(/[\\"\$]/) { |x| "\\#{x}" } |  | ||||||
|               "#{key}=\"#{value}\"" |  | ||||||
|             else |  | ||||||
|               "#{key}='#{value}'" |  | ||||||
|             end |  | ||||||
|           else |  | ||||||
|             "#{key}=#{value}" |  | ||||||
|           end |  | ||||||
|         end.join("\n") |         end.join("\n") | ||||||
| 
 | 
 | ||||||
|         generated_header = "# Generated with mastodon:setup on #{Time.now.utc}\n\n".dup |         generated_header = "# Generated with mastodon:setup on #{Time.now.utc}\n\n".dup | ||||||
|  | @ -519,3 +512,49 @@ def disable_log_stdout! | ||||||
|   HttpLog.configuration.logger = dev_null |   HttpLog.configuration.logger = dev_null | ||||||
|   Paperclip.options[:log]      = false |   Paperclip.options[:log]      = false | ||||||
| end | end | ||||||
|  | 
 | ||||||
|  | def dotenv_escape(value) | ||||||
|  |   # Dotenv has its own parser, which unfortunately deviates somewhat from | ||||||
|  |   # what shells actually do. | ||||||
|  |   # | ||||||
|  |   # In particular, we can't use Shellwords::escape because it outputs a | ||||||
|  |   # non-quotable string, while Dotenv requires `#` to always be in quoted | ||||||
|  |   # strings. | ||||||
|  |   # | ||||||
|  |   # Therefore, we need to write our own escape code… | ||||||
|  |   # Dotenv's parser has a *lot* of edge cases, and I think not every | ||||||
|  |   # ASCII string can even be represented into something Dotenv can parse, | ||||||
|  |   # so this is a best effort thing. | ||||||
|  |   # | ||||||
|  |   # In particular, strings with all the following probably cannot be | ||||||
|  |   # escaped: | ||||||
|  |   # - `#`, or ends with spaces, which requires some form of quoting (simply escaping won't work) | ||||||
|  |   # - `'` (single quote), preventing us from single-quoting | ||||||
|  |   # - `\` followed by either `r` or `n` | ||||||
|  | 
 | ||||||
|  |   # No character that would cause Dotenv trouble | ||||||
|  |   return value unless /[\s\#\\"'$]/.match?(value) | ||||||
|  | 
 | ||||||
|  |   # As long as the value doesn't include single quotes, we can safely | ||||||
|  |   # rely on single quotes | ||||||
|  |   return "'#{value}'" unless /[']/.match?(value) | ||||||
|  | 
 | ||||||
|  |   # If the value contains the string '\n' or '\r' we simply can't use | ||||||
|  |   # a double-quoted string, because Dotenv will expand \n or \r no | ||||||
|  |   # matter how much escaping we add. | ||||||
|  |   double_quoting_disallowed = /\\[rn]/.match?(value) | ||||||
|  | 
 | ||||||
|  |   value = value.gsub(double_quoting_disallowed ? /[\\"'\s]/ : /[\\"']/) { |x| "\\#{x}" } | ||||||
|  | 
 | ||||||
|  |   # Dotenv is especially tricky with `$` as unbalanced | ||||||
|  |   # parenthesis will make it not unescape `\$` as `$`… | ||||||
|  | 
 | ||||||
|  |   # Variables | ||||||
|  |   value = value.gsub(/\$(?!\()/) { |x| "\\#{x}" } | ||||||
|  |   # Commands | ||||||
|  |   value = value.gsub(/\$(?<cmd>\((?:[^()]|\g<cmd>)+\))/) { |x| "\\#{x}" } | ||||||
|  | 
 | ||||||
|  |   value = "\"#{value}\"" unless double_quoting_disallowed | ||||||
|  | 
 | ||||||
|  |   value | ||||||
|  | end | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Claire
						Claire