safe_shell 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README.rdoc +4 -1
- data/lib/safe_shell.rb +15 -0
- data/lib/safe_shell/version.rb +1 -1
- data/spec/safe_shell_spec.rb +12 -0
- metadata +6 -6
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -17,6 +17,9 @@ SafeShell sets the $? operator to the process status, in the same manner as the
|
|
17
17
|
# Return true if the command exits with a zero status:
|
18
18
|
SafeShell.execute?("echo", "Hello, world!")
|
19
19
|
|
20
|
+
# Raise an exception if the command exits with a non-zero status:
|
21
|
+
SafeShell.execute!("echo", "Hello, world!")
|
22
|
+
|
20
23
|
== Why?
|
21
24
|
|
22
25
|
If you use backticks to process a file supplied by a user, a carefully crafted filename could allow execution of an arbitrary command:
|
@@ -36,7 +39,7 @@ SafeShell solves this.
|
|
36
39
|
Tested with Ruby 1.8.7, but it should be happy on pretty much any Ruby version. Maybe not so much on Windows.
|
37
40
|
|
38
41
|
== Developing
|
39
|
-
|
42
|
+
|
40
43
|
* Fork the project.
|
41
44
|
* Make your feature addition or bug fix.
|
42
45
|
* Add tests for it. This is important so I don't break it in a
|
data/lib/safe_shell.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
module SafeShell
|
2
|
+
class CommandFailedException < RuntimeError; end
|
3
|
+
|
2
4
|
def self.execute(command, *args)
|
3
5
|
opts = args.last.kind_of?(Hash) ? args.pop : {}
|
4
6
|
read_end, write_end = IO.pipe
|
@@ -21,4 +23,17 @@ module SafeShell
|
|
21
23
|
execute(*args)
|
22
24
|
$?.success?
|
23
25
|
end
|
26
|
+
|
27
|
+
def self.execute!(*args)
|
28
|
+
execute(*args).tap do
|
29
|
+
raise_command_failed_exception(*args) unless $?.success?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def self.raise_command_failed_exception(*args)
|
36
|
+
raise CommandFailedException.new("Shell command #{args.inspect} failed with status #{$?}")
|
37
|
+
end
|
38
|
+
|
24
39
|
end
|
data/lib/safe_shell/version.rb
CHANGED
data/spec/safe_shell_spec.rb
CHANGED
@@ -40,4 +40,16 @@ describe "SafeShell" do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
context ".execute!" do
|
44
|
+
it "returns the output of the command" do
|
45
|
+
SafeShell.execute!("echo", "Hello, world!").should == "Hello, world!\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises an exception of the command fails" do
|
49
|
+
expect {
|
50
|
+
SafeShell.execute!("test", "a", "=", "b")
|
51
|
+
}.should raise_error(SafeShell::CommandFailedException)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
43
55
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Envato
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date:
|
20
|
+
date: 2012-01-03 00:00:00 +11:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
88
|
requirements: []
|
89
89
|
|
90
90
|
rubyforge_project: safe_shell
|
91
|
-
rubygems_version: 1.
|
91
|
+
rubygems_version: 1.6.2
|
92
92
|
signing_key:
|
93
93
|
specification_version: 3
|
94
94
|
summary: Safely execute shell commands and get their output.
|