Commit 63d0c0b93ba702340f9adf8e2772ecaddab635af

Authored by Dmitriy Zaporozhets
2 parents 6c1af645 36c2c354

Merge branch 'gitlab_popen_array' into 'master'

Change Gitlab::Popen to only accept arrays as commands
app/models/key.rb
@@ -53,7 +53,7 @@ class Key < ActiveRecord::Base @@ -53,7 +53,7 @@ class Key < ActiveRecord::Base
53 Tempfile.open('gitlab_key_file') do |file| 53 Tempfile.open('gitlab_key_file') do |file|
54 file.puts key 54 file.puts key
55 file.rewind 55 file.rewind
56 - cmd_output, cmd_status = popen("ssh-keygen -lf #{file.path}", '/tmp') 56 + cmd_output, cmd_status = popen(%W(ssh-keygen -lf #{file.path}), '/tmp')
57 end 57 end
58 58
59 if cmd_status.zero? 59 if cmd_status.zero?
lib/gitlab/popen.rb
1 require 'fileutils' 1 require 'fileutils'
  2 +require 'open3'
2 3
3 module Gitlab 4 module Gitlab
4 module Popen 5 module Popen
5 - def popen(cmd, path) 6 + extend self
  7 +
  8 + def popen(cmd, path=nil)
  9 + unless cmd.is_a?(Array)
  10 + raise "System commands must be given as an array of strings"
  11 + end
  12 +
  13 + path ||= Dir.pwd
6 vars = { "PWD" => path } 14 vars = { "PWD" => path }
7 options = { chdir: path } 15 options = { chdir: path }
8 16
@@ -12,10 +20,10 @@ module Gitlab @@ -12,10 +20,10 @@ module Gitlab
12 20
13 @cmd_output = "" 21 @cmd_output = ""
14 @cmd_status = 0 22 @cmd_status = 0
15 - Open3.popen3(vars, cmd, options) do |stdin, stdout, stderr, wait_thr|  
16 - @cmd_status = wait_thr.value.exitstatus 23 + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
17 @cmd_output << stdout.read 24 @cmd_output << stdout.read
18 @cmd_output << stderr.read 25 @cmd_output << stderr.read
  26 + @cmd_status = wait_thr.value.exitstatus
19 end 27 end
20 28
21 return @cmd_output, @cmd_status 29 return @cmd_output, @cmd_status
lib/gitlab/satellite/satellite.rb
@@ -33,7 +33,7 @@ module Gitlab @@ -33,7 +33,7 @@ module Gitlab
33 end 33 end
34 34
35 def create 35 def create
36 - output, status = popen("git clone #{project.repository.path_to_repo} #{path}", 36 + output, status = popen(%W(git clone -- #{project.repository.path_to_repo} #{path}),
37 Gitlab.config.satellites.path) 37 Gitlab.config.satellites.path)
38 38
39 log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}") 39 log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}")
spec/lib/gitlab/popen_spec.rb
@@ -10,7 +10,7 @@ describe &#39;Gitlab::Popen&#39;, no_db: true do @@ -10,7 +10,7 @@ describe &#39;Gitlab::Popen&#39;, no_db: true do
10 10
11 context 'zero status' do 11 context 'zero status' do
12 before do 12 before do
13 - @output, @status = @klass.new.popen('ls', path) 13 + @output, @status = @klass.new.popen(%W(ls), path)
14 end 14 end
15 15
16 it { @status.should be_zero } 16 it { @status.should be_zero }
@@ -19,11 +19,27 @@ describe &#39;Gitlab::Popen&#39;, no_db: true do @@ -19,11 +19,27 @@ describe &#39;Gitlab::Popen&#39;, no_db: true do
19 19
20 context 'non-zero status' do 20 context 'non-zero status' do
21 before do 21 before do
22 - @output, @status = @klass.new.popen('cat NOTHING', path) 22 + @output, @status = @klass.new.popen(%W(cat NOTHING), path)
23 end 23 end
24 24
25 it { @status.should == 1 } 25 it { @status.should == 1 }
26 it { @output.should include('No such file or directory') } 26 it { @output.should include('No such file or directory') }
27 end 27 end
  28 +
  29 + context 'unsafe string command' do
  30 + it 'raises an error when it gets called with a string argument' do
  31 + expect { @klass.new.popen('ls', path) }.to raise_error
  32 + end
  33 + end
  34 +
  35 + context 'without a directory argument' do
  36 + before do
  37 + @output, @status = @klass.new.popen(%W(ls))
  38 + end
  39 +
  40 + it { @status.should be_zero }
  41 + it { @output.should include('spec') }
  42 + end
  43 +
28 end 44 end
29 45