sandboxed_erb 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +127 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/example/controller.rb +11 -0
- data/example/example.rb +87 -0
- data/example/listing.sbhtml +26 -0
- data/example/note.rb +17 -0
- data/example/users.rb +55 -0
- data/example/view_notes.sbhtml +9 -0
- data/lib/sandboxed_erb.rb +45 -0
- data/lib/sandboxed_erb/sandbox_methods.rb +93 -0
- data/lib/sandboxed_erb/system_mixins.rb +37 -0
- data/lib/sandboxed_erb/template.rb +224 -0
- data/lib/sandboxed_erb/tree_processor.rb +215 -0
- data/profile/vs_erb.rb +77 -0
- data/profile/vs_liquid.rb +95 -0
- data/sandboxed_erb.gemspec +79 -0
- data/test/helper.rb +18 -0
- data/test/test_compile_errors.rb +142 -0
- data/test/test_error_handling.rb +59 -0
- data/test/test_sandboxed_erb.rb +230 -0
- data/test/test_valid_templates.rb +170 -0
- metadata +181 -0
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSandboxedErb < Test::Unit::TestCase
|
4
|
+
should "compile an erb template" do
|
5
|
+
compiled_template = SandboxedErb::Template.new.compile_erb_template("Hello World, 1 + 1 = <%= 1 + 1 %>.")
|
6
|
+
assert_equal '_erbout = \'\'; _erbout.concat "Hello World, 1 + 1 = "; _erbout.concat(( 1 + 1 ).to_s); _erbout.concat "."; _erbout', compiled_template
|
7
|
+
end
|
8
|
+
|
9
|
+
should "sandbox a basic compiled template" do
|
10
|
+
compiled_template = '_erbout = \'\'; _erbout.concat "Hello World, 1 + 1 = "; _erbout.concat(( 1 + 1 ).to_s); _erbout.concat "."; _erbout'
|
11
|
+
sandboxed_template = SandboxedErb::Template.new.sandbox_code(compiled_template)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "fully compile a basic template" do
|
15
|
+
template = SandboxedErb::Template.new
|
16
|
+
template.compile("Hello World, 1 + 1 = <%= 1 + 1 %>.")
|
17
|
+
end
|
18
|
+
|
19
|
+
should "fully compile and run a basic template" do
|
20
|
+
template = SandboxedErb::Template.new
|
21
|
+
template.compile("Hello World, 1 + 1 = <%= 1 + 1 %>.")
|
22
|
+
|
23
|
+
result = template.run(nil, {})
|
24
|
+
|
25
|
+
assert_equal "Hello World, 1 + 1 = 2.", result
|
26
|
+
end
|
27
|
+
|
28
|
+
should "be able to access local variables" do
|
29
|
+
data = { :key1 =>"A", :key2=>"B" }
|
30
|
+
str_template = "the value for key1 is <%=data[:key1] %> and key2 is <%=data[:key2] %>"
|
31
|
+
template = SandboxedErb::Template.new
|
32
|
+
template.compile(str_template)
|
33
|
+
result = template.run(nil, {:data=>data})
|
34
|
+
assert_equal "the value for key1 is A and key2 is B", result
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to sandbox a class" do
|
38
|
+
|
39
|
+
class TestClass
|
40
|
+
sandboxed_methods :ok_to_call
|
41
|
+
|
42
|
+
def ok_to_call
|
43
|
+
"A"
|
44
|
+
end
|
45
|
+
|
46
|
+
def not_ok_to_call
|
47
|
+
"B"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
tc = TestClass.new
|
52
|
+
assert_equal "A", tc._sbm(:ok_to_call)
|
53
|
+
|
54
|
+
|
55
|
+
assert_raise(SandboxedErb::MissingMethodError) {
|
56
|
+
tc._sbm(:not_ok_to_call).to_s
|
57
|
+
}
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
should "be able to access sandboxed class in template" do
|
63
|
+
|
64
|
+
class TestClass
|
65
|
+
sandboxed_methods :ok_to_call
|
66
|
+
|
67
|
+
def ok_to_call
|
68
|
+
"A"
|
69
|
+
end
|
70
|
+
|
71
|
+
def not_ok_to_call
|
72
|
+
"B"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
str_template = "ok_to_call = <%=tc.ok_to_call %>"
|
77
|
+
template = SandboxedErb::Template.new
|
78
|
+
template.compile(str_template)
|
79
|
+
result = template.run(nil, {:tc=>TestClass.new})
|
80
|
+
|
81
|
+
assert_equal "ok_to_call = A", result
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
should "report insecure call during run: method" do
|
86
|
+
str_template = "i shoudl not be
|
87
|
+
able to get
|
88
|
+
<%
|
89
|
+
eval('something')
|
90
|
+
%>
|
91
|
+
"
|
92
|
+
template = SandboxedErb::Template.new
|
93
|
+
assert_equal true, template.compile(str_template)
|
94
|
+
assert_equal nil, template.run(nil, {})
|
95
|
+
|
96
|
+
assert_equal "Error on line 4: Unknown method: eval", template.get_error
|
97
|
+
end
|
98
|
+
|
99
|
+
should "not be able to call Object methods: object_id" do
|
100
|
+
str_template = "test=<%=test_object.object_id%>"
|
101
|
+
|
102
|
+
class TestObject
|
103
|
+
sandboxed_methods :valid_method
|
104
|
+
def valid_method
|
105
|
+
"ABC"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
template = SandboxedErb::Template.new
|
110
|
+
assert_equal true, template.compile(str_template)
|
111
|
+
assert_equal nil, template.run(nil, {:test_object=>TestObject.new})
|
112
|
+
|
113
|
+
assert_equal "Error on line 1: Unknown method 'object_id' on object 'TestSandboxedErb::TestObject'", template.get_error
|
114
|
+
end
|
115
|
+
|
116
|
+
should "not be able to call Object methods: send" do
|
117
|
+
str_template = "test=<%=test_object.__send__(:valid_method)%>"
|
118
|
+
|
119
|
+
class TestObject
|
120
|
+
sandboxed_methods :valid_method
|
121
|
+
def valid_method
|
122
|
+
"ABC"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
template = SandboxedErb::Template.new
|
127
|
+
assert_equal true, template.compile(str_template)
|
128
|
+
assert_equal nil, template.run(nil, {:test_object=>TestObject.new})
|
129
|
+
|
130
|
+
assert_equal "Error on line 1: Unknown method '__send__' on object 'TestSandboxedErb::TestObject'", template.get_error
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
should "not be able to call Object methods on literal values" do
|
135
|
+
str_template = "test=<%=2.__send__(:object_id)%>"
|
136
|
+
|
137
|
+
|
138
|
+
template = SandboxedErb::Template.new
|
139
|
+
assert_equal true, template.compile(str_template)
|
140
|
+
assert_equal nil, template.run(nil, {})
|
141
|
+
|
142
|
+
assert_equal "Error on line 1: Unknown method '__send__' on object 'Fixnum'", template.get_error
|
143
|
+
end
|
144
|
+
|
145
|
+
should "not be able to set attributes of objects" do
|
146
|
+
str_template = "test <%test_object.valid_method='ABC'%>"
|
147
|
+
|
148
|
+
class TestObject
|
149
|
+
sandboxed_methods :valid_method
|
150
|
+
def valid_method
|
151
|
+
"ABC"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
template = SandboxedErb::Template.new
|
156
|
+
assert_equal true, template.compile(str_template)
|
157
|
+
assert_equal nil, template.run(nil, {:test_object=>TestObject.new})
|
158
|
+
assert_equal "Error on line 1: Unknown method 'valid_method=' on object 'TestSandboxedErb::TestObject'", template.get_error
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
should "allow mixins" do
|
163
|
+
|
164
|
+
module MixinTest
|
165
|
+
def test_mixin_method(val)
|
166
|
+
"TEST #{val}"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
str_template = "mixin = <%= test_mixin_method(1) %>"
|
171
|
+
template = SandboxedErb::Template.new([MixinTest])
|
172
|
+
assert_equal true, template.compile(str_template)
|
173
|
+
result = template.run(nil, {})
|
174
|
+
|
175
|
+
assert_equal "mixin = TEST 1", result
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
should "allow multiple mixins" do
|
180
|
+
|
181
|
+
module MixinTest1
|
182
|
+
def test_mixin_method1(val)
|
183
|
+
"TEST #{val}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
module MixinTest2
|
188
|
+
def test_mixin_method2(val)
|
189
|
+
"TEST #{val}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
str_template = "mixin = <%= test_mixin_method1(test_mixin_method2('A')) %>"
|
194
|
+
template = SandboxedErb::Template.new([MixinTest1, MixinTest2])
|
195
|
+
assert_equal true, template.compile(str_template)
|
196
|
+
result = template.run(nil, {})
|
197
|
+
|
198
|
+
assert_equal "mixin = TEST TEST A", result
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
should "access context objects from mixins" do
|
203
|
+
|
204
|
+
module MixinTest
|
205
|
+
def test_mixin_method
|
206
|
+
"TEST #{@controller.some_value}"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
class FauxController
|
211
|
+
def some_value
|
212
|
+
"ABC"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
faux_controller = FauxController.new
|
217
|
+
|
218
|
+
str_template = "mixin = <%= test_mixin_method %>"
|
219
|
+
template = SandboxedErb::Template.new([MixinTest])
|
220
|
+
assert_equal true, template.compile(str_template)
|
221
|
+
result = template.run({:controller=>faux_controller}, {})
|
222
|
+
|
223
|
+
assert_equal "mixin = TEST ABC", result
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestValidTemplates < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "allow for loop" do
|
6
|
+
str_template = "<%for i in 0..3 do %><%=i%><%end%>"
|
7
|
+
|
8
|
+
|
9
|
+
template = SandboxedErb::Template.new
|
10
|
+
result = template.compile(str_template)
|
11
|
+
|
12
|
+
assert_equal nil, template.get_error
|
13
|
+
|
14
|
+
assert_equal true, result
|
15
|
+
|
16
|
+
result = template.run(nil,{})
|
17
|
+
|
18
|
+
assert_equal nil, template.get_error
|
19
|
+
assert_equal "0123", result
|
20
|
+
end
|
21
|
+
|
22
|
+
should "allow whole loop" do
|
23
|
+
str_template = "<%
|
24
|
+
i=0
|
25
|
+
while i <= 3 do %><%=i%><% i+=1
|
26
|
+
end%>"
|
27
|
+
|
28
|
+
template = SandboxedErb::Template.new
|
29
|
+
result = template.compile(str_template)
|
30
|
+
|
31
|
+
assert_equal nil, template.get_error
|
32
|
+
|
33
|
+
assert_equal true, result
|
34
|
+
|
35
|
+
result = template.run(nil,{})
|
36
|
+
|
37
|
+
assert_equal nil, template.get_error
|
38
|
+
assert_equal "0123", result
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
should "allow if statement" do
|
43
|
+
str_template = "<%
|
44
|
+
i=0
|
45
|
+
if i > 10 %>1<%else%>2<%end%>"
|
46
|
+
|
47
|
+
template = SandboxedErb::Template.new
|
48
|
+
result = template.compile(str_template)
|
49
|
+
|
50
|
+
assert_equal nil, template.get_error
|
51
|
+
|
52
|
+
assert_equal true, result
|
53
|
+
|
54
|
+
result = template.run(nil,{})
|
55
|
+
|
56
|
+
assert_equal nil, template.get_error
|
57
|
+
assert_equal "2", result
|
58
|
+
end
|
59
|
+
|
60
|
+
should "allow unless statement" do
|
61
|
+
str_template = "<%
|
62
|
+
i=0
|
63
|
+
unless i > 10 %>1<%else%>2<%end%>"
|
64
|
+
|
65
|
+
template = SandboxedErb::Template.new
|
66
|
+
result = template.compile(str_template)
|
67
|
+
assert_equal nil, template.get_error
|
68
|
+
|
69
|
+
assert_equal true, result
|
70
|
+
|
71
|
+
result = template.run(nil,{})
|
72
|
+
|
73
|
+
assert_equal nil, template.get_error
|
74
|
+
assert_equal "1", result
|
75
|
+
end
|
76
|
+
|
77
|
+
should "allow case statement" do
|
78
|
+
str_template = "<%
|
79
|
+
i=3
|
80
|
+
case i
|
81
|
+
when 0...3: %>1<%
|
82
|
+
when 4..100: %>2<%
|
83
|
+
when 2...4:%>3<%
|
84
|
+
else %>4<%
|
85
|
+
end%>"
|
86
|
+
|
87
|
+
template = SandboxedErb::Template.new
|
88
|
+
result = template.compile(str_template)
|
89
|
+
assert_equal nil, template.get_error
|
90
|
+
|
91
|
+
assert_equal true, result
|
92
|
+
|
93
|
+
result = template.run(nil,{})
|
94
|
+
|
95
|
+
assert_equal nil, template.get_error
|
96
|
+
assert_equal "3", result
|
97
|
+
end
|
98
|
+
|
99
|
+
should "allow defining array" do
|
100
|
+
str_template = "<%
|
101
|
+
test = [1,2,3,4]
|
102
|
+
%><%=test[2]%>"
|
103
|
+
|
104
|
+
template = SandboxedErb::Template.new
|
105
|
+
result = template.compile(str_template)
|
106
|
+
assert_equal nil, template.get_error
|
107
|
+
|
108
|
+
assert_equal true, result
|
109
|
+
|
110
|
+
result = template.run(nil,{})
|
111
|
+
|
112
|
+
assert_equal nil, template.get_error
|
113
|
+
assert_equal "3", result
|
114
|
+
end
|
115
|
+
|
116
|
+
should "allow setting array value" do
|
117
|
+
str_template = "<%
|
118
|
+
test = [1,2,3,4]
|
119
|
+
test[2] = 8
|
120
|
+
%><%=test[2]%>"
|
121
|
+
|
122
|
+
template = SandboxedErb::Template.new
|
123
|
+
result = template.compile(str_template)
|
124
|
+
assert_equal nil, template.get_error
|
125
|
+
|
126
|
+
assert_equal true, result
|
127
|
+
|
128
|
+
result = template.run(nil,{})
|
129
|
+
|
130
|
+
assert_equal nil, template.get_error
|
131
|
+
assert_equal "8", result
|
132
|
+
end
|
133
|
+
|
134
|
+
should "allow defining hash" do
|
135
|
+
str_template = "<%
|
136
|
+
test = {1=>2,2=>3,3=>4,4=>5}
|
137
|
+
%><%=test[2]%>"
|
138
|
+
|
139
|
+
template = SandboxedErb::Template.new
|
140
|
+
result = template.compile(str_template)
|
141
|
+
assert_equal nil, template.get_error
|
142
|
+
|
143
|
+
assert_equal true, result
|
144
|
+
|
145
|
+
result = template.run(nil,{})
|
146
|
+
|
147
|
+
assert_equal nil, template.get_error
|
148
|
+
assert_equal "3", result
|
149
|
+
end
|
150
|
+
|
151
|
+
should "allow setting hash value" do
|
152
|
+
str_template = "<%
|
153
|
+
test = {1=>2,2=>3,3=>4,4=>5}
|
154
|
+
test[2] = 8
|
155
|
+
%><%=test[2]%>"
|
156
|
+
|
157
|
+
template = SandboxedErb::Template.new
|
158
|
+
result = template.compile(str_template)
|
159
|
+
assert_equal nil, template.get_error
|
160
|
+
|
161
|
+
assert_equal true, result
|
162
|
+
|
163
|
+
result = template.run(nil,{})
|
164
|
+
|
165
|
+
assert_equal nil, template.get_error
|
166
|
+
assert_equal "8", result
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
end
|
metadata
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sandboxed_erb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- MarkPent
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-06-05 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 23
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
version: 0.2.0
|
32
|
+
version_requirements: *id001
|
33
|
+
name: partialruby
|
34
|
+
prerelease: false
|
35
|
+
type: :runtime
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
- 0
|
46
|
+
- 6
|
47
|
+
version: 2.0.6
|
48
|
+
version_requirements: *id002
|
49
|
+
name: ruby_parser
|
50
|
+
prerelease: false
|
51
|
+
type: :runtime
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
version_requirements: *id003
|
63
|
+
name: shoulda
|
64
|
+
prerelease: false
|
65
|
+
type: :development
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 23
|
73
|
+
segments:
|
74
|
+
- 1
|
75
|
+
- 0
|
76
|
+
- 0
|
77
|
+
version: 1.0.0
|
78
|
+
version_requirements: *id004
|
79
|
+
name: bundler
|
80
|
+
prerelease: false
|
81
|
+
type: :development
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ~>
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 13
|
89
|
+
segments:
|
90
|
+
- 1
|
91
|
+
- 6
|
92
|
+
- 1
|
93
|
+
version: 1.6.1
|
94
|
+
version_requirements: *id005
|
95
|
+
name: jeweler
|
96
|
+
prerelease: false
|
97
|
+
type: :development
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
version_requirements: *id006
|
109
|
+
name: rcov
|
110
|
+
prerelease: false
|
111
|
+
type: :development
|
112
|
+
description: All your customers to extend your web application by exposing erb templates that can be safely run on your server within a sandbox.
|
113
|
+
email: mark.pent@gmail.com
|
114
|
+
executables: []
|
115
|
+
|
116
|
+
extensions: []
|
117
|
+
|
118
|
+
extra_rdoc_files:
|
119
|
+
- LICENSE.txt
|
120
|
+
- README.rdoc
|
121
|
+
files:
|
122
|
+
- .document
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE.txt
|
125
|
+
- README.rdoc
|
126
|
+
- Rakefile
|
127
|
+
- VERSION
|
128
|
+
- example/controller.rb
|
129
|
+
- example/example.rb
|
130
|
+
- example/listing.sbhtml
|
131
|
+
- example/note.rb
|
132
|
+
- example/users.rb
|
133
|
+
- example/view_notes.sbhtml
|
134
|
+
- lib/sandboxed_erb.rb
|
135
|
+
- lib/sandboxed_erb/sandbox_methods.rb
|
136
|
+
- lib/sandboxed_erb/system_mixins.rb
|
137
|
+
- lib/sandboxed_erb/template.rb
|
138
|
+
- lib/sandboxed_erb/tree_processor.rb
|
139
|
+
- profile/vs_erb.rb
|
140
|
+
- profile/vs_liquid.rb
|
141
|
+
- sandboxed_erb.gemspec
|
142
|
+
- test/helper.rb
|
143
|
+
- test/test_compile_errors.rb
|
144
|
+
- test/test_error_handling.rb
|
145
|
+
- test/test_sandboxed_erb.rb
|
146
|
+
- test/test_valid_templates.rb
|
147
|
+
homepage: http://github.com/markpent/SandboxedERB
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
post_install_message:
|
151
|
+
rdoc_options: []
|
152
|
+
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
none: false
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
hash: 3
|
161
|
+
segments:
|
162
|
+
- 0
|
163
|
+
version: "0"
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
hash: 3
|
170
|
+
segments:
|
171
|
+
- 0
|
172
|
+
version: "0"
|
173
|
+
requirements: []
|
174
|
+
|
175
|
+
rubyforge_project:
|
176
|
+
rubygems_version: 1.7.2
|
177
|
+
signing_key:
|
178
|
+
specification_version: 3
|
179
|
+
summary: Run an erb template in a sandbox.
|
180
|
+
test_files: []
|
181
|
+
|