forked from github/gem-builder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gem_eval.rb
81 lines (71 loc) · 1.98 KB
/
gem_eval.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env ruby
require 'rubygems'
require 'rubygems/specification'
require 'sinatra'
require 'timeout'
require 'yaml'
post '/' do
r, w = IO.pipe
pid = nil
begin
repo = params[:repo]
data = params[:data]
tmpdir = "tmp/#{repo}"
spec = nil
Timeout::timeout(3) do
`git clone --depth 1 git://github.com/#{repo} #{tmpdir}`
pid = fork do
begin
r.close
require File.dirname(__FILE__)+'/security'
require File.dirname(__FILE__)+'/lazy_dir'
Dir.chdir(tmpdir) do
thread = Thread.new do
eval <<-EOE
BEGIN { # First in first out. Get this one exec'ed before the code below.
Object.class_eval do
remove_const :OrigDir rescue nil
OrigDir = Dir
remove_const :Dir
Dir = LazyDir
end
$SAFE = 3
OrigDir.set_safe_level
}
BEGIN { # This forces Ruby to ignore nested END {} blocks
begin
params = tmpdir = data = spec = repo = nil
# Pass data out using TLS
Thread.current[:spec] = (#{data})
ensure
Object.class_eval do
remove_const :Dir
Dir = OrigDir
end
end
}
EOE
end.join
Dir.set_safe_level
spec = thread[:spec]
spec.rubygems_version = Gem::RubyGemsVersion # make sure validation passes
spec.validate
end
w.write YAML.dump(spec)
rescue Object
puts $!,$@
w.write "ERROR: #$!"
end
end
w.close
Process.wait pid
r.read
end
rescue Exception
Process.kill 9, pid
puts $!,$@
"ERROR: #$!"
ensure
`rm -rf #{tmpdir}` if tmpdir
end
end