utils/service: add systemd_quote helper
We need a way to escape systemd command lines properly as systemd treats unrecognised escape sequences as separate literal characters. This helper function does that.
This commit is contained in:
parent
b854d17426
commit
15146b2b67
24
Library/Homebrew/test/utils/service_spec.rb
Normal file
24
Library/Homebrew/test/utils/service_spec.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "utils/service"
|
||||||
|
|
||||||
|
RSpec.describe Utils::Service do
|
||||||
|
describe "::systemd_quote" do
|
||||||
|
it "quotes empty strings correctly" do
|
||||||
|
expect(described_class.systemd_quote("")).to eq '""'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "quotes strings with special characters escaped correctly" do
|
||||||
|
expect(described_class.systemd_quote("\a\b\f\n\r\t\v\\"))
|
||||||
|
.to eq '"\\a\\b\\f\\n\\r\\t\\v\\\\"'
|
||||||
|
expect(described_class.systemd_quote("\"' ")).to eq "\"\\\"' \""
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not escape characters that do not need escaping" do
|
||||||
|
expect(described_class.systemd_quote("daemon off;")).to eq '"daemon off;"'
|
||||||
|
expect(described_class.systemd_quote("--timeout=3")).to eq '"--timeout=3"'
|
||||||
|
expect(described_class.systemd_quote("--answer=foo bar"))
|
||||||
|
.to eq '"--answer=foo bar"'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -48,5 +48,40 @@ module Utils
|
|||||||
def self.systemctl?
|
def self.systemctl?
|
||||||
!systemctl.nil?
|
!systemctl.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Quote a string for use in systemd command lines, e.g., in `ExecStart`.
|
||||||
|
# https://www.freedesktop.org/software/systemd/man/latest/systemd.syntax.html#Quoting
|
||||||
|
sig { params(str: String).returns(String) }
|
||||||
|
def self.systemd_quote(str)
|
||||||
|
result = +"\""
|
||||||
|
# No need to escape single quotes and spaces, as we're always double
|
||||||
|
# quoting the entire string.
|
||||||
|
str.each_char do |char|
|
||||||
|
result << case char
|
||||||
|
when "\a"
|
||||||
|
"\\a"
|
||||||
|
when "\b"
|
||||||
|
"\\b"
|
||||||
|
when "\f"
|
||||||
|
"\\f"
|
||||||
|
when "\n"
|
||||||
|
"\\n"
|
||||||
|
when "\r"
|
||||||
|
"\\r"
|
||||||
|
when "\t"
|
||||||
|
"\\t"
|
||||||
|
when "\v"
|
||||||
|
"\\v"
|
||||||
|
when "\\"
|
||||||
|
"\\\\"
|
||||||
|
when "\""
|
||||||
|
"\\\""
|
||||||
|
else
|
||||||
|
char
|
||||||
|
end
|
||||||
|
end
|
||||||
|
result << "\""
|
||||||
|
result.freeze
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user