diff options
author | Claire <claire.github-309c@sitedethib.com> | 2023-01-13 12:26:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-13 12:26:34 +0100 |
commit | afd0d424da4928b9e20a3c7a943f970252ed3a29 (patch) | |
tree | 98641aa5df145b1a025ff29940c2d8814f6b7b2f /lib | |
parent | 932a22219ae99a285bdd0b69f02627f029327db3 (diff) | |
parent | b52dc5f69d27ce2fcc84b3929840f2d8704ae48a (diff) |
Merge pull request #2080 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sanitize_ext/sanitize_config.rb | 2 | ||||
-rw-r--r-- | lib/tasks/mastodon.rake | 61 |
2 files changed, 51 insertions, 12 deletions
diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb index 946543868..8da067585 100644 --- a/lib/sanitize_ext/sanitize_config.rb +++ b/lib/sanitize_ext/sanitize_config.rb @@ -68,7 +68,7 @@ class Sanitize end end - current_node.replace(current_node.text) unless LINK_PROTOCOLS.include?(scheme) + current_node.replace(Nokogiri::XML::Text.new(current_node.text, current_node.document)) unless LINK_PROTOCOLS.include?(scheme) end MASTODON_STRICT ||= freeze_config( diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 3c891a07f..32040feec 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -395,18 +395,11 @@ namespace :mastodon do incompatible_syntax = false env_contents = env.each_pair.map do |key, value| - if value.is_a?(String) && value =~ /[\s\#\\"]/ - incompatible_syntax = true + value = value.to_s + escaped = dotenv_escape(value) + incompatible_syntax = true if value != escaped - if value =~ /[']/ - value = value.to_s.gsub(/[\\"\$]/) { |x| "\\#{x}" } - "#{key}=\"#{value}\"" - else - "#{key}='#{value}'" - end - else - "#{key}=#{value}" - end + "#{key}=#{escaped}" end.join("\n") 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 Paperclip.options[:log] = false 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 |