roo 2.6.0 → 2.7.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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.travis.yml +2 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile +2 -4
- data/Gemfile_ruby2 +4 -3
- data/README.md +10 -0
- data/lib/roo/base.rb +14 -165
- data/lib/roo/csv.rb +93 -98
- data/lib/roo/excelx.rb +8 -3
- data/lib/roo/excelx/cell/datetime.rb +38 -28
- data/lib/roo/excelx/cell/number.rb +19 -23
- data/lib/roo/excelx/cell/time.rb +13 -13
- data/lib/roo/formatters/base.rb +15 -0
- data/lib/roo/formatters/csv.rb +84 -0
- data/lib/roo/formatters/matrix.rb +23 -0
- data/lib/roo/formatters/xml.rb +31 -0
- data/lib/roo/formatters/yaml.rb +40 -0
- data/lib/roo/open_office.rb +9 -3
- data/lib/roo/tempdir.rb +5 -10
- data/lib/roo/version.rb +1 -1
- data/roo.gemspec +1 -0
- data/spec/spec_helper.rb +2 -6
- data/test/excelx/cell/test_time.rb +3 -3
- data/test/formatters/test_csv.rb +119 -0
- data/test/formatters/test_matrix.rb +76 -0
- data/test/formatters/test_xml.rb +74 -0
- data/test/formatters/test_yaml.rb +20 -0
- data/test/roo/test_csv.rb +52 -0
- data/test/roo/test_excelx.rb +186 -0
- data/test/roo/test_libre_office.rb +9 -0
- data/test/roo/test_open_office.rb +126 -0
- data/test/test_helper.rb +74 -3
- data/test/test_roo.rb +22 -928
- metadata +55 -21
data/lib/roo/excelx.rb
CHANGED
@@ -4,12 +4,11 @@ require 'roo/link'
|
|
4
4
|
require 'roo/tempdir'
|
5
5
|
require 'roo/utils'
|
6
6
|
require 'forwardable'
|
7
|
+
require 'set'
|
7
8
|
|
8
9
|
module Roo
|
9
10
|
class Excelx < Roo::Base
|
10
11
|
extend Roo::Tempdir
|
11
|
-
|
12
|
-
require 'set'
|
13
12
|
extend Forwardable
|
14
13
|
|
15
14
|
ERROR_VALUES = %w(#N/A #REF! #NAME? #DIV/0! #NULL! #VALUE! #NUM!).to_set
|
@@ -46,7 +45,13 @@ module Roo
|
|
46
45
|
basename = find_basename(filename_or_stream)
|
47
46
|
end
|
48
47
|
|
48
|
+
# NOTE: Create temp directory and allow Ruby to cleanup the temp directory
|
49
|
+
# when the object is garbage collected. Initially, the finalizer was
|
50
|
+
# created in the Roo::Tempdir module, but that led to a segfault
|
51
|
+
# when testing in Ruby 2.4.0.
|
49
52
|
@tmpdir = self.class.make_tempdir(self, basename, options[:tmpdir_root])
|
53
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(object_id))
|
54
|
+
|
50
55
|
@shared = Shared.new(@tmpdir)
|
51
56
|
@filename = local_filename(filename_or_stream, @tmpdir, packed)
|
52
57
|
process_zipfile(@filename || filename_or_stream)
|
@@ -218,7 +223,7 @@ module Roo
|
|
218
223
|
sheet = sheet_for(sheet)
|
219
224
|
key = normalize(row, col)
|
220
225
|
cell = sheet.cells[key]
|
221
|
-
!cell || cell.empty? ||
|
226
|
+
!cell || cell.empty? ||
|
222
227
|
(row < sheet.first_row || row > sheet.last_row || col < sheet.first_column || col > sheet.last_column)
|
223
228
|
end
|
224
229
|
|
@@ -32,14 +32,9 @@ module Roo
|
|
32
32
|
#
|
33
33
|
# Returns a String representation of a cell's value.
|
34
34
|
def formatted_value
|
35
|
-
date_regex = /(?<date>[dmy]+[\-\/][dmy]+([\-\/][dmy]+)?)/
|
36
|
-
time_regex = /(?<time>(\[?[h]\]?+:)?[m]+(:?ss|:?s)?)/
|
37
|
-
|
38
35
|
formatter = @format.downcase.split(' ').map do |part|
|
39
|
-
if
|
40
|
-
|
41
|
-
elsif part[time_regex]
|
42
|
-
part.gsub(/#{TIME_FORMATS.keys.join('|')}/, TIME_FORMATS)
|
36
|
+
if (parsed_format = parse_date_or_time_format(part))
|
37
|
+
parsed_format
|
43
38
|
else
|
44
39
|
warn 'Unable to parse custom format. Using "YYYY-mm-dd HH:MM:SS" format.'
|
45
40
|
return @value.strftime('%F %T')
|
@@ -51,35 +46,50 @@ module Roo
|
|
51
46
|
|
52
47
|
private
|
53
48
|
|
49
|
+
def parse_date_or_time_format(part)
|
50
|
+
date_regex = /(?<date>[dmy]+[\-\/][dmy]+([\-\/][dmy]+)?)/
|
51
|
+
time_regex = /(?<time>(\[?[h]\]?+:)?[m]+(:?ss|:?s)?)/
|
52
|
+
|
53
|
+
if part[date_regex] == part
|
54
|
+
formats = DATE_FORMATS
|
55
|
+
elsif part[time_regex]
|
56
|
+
formats = TIME_FORMATS
|
57
|
+
else
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
part.gsub(/#{formats.keys.join('|')}/, formats)
|
62
|
+
end
|
63
|
+
|
54
64
|
DATE_FORMATS = {
|
55
|
-
'yyyy'
|
56
|
-
'yy'
|
65
|
+
'yyyy' => '%Y', # Year: 2000
|
66
|
+
'yy' => '%y', # Year: 00
|
57
67
|
# mmmmm => J-D
|
58
|
-
'mmmm'
|
59
|
-
'mmm'
|
60
|
-
'mm'
|
61
|
-
'm'
|
62
|
-
'dddd'
|
63
|
-
'ddd'
|
64
|
-
'dd'
|
65
|
-
'd'
|
68
|
+
'mmmm' => '%B', # Month: January
|
69
|
+
'mmm' => '%^b', # Month: JAN
|
70
|
+
'mm' => '%m', # Month: 01
|
71
|
+
'm' => '%-m', # Month: 1
|
72
|
+
'dddd' => '%A', # Day of the Week: Sunday
|
73
|
+
'ddd' => '%^a', # Day of the Week: SUN
|
74
|
+
'dd' => '%d', # Day of the Month: 01
|
75
|
+
'd' => '%-d' # Day of the Month: 1
|
66
76
|
# '\\\\'.freeze => ''.freeze, # NOTE: Fixes a custom format's output.
|
67
77
|
}
|
68
78
|
|
69
79
|
TIME_FORMATS = {
|
70
|
-
'hh'
|
71
|
-
'h'
|
80
|
+
'hh' => '%H', # Hour (24): 01
|
81
|
+
'h' => '%-k'.freeze, # Hour (24): 1
|
72
82
|
# 'hh'.freeze => '%I'.freeze, # Hour (12): 08
|
73
83
|
# 'h'.freeze => '%-l'.freeze, # Hour (12): 8
|
74
|
-
'mm'
|
84
|
+
'mm' => '%M', # Minute: 01
|
75
85
|
# FIXME: is this used? Seems like 'm' is used for month, not minute.
|
76
|
-
'm'
|
77
|
-
'ss'
|
78
|
-
's'
|
79
|
-
'am/pm'
|
80
|
-
'000'
|
81
|
-
'00'
|
82
|
-
'0'
|
86
|
+
'm' => '%-M', # Minute: 1
|
87
|
+
'ss' => '%S', # Seconds: 01
|
88
|
+
's' => '%-S', # Seconds: 1
|
89
|
+
'am/pm' => '%p', # Meridian: AM
|
90
|
+
'000' => '%3N', # Fractional Seconds: thousandth.
|
91
|
+
'00' => '%2N', # Fractional Seconds: hundredth.
|
92
|
+
'0' => '%1N' # Fractional Seconds: tenths.
|
83
93
|
}
|
84
94
|
|
85
95
|
def create_datetime(base_date, value)
|
@@ -93,7 +103,7 @@ module Roo
|
|
93
103
|
def round_datetime(datetime_string)
|
94
104
|
/(?<yyyy>\d+)-(?<mm>\d+)-(?<dd>\d+) (?<hh>\d+):(?<mi>\d+):(?<ss>\d+.\d+)/ =~ datetime_string
|
95
105
|
|
96
|
-
::Time.new(yyyy
|
106
|
+
::Time.new(yyyy, mm, dd, hh, mi, ss.to_r).round(0)
|
97
107
|
end
|
98
108
|
end
|
99
109
|
end
|
@@ -32,7 +32,7 @@ module Roo
|
|
32
32
|
if formatter.is_a? Proc
|
33
33
|
formatter.call(@cell_value)
|
34
34
|
elsif zero_padded_number?
|
35
|
-
"%0#{@format.size}d"% @cell_value
|
35
|
+
"%0#{@format.size}d" % @cell_value
|
36
36
|
else
|
37
37
|
Kernel.format(formatter, @cell_value)
|
38
38
|
end
|
@@ -45,12 +45,9 @@ module Roo
|
|
45
45
|
'General' => '%.0f',
|
46
46
|
'0' => '%.0f',
|
47
47
|
'0.00' => '%.2f',
|
48
|
-
'
|
49
|
-
|
50
|
-
|
51
|
-
'#,##0.00' => proc do |number|
|
52
|
-
Kernel.format('%.2f', number).reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
53
|
-
end,
|
48
|
+
'0.000000' => '%.6f',
|
49
|
+
'#,##0' => number_format('%.0f'),
|
50
|
+
'#,##0.00' => number_format('%.2f'),
|
54
51
|
'0%' => proc do |number|
|
55
52
|
Kernel.format('%d%', number.to_f * 100)
|
56
53
|
end,
|
@@ -58,22 +55,10 @@ module Roo
|
|
58
55
|
Kernel.format('%.2f%', number.to_f * 100)
|
59
56
|
end,
|
60
57
|
'0.00E+00' => '%.2E',
|
61
|
-
'#,##0 ;(#,##0)' =>
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
'#,##0 ;[Red](#,##0)' => proc do |number|
|
66
|
-
formatter = number.to_i > 0 ? '%.0f' : '[Red](%.0f)'
|
67
|
-
Kernel.format(formatter, number.to_f.abs).reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
68
|
-
end,
|
69
|
-
'#,##0.00;(#,##0.00)' => proc do |number|
|
70
|
-
formatter = number.to_i > 0 ? '%.2f' : '(%.2f)'
|
71
|
-
Kernel.format(formatter, number.to_f.abs).reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
72
|
-
end,
|
73
|
-
'#,##0.00;[Red](#,##0.00)' => proc do |number|
|
74
|
-
formatter = number.to_i > 0 ? '%.2f' : '[Red](%.2f)'
|
75
|
-
Kernel.format(formatter, number.to_f.abs).reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
76
|
-
end,
|
58
|
+
'#,##0 ;(#,##0)' => number_format('%.0f', '(%.0f)'),
|
59
|
+
'#,##0 ;[Red](#,##0)' => number_format('%.0f', '[Red](%.0f)'),
|
60
|
+
'#,##0.00;(#,##0.00)' => number_format('%.2f', '(%.2f)'),
|
61
|
+
'#,##0.00;[Red](#,##0.00)' => number_format('%.2f', '[Red](%.2f)'),
|
77
62
|
# FIXME: not quite sure what the format should look like in this case.
|
78
63
|
'##0.0E+0' => '%.1E',
|
79
64
|
'@' => proc { |number| number }
|
@@ -82,6 +67,17 @@ module Roo
|
|
82
67
|
|
83
68
|
private
|
84
69
|
|
70
|
+
def number_format(formatter, negative_formatter = nil)
|
71
|
+
proc do |number|
|
72
|
+
if negative_formatter
|
73
|
+
formatter = number.to_i > 0 ? formatter : negative_formatter
|
74
|
+
number = number.to_f.abs
|
75
|
+
end
|
76
|
+
|
77
|
+
Kernel.format(formatter, number).reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
85
81
|
def zero_padded_number?
|
86
82
|
@format[/0+/] == @format
|
87
83
|
end
|
data/lib/roo/excelx/cell/time.rb
CHANGED
@@ -24,19 +24,19 @@ module Roo
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
def create_datetime(base_date, value)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def round_datetime(datetime_string)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
27
|
+
# def create_datetime(base_date, value)
|
28
|
+
# date = base_date + value.to_f.round(6)
|
29
|
+
# datetime_string = date.strftime('%Y-%m-%d %H:%M:%S.%N')
|
30
|
+
# t = round_datetime(datetime_string)
|
31
|
+
#
|
32
|
+
# ::DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# def round_datetime(datetime_string)
|
36
|
+
# /(?<yyyy>\d+)-(?<mm>\d+)-(?<dd>\d+) (?<hh>\d+):(?<mi>\d+):(?<ss>\d+.\d+)/ =~ datetime_string
|
37
|
+
#
|
38
|
+
# ::Time.new(yyyy.to_i, mm.to_i, dd.to_i, hh.to_i, mi.to_i, ss.to_r).round(0)
|
39
|
+
# end
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Roo
|
2
|
+
module Formatters
|
3
|
+
module Base
|
4
|
+
# converts an integer value to a time string like '02:05:06'
|
5
|
+
def integer_to_timestring(content)
|
6
|
+
h = (content / 3600.0).floor
|
7
|
+
content -= h * 3600
|
8
|
+
m = (content / 60.0).floor
|
9
|
+
content -= m * 60
|
10
|
+
s = content
|
11
|
+
Kernel.format("%02d:%02d:%02d", h, m, s)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Roo
|
2
|
+
module Formatters
|
3
|
+
module CSV
|
4
|
+
def to_csv(filename = nil, separator = ",", sheet = default_sheet)
|
5
|
+
if filename
|
6
|
+
File.open(filename, "w") do |file|
|
7
|
+
write_csv_content(file, sheet, separator)
|
8
|
+
end
|
9
|
+
true
|
10
|
+
else
|
11
|
+
sio = ::StringIO.new
|
12
|
+
write_csv_content(sio, sheet, separator)
|
13
|
+
sio.rewind
|
14
|
+
sio.read
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Write all cells to the csv file. File can be a filename or nil. If the
|
21
|
+
# file argument is nil the output goes to STDOUT
|
22
|
+
def write_csv_content(file = nil, sheet = nil, separator = ",")
|
23
|
+
file ||= STDOUT
|
24
|
+
return unless first_row(sheet) # The sheet is empty
|
25
|
+
|
26
|
+
1.upto(last_row(sheet)) do |row|
|
27
|
+
1.upto(last_column(sheet)) do |col|
|
28
|
+
# TODO: use CSV.generate_line
|
29
|
+
file.print(separator) if col > 1
|
30
|
+
file.print cell_to_csv(row, col, sheet)
|
31
|
+
end
|
32
|
+
file.print("\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# The content of a cell in the csv output
|
37
|
+
def cell_to_csv(row, col, sheet)
|
38
|
+
return "" if empty?(row, col, sheet)
|
39
|
+
|
40
|
+
onecell = cell(row, col, sheet)
|
41
|
+
|
42
|
+
case celltype(row, col, sheet)
|
43
|
+
when :string
|
44
|
+
%("#{onecell.gsub('"', '""')}") unless onecell.empty?
|
45
|
+
when :boolean
|
46
|
+
# TODO: this only works for excelx
|
47
|
+
onecell = self.sheet_for(sheet).cells[[row, col]].formatted_value
|
48
|
+
%("#{onecell.gsub('"', '""').downcase}")
|
49
|
+
when :float, :percentage
|
50
|
+
if onecell == onecell.to_i
|
51
|
+
onecell.to_i.to_s
|
52
|
+
else
|
53
|
+
onecell.to_s
|
54
|
+
end
|
55
|
+
when :formula
|
56
|
+
case onecell
|
57
|
+
when String
|
58
|
+
%("#{onecell.gsub('"', '""')}") unless onecell.empty?
|
59
|
+
when Integer
|
60
|
+
onecell.to_s
|
61
|
+
when Float
|
62
|
+
if onecell == onecell.to_i
|
63
|
+
onecell.to_i.to_s
|
64
|
+
else
|
65
|
+
onecell.to_s
|
66
|
+
end
|
67
|
+
when Date, DateTime, TrueClass, FalseClass
|
68
|
+
onecell.to_s
|
69
|
+
else
|
70
|
+
fail "unhandled onecell-class #{onecell.class}"
|
71
|
+
end
|
72
|
+
when :date, :datetime
|
73
|
+
onecell.to_s
|
74
|
+
when :time
|
75
|
+
integer_to_timestring(onecell)
|
76
|
+
when :link
|
77
|
+
%("#{onecell.url.gsub('"', '""')}")
|
78
|
+
else
|
79
|
+
fail "unhandled celltype #{celltype(row, col, sheet)}"
|
80
|
+
end || ""
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Roo
|
2
|
+
module Formatters
|
3
|
+
module Matrix
|
4
|
+
# returns a matrix object from the whole sheet or a rectangular area of a sheet
|
5
|
+
def to_matrix(from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet)
|
6
|
+
require 'matrix'
|
7
|
+
|
8
|
+
return ::Matrix.empty unless first_row
|
9
|
+
|
10
|
+
from_row ||= first_row(sheet)
|
11
|
+
to_row ||= last_row(sheet)
|
12
|
+
from_column ||= first_column(sheet)
|
13
|
+
to_column ||= last_column(sheet)
|
14
|
+
|
15
|
+
::Matrix.rows(from_row.upto(to_row).map do |row|
|
16
|
+
from_column.upto(to_column).map do |col|
|
17
|
+
cell(row, col, sheet)
|
18
|
+
end
|
19
|
+
end)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# returns an XML representation of all sheets of a spreadsheet file
|
2
|
+
module Roo
|
3
|
+
module Formatters
|
4
|
+
module XML
|
5
|
+
def to_xml
|
6
|
+
Nokogiri::XML::Builder.new do |xml|
|
7
|
+
xml.spreadsheet do
|
8
|
+
sheets.each do |sheet|
|
9
|
+
self.default_sheet = sheet
|
10
|
+
xml.sheet(name: sheet) do |x|
|
11
|
+
if first_row && last_row && first_column && last_column
|
12
|
+
# sonst gibt es Fehler bei leeren Blaettern
|
13
|
+
first_row.upto(last_row) do |row|
|
14
|
+
first_column.upto(last_column) do |col|
|
15
|
+
next if empty?(row, col)
|
16
|
+
|
17
|
+
x.cell(cell(row, col),
|
18
|
+
row: row,
|
19
|
+
column: col,
|
20
|
+
type: celltype(row, col))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end.to_xml
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Roo
|
2
|
+
module Formatters
|
3
|
+
module YAML
|
4
|
+
# returns a rectangular area (default: all cells) as yaml-output
|
5
|
+
# you can add additional attributes with the prefix parameter like:
|
6
|
+
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
|
7
|
+
def to_yaml(prefix = {}, from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet)
|
8
|
+
# return an empty string if there is no first_row, i.e. the sheet is empty
|
9
|
+
return "" unless first_row
|
10
|
+
|
11
|
+
from_row ||= first_row(sheet)
|
12
|
+
to_row ||= last_row(sheet)
|
13
|
+
from_column ||= first_column(sheet)
|
14
|
+
to_column ||= last_column(sheet)
|
15
|
+
|
16
|
+
result = "--- \n"
|
17
|
+
from_row.upto(to_row) do |row|
|
18
|
+
from_column.upto(to_column) do |col|
|
19
|
+
next if empty?(row, col, sheet)
|
20
|
+
|
21
|
+
result << "cell_#{row}_#{col}: \n"
|
22
|
+
prefix.each do|k, v|
|
23
|
+
result << " #{k}: #{v} \n"
|
24
|
+
end
|
25
|
+
result << " row: #{row} \n"
|
26
|
+
result << " col: #{col} \n"
|
27
|
+
result << " celltype: #{celltype(row, col, sheet)} \n"
|
28
|
+
value = cell(row, col, sheet)
|
29
|
+
if celltype(row, col, sheet) == :time
|
30
|
+
value = integer_to_timestring(value)
|
31
|
+
end
|
32
|
+
result << " value: #{value} \n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/roo/open_office.rb
CHANGED
@@ -5,6 +5,7 @@ require 'zip/filesystem'
|
|
5
5
|
require 'roo/font'
|
6
6
|
require 'roo/tempdir'
|
7
7
|
require 'base64'
|
8
|
+
require 'openssl'
|
8
9
|
|
9
10
|
module Roo
|
10
11
|
class OpenOffice < Roo::Base
|
@@ -22,7 +23,12 @@ module Roo
|
|
22
23
|
|
23
24
|
@only_visible_sheets = options[:only_visible_sheets]
|
24
25
|
file_type_check(filename, '.ods', 'an Roo::OpenOffice', file_warning, packed)
|
25
|
-
|
26
|
+
# NOTE: Create temp directory and allow Ruby to cleanup the temp directory
|
27
|
+
# when the object is garbage collected. Initially, the finalizer was
|
28
|
+
# created in the Roo::Tempdir module, but that led to a segfault
|
29
|
+
# when testing in Ruby 2.4.0.
|
30
|
+
@tmpdir = self.class.make_tempdir(self, find_basename(filename), options[:tmpdir_root])
|
31
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(object_id))
|
26
32
|
@filename = local_filename(filename, @tmpdir, packed)
|
27
33
|
# TODO: @cells_read[:default] = false
|
28
34
|
open_oo_file(options)
|
@@ -340,7 +346,7 @@ module Roo
|
|
340
346
|
def find_cipher(*args)
|
341
347
|
fail ArgumentError, 'Unknown algorithm ' + algorithm unless args[0] == 'http://www.w3.org/2001/04/xmlenc#aes256-cbc'
|
342
348
|
|
343
|
-
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
349
|
+
cipher = ::OpenSSL::Cipher.new('AES-256-CBC')
|
344
350
|
cipher.decrypt
|
345
351
|
cipher.padding = 0
|
346
352
|
cipher.key = find_cipher_key(cipher, *args[1..4])
|
@@ -353,7 +359,7 @@ module Roo
|
|
353
359
|
def find_cipher_key(*args)
|
354
360
|
fail ArgumentError, 'Unknown key derivation name ', args[1] unless args[1] == 'PBKDF2'
|
355
361
|
|
356
|
-
OpenSSL::PKCS5.pbkdf2_hmac_sha1(args[2], args[3], args[4], args[0].key_len)
|
362
|
+
::OpenSSL::PKCS5.pbkdf2_hmac_sha1(args[2], args[3], args[4], args[0].key_len)
|
357
363
|
end
|
358
364
|
|
359
365
|
# Block decrypt raw bytes from the zip file based on the cipher
|