Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/difftastic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def self.execute(command)
`#{executable} #{command}`
end

def self.capture(*arguments)
IO.popen([executable, *arguments], &:read)
end

def self.platform
[:cpu, :os].map { |m| Gem::Platform.local.__send__(m) }.join("-")
end
Expand Down
4 changes: 2 additions & 2 deletions lib/difftastic/differ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ def diff_files(old_file, new_file)
("--tab-width=#{@tab_width}" if @tab_width),
("--display=#{@display}" if @display),
("--width=#{@width}" if @width),
].compact!
].compact

result = Difftastic.execute(options.join(" ")).lstrip.sub(/\n{2}\z/, "")
result = Difftastic.capture(*options).lstrip.sub(/\n{2}\z/, "")

unless @show_paths
new_line_index = (result.index("\n") || 0) + 1
Expand Down
54 changes: 54 additions & 0 deletions test/shell_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require_relative "test_helper"
require "tmpdir"

class ShellTest < Minitest::Spec
it "diff_files with spaces, quotes and command substitution in paths" do
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
File.write("a $(touch injected).txt", "A")
File.write("b 'quoted\".txt", "B")

output = Difftastic::Differ.new(color: :never, tab_width: 2).diff_files("a $(touch injected).txt", "b 'quoted\".txt")

assert_equal "1 A 1 B", output
end
end
end

it "diff_files does not run command substitution in paths" do
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
File.write("a $(touch injected).txt", "A")
File.write("b.txt", "B")

Difftastic::Differ.new(color: :never, tab_width: 2).diff_files("a $(touch injected).txt", "b.txt")

refute File.exist?("injected")
end
end
end

it "diff_strings with a temporary directory containing a space" do
original_tmpdir = ENV["TMPDIR"]

Dir.mktmpdir do |parent|
dir = File.join(parent, "with space")
Dir.mkdir(dir, 0o700)
ENV["TMPDIR"] = dir

output = Difftastic::Differ.new(color: :never, tab_width: 2).diff_strings("A", "B")

assert_equal "1 A 1 B", output
ensure
ENV["TMPDIR"] = original_tmpdir
end
end

it "diff_strings with every option set" do
differ = Difftastic::Differ.new(color: :never, context: 3, background: :dark, syntax_highlight: :off, tab_width: 2, width: 80)

assert_equal "1 A 1 B", differ.diff_strings("A", "B")
end
end