Commit 63d0c0b93ba702340f9adf8e2772ecaddab635af
Exists in
spb-stable
and in
3 other branches
Merge branch 'gitlab_popen_array' into 'master'
Change Gitlab::Popen to only accept arrays as commands
Showing
4 changed files
with
31 additions
and
7 deletions
Show diff stats
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 'Gitlab::Popen', no_db: true do | @@ -10,7 +10,7 @@ describe 'Gitlab::Popen', 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 'Gitlab::Popen', no_db: true do | @@ -19,11 +19,27 @@ describe 'Gitlab::Popen', 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 |