From 9a9a0914cdbcc045552a98bad7829fbf415ab268 Mon Sep 17 00:00:00 2001 From: xiaohui Date: Wed, 17 Apr 2024 17:42:06 +0800 Subject: [PATCH] don't escape non-ascii characters in docker env file --- lib/kamal/env_file.rb | 7 +++++ test/env_file_test.rb | 27 +++++++++++++++++++ test/integration/docker/deployer/app/.env.erb | 2 +- .../docker/deployer/app_with_roles/.env.erb | 2 +- test/integration/main_test.rb | 6 ++--- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/kamal/env_file.rb b/lib/kamal/env_file.rb index 0c9f2341..2228be09 100644 --- a/lib/kamal/env_file.rb +++ b/lib/kamal/env_file.rb @@ -24,6 +24,13 @@ class Kamal::EnvFile # Escape a value to make it safe to dump in a docker file. def escape_docker_env_file_value(value) + # keep non-ascii(UTF-8) characters as it is + value.to_s.scan(/[\x00-\x7F]+|[^\x00-\x7F]+/).map do |part| + part.ascii_only? ? escape_docker_env_file_ascii_value(part) : part + end.join + end + + def escape_docker_env_file_ascii_value(value) # Doublequotes are treated literally in docker env files # so remove leading and trailing ones and unescape any others value.to_s.dump[1..-2].gsub(/\\"/, "\"") diff --git a/test/env_file_test.rb b/test/env_file_test.rb index 6fcef6e3..c6b9e66e 100644 --- a/test/env_file_test.rb +++ b/test/env_file_test.rb @@ -11,6 +11,33 @@ class EnvFileTest < ActiveSupport::TestCase Kamal::EnvFile.new(env).to_s end + test "to_str won't escape chinese characters" do + env = { + "foo" => 'δ½ ε₯½ means hello, "欒迎" means welcome, that\'s simple! πŸ˜ƒ {smile}' + } + + assert_equal "foo=δ½ ε₯½ means hello, \"欒迎\" means welcome, that's simple! πŸ˜ƒ {smile}\n", + Kamal::EnvFile.new(env).to_s + end + + test "to_s won't escape japanese characters" do + env = { + "foo" => 'こんにけは means hello, "γ‚ˆγ†γ“γ" means welcome, that\'s simple! πŸ˜ƒ {smile}' + } + + assert_equal "foo=こんにけは means hello, \"γ‚ˆγ†γ“γ\" means welcome, that's simple! πŸ˜ƒ {smile}\n", \ + Kamal::EnvFile.new(env).to_s + end + + test "to_s won't escape korean characters" do + env = { + "foo" => 'μ•ˆλ…•ν•˜μ„Έμš” means hello, "μ–΄μ„œ μ˜€μ‹­μ‹œμ˜€" means welcome, that\'s simple! πŸ˜ƒ {smile}' + } + + assert_equal "foo=μ•ˆλ…•ν•˜μ„Έμš” means hello, \"μ–΄μ„œ μ˜€μ‹­μ‹œμ˜€\" means welcome, that's simple! πŸ˜ƒ {smile}\n", \ + Kamal::EnvFile.new(env).to_s + end + test "to_s empty" do assert_equal "\n", Kamal::EnvFile.new({}).to_s end diff --git a/test/integration/docker/deployer/app/.env.erb b/test/integration/docker/deployer/app/.env.erb index dcd2fcf5..cb2988d6 100644 --- a/test/integration/docker/deployer/app/.env.erb +++ b/test/integration/docker/deployer/app/.env.erb @@ -1 +1 @@ -SECRET_TOKEN=1234 +SECRET_TOKEN='1234 with "δΈ­ζ–‡"' diff --git a/test/integration/docker/deployer/app_with_roles/.env.erb b/test/integration/docker/deployer/app_with_roles/.env.erb index dcd2fcf5..cb2988d6 100644 --- a/test/integration/docker/deployer/app_with_roles/.env.erb +++ b/test/integration/docker/deployer/app_with_roles/.env.erb @@ -1 +1 @@ -SECRET_TOKEN=1234 +SECRET_TOKEN='1234 with "δΈ­ζ–‡"' diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index f8f69b0e..ac549b97 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -3,8 +3,8 @@ require_relative "integration_test" class MainTest < IntegrationTest test "envify, deploy, redeploy, rollback, details and audit" do kamal :envify - assert_local_env_file "SECRET_TOKEN=1234" - assert_remote_env_file "SECRET_TOKEN=1234" + assert_local_env_file "SECRET_TOKEN='1234 with \"δΈ­ζ–‡\"'" + assert_remote_env_file "SECRET_TOKEN=1234 with \"δΈ­ζ–‡\"" remove_local_env_file first_version = latest_app_version @@ -16,7 +16,7 @@ class MainTest < IntegrationTest assert_hooks_ran "pre-connect", "pre-build", "pre-deploy", "post-deploy" assert_env :CLEAR_TOKEN, "4321", version: first_version assert_env :HOST_TOKEN, "abcd", version: first_version - assert_env :SECRET_TOKEN, "1234", version: first_version + assert_env :SECRET_TOKEN, "1234 with \"δΈ­ζ–‡\"", version: first_version second_version = update_app_rev