cgi_multipart_eof_fix 2.1 → 2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/{LICENSE.txt → AFL3-LICENSE} +0 -0
- data/CHANGELOG +9 -0
- data/Manifest +9 -0
- data/README +41 -0
- data/RUBY-LICENSE +58 -0
- data/Rakefile +16 -42
- data/lib/cgi_multipart_eof_fix.rb +109 -98
- data/lib/rake_task_redefine_task.rb +25 -0
- data/{cgi_multipart_eof_fix_test.rb → test/cgi_multipart_eof_fix_test.rb} +0 -0
- metadata +15 -11
- data/README.txt +0 -45
File without changes
|
data/CHANGELOG
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
v2.2. don't load on Ruby > 1.8.5; copyright correction at request of Zed Shaw
|
3
|
+
|
4
|
+
v2.1. license change due to no provision for use in original Ruby license (prevents installation in Florida)
|
5
|
+
|
6
|
+
v2.0. updated for second cgi.rb vulnerability
|
7
|
+
|
8
|
+
v1.0.0. original single-patch release by Zed Shaw, et. al.
|
9
|
+
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
cgi_multipart_eof_fix
|
3
|
+
|
4
|
+
Fix an exploitable bug in CGI multipart parsing.
|
5
|
+
|
6
|
+
== License
|
7
|
+
|
8
|
+
Copyright 2006, 2007 Cloudburst, LLC. Portions copyright 2006 Jeremy Kemper, Jamis Buck, Zed A. Shaw, and Yukihiro Matsumoto, and used with permission. Licensed under both the AFL 3.0 and Ruby License.
|
9
|
+
|
10
|
+
== Description
|
11
|
+
|
12
|
+
Fixes an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5. When multipart boundary attributes contain non-halting regular expression strings, the boundary searcher in the CGI module does not properly escape the parameter and will execute arbitrary regular expressions. This fix adds escaping for the user data.
|
13
|
+
|
14
|
+
This is fix is cumulative with previous CGI multipart vulnerability fixes; see version 1.0.0 of the gem by Jamis Buck et. al.
|
15
|
+
|
16
|
+
== Installation
|
17
|
+
|
18
|
+
sudo gem install cgi_multipart_eof_fix
|
19
|
+
|
20
|
+
== Scope
|
21
|
+
|
22
|
+
* Affected: standalone CGI, Mongrel, WEBrick
|
23
|
+
* Unaffected: FastCGI, Ruby 1.8.6 (all servers)
|
24
|
+
* Unknown: mod_ruby
|
25
|
+
|
26
|
+
This library will not modify versions of Ruby greater than 1.8.5.
|
27
|
+
|
28
|
+
== Usage
|
29
|
+
|
30
|
+
Run the included test to verify that the patch works as intended. Then, <tt>require</tt> the gem in every affected application, as follows:
|
31
|
+
|
32
|
+
require 'rubygems'
|
33
|
+
require 'cgi_multipart_eof_fix'
|
34
|
+
|
35
|
+
Currently Mongrel requires this gem automatically. However, Mongrel may change in the future.
|
36
|
+
|
37
|
+
== Further resources
|
38
|
+
|
39
|
+
* http://blog.evanweaver.com/pages/code#cgi_multipart_eof_fix
|
40
|
+
* http://rubyforge.org/forum/forum.php?forum_id=13985
|
41
|
+
* http://www.ruby-lang.org/en/news/2006/12/04/another-dos-vulnerability-in-cgi-library/
|
data/RUBY-LICENSE
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
(see COPYING.txt file), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict
|
21
|
+
with standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
45
|
+
files under the ./missing directory. See each file for the copying
|
46
|
+
condition.
|
47
|
+
|
48
|
+
5. The scripts and library files supplied as input to or produced as
|
49
|
+
output from the software do not automatically fall under the
|
50
|
+
copyright of the software, but belong to whomever generated them,
|
51
|
+
and may be sold commercially, and may be aggregated with this
|
52
|
+
software.
|
53
|
+
|
54
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
55
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
56
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
57
|
+
PURPOSE.
|
58
|
+
|
data/Rakefile
CHANGED
@@ -1,53 +1,27 @@
|
|
1
|
+
|
1
2
|
require 'rubygems'
|
2
3
|
require 'rake'
|
3
|
-
|
4
|
-
NAME = "cgi_multipart_eof_fix"
|
4
|
+
require 'lib/rake_task_redefine_task.rb'
|
5
5
|
|
6
6
|
begin
|
7
7
|
require 'rake/clean'
|
8
8
|
require 'echoe'
|
9
|
-
require 'fileutils'
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
REV = nil
|
19
|
-
VERS = "2.1"
|
20
|
-
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
21
|
-
RDOC_OPTS = ['--quiet', '--title', "cgi_multipart_eof_fix documentation",
|
22
|
-
"--opname", "index.html",
|
23
|
-
"--line-numbers",
|
24
|
-
"--main", "README",
|
25
|
-
"--inline-source"]
|
26
|
-
|
27
|
-
include FileUtils
|
28
|
-
require File.join(File.dirname(__FILE__), 'lib', 'cgi_multipart_eof_fix')
|
29
|
-
|
30
|
-
echoe = Echoe.new(GEM_NAME, VERS) do |p|
|
31
|
-
p.author = AUTHOR
|
32
|
-
p.rubyforge_name = RUBYFORGE_NAME
|
33
|
-
p.name = NAME
|
34
|
-
p.description = DESCRIPTION
|
35
|
-
p.email = EMAIL
|
36
|
-
p.summary = DESCRIPTION
|
37
|
-
p.url = HOMEPATH
|
38
|
-
p.test_globs = ["*_test.rb"]
|
39
|
-
p.clean_globs = CLEAN
|
10
|
+
echoe = Echoe.new("cgi_multipart_eof_fix") do |p|
|
11
|
+
p.author = "Evan Weaver"
|
12
|
+
p.rubyforge_name = "fauna"
|
13
|
+
p.summary = p.description = "Fix an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5 when multipart boundary attribute contains a non-halting regular expression string."
|
14
|
+
p.url = "http://blog.evanweaver.com/pages/code#cgi_multipart_eof_fix"
|
15
|
+
p.docs_host = "blog.evanweaver.com:~/www/snax/public/files/doc/"
|
16
|
+
p.rdoc_pattern = /CHANGELOG|LICENSE|README|lib\/cgi_multipart_eof_fix/
|
40
17
|
end
|
41
18
|
|
42
|
-
rescue LoadError
|
43
|
-
puts "You are missing a dependency required for meta-operations on this gem."
|
44
|
-
puts "#{boom.to_s.capitalize}."
|
45
|
-
|
19
|
+
rescue LoadError
|
46
20
|
desc 'Run the default tasks'
|
47
|
-
task :default => :test
|
48
|
-
|
49
|
-
desc 'Run the test suite.'
|
50
|
-
task :test do
|
51
|
-
system "ruby -Ibin:lib:test #{NAME}_test.rb"
|
52
|
-
end
|
21
|
+
task :default => :test
|
53
22
|
end
|
23
|
+
|
24
|
+
Rake::Task.redefine_task("test") do
|
25
|
+
system "ruby -Ibin:lib:test test/cgi_multipart_eof_fix_test.rb"
|
26
|
+
end
|
27
|
+
|
@@ -1,112 +1,123 @@
|
|
1
|
-
require 'cgi'
|
2
1
|
|
3
|
-
|
4
|
-
module QueryExtension
|
5
|
-
def read_multipart(boundary, content_length)
|
6
|
-
params = Hash.new([])
|
7
|
-
boundary = "--" + boundary
|
8
|
-
quoted_boundary = Regexp.quote(boundary, "n")
|
9
|
-
buf = ""
|
10
|
-
bufsize = 10 * 1024
|
11
|
-
boundary_end=""
|
2
|
+
version = RUBY_VERSION.split(".").map {|num| num.to_i }
|
12
3
|
|
13
|
-
|
14
|
-
stdinput.binmode if defined? stdinput.binmode
|
15
|
-
boundary_size = boundary.size + EOL.size
|
16
|
-
content_length -= boundary_size
|
17
|
-
status = stdinput.read(boundary_size)
|
18
|
-
if nil == status
|
19
|
-
raise EOFError, "no content body"
|
20
|
-
elsif boundary + EOL != status
|
21
|
-
raise EOFError, "bad content body #{status.inspect} expected, got #{(boundary + EOL).inspect}"
|
22
|
-
end
|
4
|
+
if version[0] < 2 and version[1] < 9 and version[2] < 6
|
23
5
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
6
|
+
$stderr.puts "** Ruby version is not up-to-date; loading cgi_multipart_eof_fix"
|
7
|
+
|
8
|
+
require 'cgi'
|
9
|
+
|
10
|
+
class CGI
|
11
|
+
module QueryExtension
|
12
|
+
def read_multipart(boundary, content_length)
|
13
|
+
params = Hash.new([])
|
14
|
+
boundary = "--" + boundary
|
15
|
+
quoted_boundary = Regexp.quote(boundary, "n")
|
16
|
+
buf = ""
|
17
|
+
bufsize = 10 * 1024
|
18
|
+
boundary_end=""
|
19
|
+
|
20
|
+
# start multipart/form-data
|
21
|
+
stdinput.binmode if defined? stdinput.binmode
|
22
|
+
boundary_size = boundary.size + EOL.size
|
23
|
+
content_length -= boundary_size
|
24
|
+
status = stdinput.read(boundary_size)
|
25
|
+
if nil == status
|
26
|
+
raise EOFError, "no content body"
|
27
|
+
elsif boundary + EOL != status
|
28
|
+
raise EOFError, "bad content body #{status.inspect} expected, got #{(boundary + EOL).inspect}"
|
29
|
+
end
|
30
|
+
|
31
|
+
loop do
|
32
|
+
head = nil
|
33
|
+
if 10240 < content_length
|
34
34
|
require "tempfile"
|
35
35
|
body = Tempfile.new("CGI")
|
36
|
+
else
|
37
|
+
begin
|
38
|
+
require "stringio"
|
39
|
+
body = StringIO.new
|
40
|
+
rescue LoadError
|
41
|
+
require "tempfile"
|
42
|
+
body = Tempfile.new("CGI")
|
43
|
+
end
|
36
44
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
body.binmode if defined? body.binmode
|
46
|
+
|
47
|
+
until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)
|
48
|
+
|
49
|
+
if (not head) and /#{EOL}#{EOL}/n.match(buf)
|
50
|
+
buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
|
51
|
+
head = $1.dup
|
52
|
+
""
|
53
|
+
end
|
54
|
+
next
|
55
|
+
end
|
56
|
+
|
57
|
+
if head and ( (EOL + boundary + EOL).size < buf.size )
|
58
|
+
body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
|
59
|
+
buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
|
60
|
+
end
|
61
|
+
|
62
|
+
c = if bufsize < content_length
|
63
|
+
stdinput.read(bufsize)
|
64
|
+
else
|
65
|
+
stdinput.read(content_length)
|
66
|
+
end
|
67
|
+
if c.nil? || c.empty?
|
68
|
+
raise EOFError, "bad content body"
|
46
69
|
end
|
47
|
-
|
70
|
+
buf.concat(c)
|
71
|
+
content_length -= c.size
|
48
72
|
end
|
49
|
-
|
50
|
-
|
51
|
-
body.print
|
52
|
-
|
73
|
+
|
74
|
+
buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
|
75
|
+
body.print $1
|
76
|
+
if "--" == $2
|
77
|
+
content_length = -1
|
78
|
+
end
|
79
|
+
boundary_end = $2.dup
|
80
|
+
""
|
53
81
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
82
|
+
|
83
|
+
body.rewind
|
84
|
+
|
85
|
+
/Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
|
86
|
+
filename = ($1 or "")
|
87
|
+
if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
|
88
|
+
/Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
|
89
|
+
(not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
|
90
|
+
filename = CGI::unescape(filename)
|
91
|
+
end
|
92
|
+
|
93
|
+
/Content-Type: (.*)/ni.match(head)
|
94
|
+
content_type = ($1 or "")
|
95
|
+
|
96
|
+
(class << body; self; end).class_eval do
|
97
|
+
alias local_path path
|
98
|
+
define_method(:original_filename) {filename.dup.taint}
|
99
|
+
define_method(:content_type) {content_type.dup.taint}
|
62
100
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
101
|
+
|
102
|
+
/Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
|
103
|
+
name = $1.dup
|
104
|
+
|
105
|
+
if params.has_key?(name)
|
106
|
+
params[name].push(body)
|
107
|
+
else
|
108
|
+
params[name] = [body]
|
71
109
|
end
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
body.rewind
|
77
|
-
|
78
|
-
/Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
|
79
|
-
filename = ($1 or "")
|
80
|
-
if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
|
81
|
-
/Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
|
82
|
-
(not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
|
83
|
-
filename = CGI::unescape(filename)
|
84
|
-
end
|
85
|
-
|
86
|
-
/Content-Type: (.*)/ni.match(head)
|
87
|
-
content_type = ($1 or "")
|
88
|
-
|
89
|
-
(class << body; self; end).class_eval do
|
90
|
-
alias local_path path
|
91
|
-
define_method(:original_filename) {filename.dup.taint}
|
92
|
-
define_method(:content_type) {content_type.dup.taint}
|
93
|
-
end
|
94
|
-
|
95
|
-
/Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
|
96
|
-
name = $1.dup
|
97
|
-
|
98
|
-
if params.has_key?(name)
|
99
|
-
params[name].push(body)
|
100
|
-
else
|
101
|
-
params[name] = [body]
|
110
|
+
break if buf.size == 0
|
111
|
+
break if content_length === -1
|
102
112
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end # read_multipart
|
110
|
-
private :read_multipart
|
113
|
+
raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/
|
114
|
+
|
115
|
+
params
|
116
|
+
end # read_multipart
|
117
|
+
private :read_multipart
|
118
|
+
end
|
111
119
|
end
|
120
|
+
|
121
|
+
else
|
122
|
+
$stderr.puts "** Ruby version is up-to-date; cgi_multipart_eof_fix was not loaded"
|
112
123
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
# http://www.bigbold.com/snippets/posts/show/2032
|
3
|
+
module Rake
|
4
|
+
module TaskManager
|
5
|
+
def redefine_task(task_class, args, &block)
|
6
|
+
task_name, deps = resolve_args(args)
|
7
|
+
task_name = task_class.scope_name(@scope, task_name)
|
8
|
+
deps = [deps] unless deps.respond_to?(:to_ary)
|
9
|
+
deps = deps.collect {|d| d.to_s }
|
10
|
+
task = @tasks[task_name.to_s] = task_class.new(task_name, self)
|
11
|
+
task.application = self
|
12
|
+
task.add_comment(@last_comment)
|
13
|
+
@last_comment = nil
|
14
|
+
task.enhance(deps, &block)
|
15
|
+
task
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class Task
|
19
|
+
class << self
|
20
|
+
def redefine_task(args, &block)
|
21
|
+
Rake.application.redefine_task(self, args, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: cgi_multipart_eof_fix
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "2.
|
7
|
-
date: 2007-
|
6
|
+
version: "2.2"
|
7
|
+
date: 2007-08-07 00:00:00 -04:00
|
8
8
|
summary: Fix an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5 when multipart boundary attribute contains a non-halting regular expression string.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
email:
|
12
|
-
homepage: http://blog.evanweaver.com
|
11
|
+
email: ""
|
12
|
+
homepage: http://blog.evanweaver.com/pages/code#cgi_multipart_eof_fix
|
13
13
|
rubyforge_project: fauna
|
14
14
|
description: Fix an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5 when multipart boundary attribute contains a non-halting regular expression string.
|
15
15
|
autorequire:
|
@@ -29,13 +29,17 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Evan Weaver
|
31
31
|
files:
|
32
|
-
-
|
33
|
-
-
|
34
|
-
- Rakefile
|
32
|
+
- test/cgi_multipart_eof_fix_test.rb
|
33
|
+
- lib/rake_task_redefine_task.rb
|
35
34
|
- lib/cgi_multipart_eof_fix.rb
|
36
|
-
-
|
37
|
-
|
38
|
-
-
|
35
|
+
- Rakefile
|
36
|
+
- RUBY-LICENSE
|
37
|
+
- README
|
38
|
+
- Manifest
|
39
|
+
- CHANGELOG
|
40
|
+
- AFL3-LICENSE
|
41
|
+
test_files: []
|
42
|
+
|
39
43
|
rdoc_options: []
|
40
44
|
|
41
45
|
extra_rdoc_files: []
|
data/README.txt
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
|
2
|
-
DESCRIPTION
|
3
|
-
|
4
|
-
Fix an exploitable bug in CGI multipart parsing which affects Ruby <= 1.8.5
|
5
|
-
when multipart boundary attribute contains a non-halting regular expression
|
6
|
-
string. The boundary searcher in the CGI module does not properly escape
|
7
|
-
the user-supplied parameter and will execute arbitrary regular expressions.
|
8
|
-
The fix adds escaping for the user data.
|
9
|
-
|
10
|
-
This is fix is cumulative with previous CGI multipart vulnerability fixes; see
|
11
|
-
version 1.0.0 of the gem by Zed Shaw.
|
12
|
-
|
13
|
-
SCOPE
|
14
|
-
|
15
|
-
Affected: standalone CGI, Mongrel, WEBrick
|
16
|
-
Unaffected: FastCGI
|
17
|
-
Unknown: mod_ruby
|
18
|
-
|
19
|
-
USAGE
|
20
|
-
|
21
|
-
Install the hotfix gem and run the included test to verify the flaw is
|
22
|
-
corrected. You must require the gem in every affected application, as follows:
|
23
|
-
|
24
|
-
require 'rubygems'
|
25
|
-
require 'cgi_multipart_eof_fix'
|
26
|
-
|
27
|
-
If you only use mongrel_rails for application hosting, you may install mongrel
|
28
|
-
like so:
|
29
|
-
|
30
|
-
sudo gem install mongrel --source=http://mongrel.rubyforge.org/releases
|
31
|
-
|
32
|
-
Then mongrel will require the fix for you, provided you have installed version 2.0.0
|
33
|
-
of this gem. This is a hack, and mongrel may change in the future.
|
34
|
-
|
35
|
-
RESOURCES
|
36
|
-
|
37
|
-
http://www.ruby-lang.org/en/news/2006/12/04/another-dos-vulnerability-in-cgi-library/
|
38
|
-
http://blog.evanweaver.com/articles/2006/12/05/cgi-rb-vulnerability-hotfix
|
39
|
-
http://blog.evanweaver.com/articles/2006/12/05/new-cgi-rb-vulnerability
|
40
|
-
|
41
|
-
LICENSE
|
42
|
-
|
43
|
-
Copyright 2006, 2007 Cloudburst, LLC. Portions copyright 2006 Zed A. Shaw,
|
44
|
-
Yukihiro Matsumoto and used with permission. Licensed under the AFL 3.0.
|
45
|
-
See the included LICENSE.txt file.
|