axlsx 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +41 -5
- data/Rakefile +3 -2
- data/examples/chart_colors.rb +18 -3
- data/examples/example.rb +100 -46
- data/examples/extractive.pdf +0 -0
- data/lib/axlsx.rb +7 -6
- data/lib/axlsx/content_type/content_type.rb +2 -0
- data/lib/axlsx/content_type/default.rb +21 -12
- data/lib/axlsx/content_type/override.rb +22 -11
- data/lib/axlsx/doc_props/app.rb +36 -32
- data/lib/axlsx/doc_props/core.rb +9 -5
- data/lib/axlsx/drawing/ax_data_source.rb +7 -6
- data/lib/axlsx/drawing/axis.rb +48 -27
- data/lib/axlsx/drawing/bar_3D_chart.rb +47 -37
- data/lib/axlsx/drawing/bar_series.rb +1 -0
- data/lib/axlsx/drawing/cat_axis.rb +42 -38
- data/lib/axlsx/drawing/chart.rb +34 -27
- data/lib/axlsx/drawing/drawing.rb +5 -4
- data/lib/axlsx/drawing/line_3D_chart.rb +1 -1
- data/lib/axlsx/drawing/num_data_source.rb +1 -1
- data/lib/axlsx/drawing/pie_3D_chart.rb +7 -7
- data/lib/axlsx/drawing/two_cell_anchor.rb +3 -8
- data/lib/axlsx/drawing/view_3D.rb +41 -31
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +11 -11
- data/lib/axlsx/rels/relationship.rb +3 -3
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/util/constants.rb +4 -0
- data/lib/axlsx/util/simple_typed_list.rb +2 -2
- data/lib/axlsx/util/validators.rb +2 -2
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/workbook.rb +1 -2
- data/lib/axlsx/workbook/worksheet/cell.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
- data/lib/axlsx/workbook/worksheet/page_setup.rb +9 -0
- data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +180 -56
- data/test/content_type/tc_content_type.rb +1 -6
- data/test/doc_props/tc_core.rb +1 -1
- data/test/drawing/tc_axis.rb +8 -0
- data/test/drawing/tc_bar_3D_chart.rb +12 -12
- data/test/drawing/tc_bar_series.rb +0 -1
- data/test/drawing/tc_chart.rb +1 -5
- data/test/drawing/tc_pie_3D_chart.rb +3 -7
- data/test/drawing/tc_view_3D.rb +18 -18
- data/test/tc_package.rb +2 -0
- data/test/workbook/worksheet/tc_page_setup.rb +20 -3
- data/test/workbook/worksheet/tc_protected_range.rb +18 -0
- data/test/workbook/worksheet/tc_selection.rb +1 -1
- data/test/workbook/worksheet/tc_worksheet.rb +39 -18
- metadata +54 -103
- data/examples/axis-titles.xlsx +0 -0
- data/examples/basic_charts.xlsx +0 -0
- data/examples/chart_colors.xlsx +0 -0
- data/examples/charts.xlsx +0 -0
- data/examples/conditional_formatting/getting_barred.xlsx +0 -0
- data/examples/doc/_index.html +0 -84
- data/examples/doc/class_list.html +0 -47
- data/examples/doc/css/common.css +0 -1
- data/examples/doc/css/full_list.css +0 -55
- data/examples/doc/css/style.css +0 -322
- data/examples/doc/file_list.html +0 -46
- data/examples/doc/frames.html +0 -13
- data/examples/doc/index.html +0 -84
- data/examples/doc/js/app.js +0 -205
- data/examples/doc/js/full_list.js +0 -173
- data/examples/doc/js/jquery.js +0 -16
- data/examples/doc/method_list.html +0 -46
- data/examples/doc/top-level-namespace.html +0 -95
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/examples_saved.xlsx +0 -0
- data/examples/extractive.xlsx +0 -0
- data/examples/fish.xlsx +0 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/pareto.rb +0 -28
- data/examples/pareto.xlsx +0 -0
- data/examples/pie_chart_excel.xlsx +0 -0
- data/examples/pie_chart_saved.xlsx +0 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_protection.xlsx +0 -0
- data/examples/sheet_view.xlsx +0 -0
- data/examples/two_cell_anchor_image.xlsx +0 -0
- data/examples/~$example.xlsx +0 -0
- data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
- data/lib/axlsx/drawing/data_source.rb~ +0 -51
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/num_data.rb~ +0 -51
- data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
- data/lib/axlsx/drawing/num_val.rb~ +0 -40
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/ref.rb~ +0 -41
- data/lib/axlsx/drawing/str_data.rb~ +0 -58
- data/lib/axlsx/drawing/str_val.rb~ +0 -35
- data/lib/axlsx/drawing/vml_drawing.rb~ +0 -6
- data/lib/axlsx/drawing/vml_shape.rb~ +0 -61
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- data/lib/axlsx/util/font_tables.rb~ +0 -0
- data/lib/axlsx/util/ms_off_crypto.rb +0 -189
- data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
- data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
- data/lib/axlsx/util/parser.rb~ +0 -6
- data/lib/axlsx/util/storage.rb~ +0 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
- data/lib/axlsx/workbook/worksheet/comment.rb~ +0 -91
- data/lib/axlsx/workbook/worksheet/comments.rb~ +0 -86
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
- data/lib/schema/dc.xsd~ +0 -118
- data/lib/schema/dcterms.xsd~ +0 -331
- data/lib/schema/opc-coreProperties.xsd~ +0 -50
- data/test/drawing/tc_data_source.rb~ +0 -30
- data/test/drawing/tc_num_data.rb~ +0 -35
- data/test/drawing/tc_num_val.rb~ +0 -29
- data/test/drawing/tc_str_data.rb~ +0 -30
- data/test/drawing/tc_str_val.rb~ +0 -26
- data/test/drawing/tc_vml_drawing.rb~ +0 -0
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
data/lib/axlsx/util/cfb.rb~
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
module Axlsx
|
2
|
-
|
3
|
-
# The Cfb class is a MS-OFF-CRYPTOGRAPHY specific OLE (MS-CBF) writer implementation. No attempt is made to re-invent the wheel for read/write of compound binary files.
|
4
|
-
class Cbf
|
5
|
-
|
6
|
-
# the serialization for the CBF FAT
|
7
|
-
FAT_PACKING = "s128"
|
8
|
-
|
9
|
-
# the serialization for the MS-OFF-CRYPTO version stream
|
10
|
-
VERSION_PACKING = 'l s30 l3'
|
11
|
-
|
12
|
-
# The serialization for the MS-OFF-CRYPTO dataspace map stream
|
13
|
-
DATA_SPACE_MAP_PACKING = 'l6 s16 l s25'
|
14
|
-
|
15
|
-
# The serialization for the MS-OFF-CRYPTO strong encrytion data space stream
|
16
|
-
STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s25'
|
17
|
-
|
18
|
-
# The serialization for the MS-OFF-CRYPTO primary stream
|
19
|
-
PRIMARY_PACKING = 'l3 s38 l s39 l3 x12 l x2'
|
20
|
-
|
21
|
-
# The cutoff size that determines if a stream should be in the mini-fat or the fat
|
22
|
-
MINI_CUTOFF = 4096
|
23
|
-
|
24
|
-
# Creates a new Cbf object based on a package.
|
25
|
-
def initialize(ms_off_crypto)
|
26
|
-
@file_name = ms_off_crypto.file_name
|
27
|
-
@storages = []
|
28
|
-
@encryption_info = ms_off_crypto.encryption_info
|
29
|
-
@encrypted_package = ms_off_crypto.encrypted_package
|
30
|
-
@storages << Storage.new('R', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :modified=>129685612742510730)
|
31
|
-
@storages.last.name_size = 2
|
32
|
-
@storages << Storage.new('EncryptionInfo', :data=>@encryption_info, :left=>3, :size => @encryption_info.size) # example shows right child. do we need the summary info????
|
33
|
-
@storages << Storage.new('EncryptedPackage', :data=>@encrypted_package, :color=>Storage::COLORS[:red], :size=>@encrypted_package.size)
|
34
|
-
@storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979)
|
35
|
-
@storages << version
|
36
|
-
@storages << data_space_map
|
37
|
-
@storages << Storage.new('DataSpaceInfo', :right=>8, :child=>7, :created=>129685612740828880,:modified=>129685612740831800)
|
38
|
-
@storages << strong_encryption_data_space
|
39
|
-
@storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959)
|
40
|
-
@storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280)
|
41
|
-
@storages << primary
|
42
|
-
mini_fat_stream
|
43
|
-
mini_fat
|
44
|
-
fat
|
45
|
-
header
|
46
|
-
end
|
47
|
-
|
48
|
-
def version
|
49
|
-
@version ||= create_version
|
50
|
-
end
|
51
|
-
|
52
|
-
def data_space_map
|
53
|
-
@data_space_map ||= create_data_space_map
|
54
|
-
end
|
55
|
-
|
56
|
-
def strong_encryption_data_space
|
57
|
-
@strong_encryption_data_space ||= create_strong_encryption_data_space
|
58
|
-
end
|
59
|
-
|
60
|
-
def primary
|
61
|
-
@primary ||= create_primary
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
|
-
def create_primary
|
66
|
-
v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten
|
67
|
-
v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,1,1,1,4].flatten
|
68
|
-
v_stream = v_stream.pack PRIMARY_PACKING
|
69
|
-
Storage.new([6].pack("c")+"Primary", :data=>v_stream, :size=>v_stream.size)
|
70
|
-
end
|
71
|
-
|
72
|
-
def create_strong_encryption_data_space
|
73
|
-
v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
|
74
|
-
Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Create the version storage
|
78
|
-
def create_version
|
79
|
-
v_stream= [60, "Microsoft.Container.DataSpaces".bytes.to_a, 1, 1, 1].flatten!.pack VERSION_PACKING
|
80
|
-
Storage.new('Version', :data=>v_stream, :size=>v_stream.size)
|
81
|
-
end
|
82
|
-
|
83
|
-
def create_data_space_map
|
84
|
-
v_stream = [8,1,104, 1,0, 32, "EncryptedPackage".bytes.to_a, 50, "StrongEncryptionDataSpace".bytes.to_a].flatten!.pack DATA_SPACE_MAP_PACKING
|
85
|
-
Storage.new('DataSpaceMap', :data=>v_stream, :left => 4, :right => 6, :size=>v_stream.size)
|
86
|
-
end
|
87
|
-
|
88
|
-
def allocate_stream(table, stream, size)
|
89
|
-
stream.sector = table.size if stream.respond_to?(:sector)
|
90
|
-
((stream.size / size.to_f).ceil).times { table << table.size }
|
91
|
-
table[table.size-1] = -2
|
92
|
-
end
|
93
|
-
|
94
|
-
def fat_stream
|
95
|
-
@fat_stream ||= create_fat_stream
|
96
|
-
end
|
97
|
-
def create_fat_stream
|
98
|
-
mfs = []
|
99
|
-
@storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index|
|
100
|
-
mfs.concat stream.data
|
101
|
-
mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512
|
102
|
-
end
|
103
|
-
mfs.pack 'c*'
|
104
|
-
end
|
105
|
-
|
106
|
-
def mini_fat_stream
|
107
|
-
@mini_fat_stream ||= create_mini_fat_stream
|
108
|
-
end
|
109
|
-
|
110
|
-
def create_mini_fat_stream
|
111
|
-
mfs = []
|
112
|
-
@storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index|
|
113
|
-
mfs.concat stream.data
|
114
|
-
mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64
|
115
|
-
end
|
116
|
-
@storages[0].size = mfs.size
|
117
|
-
mfs.concat(Array.new(512 - (mfs.size % 512), 0))
|
118
|
-
mfs.pack 'c*'
|
119
|
-
end
|
120
|
-
|
121
|
-
def mini_fat
|
122
|
-
@mini_fat ||= create_mini_fat
|
123
|
-
end
|
124
|
-
|
125
|
-
def create_mini_fat
|
126
|
-
v_mf = []
|
127
|
-
@storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each do |stream|
|
128
|
-
allocate_stream(v_mf, stream, 64)
|
129
|
-
end
|
130
|
-
v_mf.concat Array.new(128 - v_mf.size, -1)
|
131
|
-
v_mf.pack 'l*'
|
132
|
-
end
|
133
|
-
|
134
|
-
def fat
|
135
|
-
@fat ||= create_fat
|
136
|
-
end
|
137
|
-
|
138
|
-
def create_fat
|
139
|
-
v_fat = [-3]
|
140
|
-
# storages four per sector, allocation forces directories to start at sector ID 0
|
141
|
-
allocate_stream(v_fat, @storages, 4)
|
142
|
-
# fat entry for minifat
|
143
|
-
allocate_stream(v_fat, 0, 512)
|
144
|
-
# fat entry for minifat stream
|
145
|
-
@storages[0].sector = v_fat.size
|
146
|
-
allocate_stream(v_fat, mini_fat_stream, 512)
|
147
|
-
# fat entries for encrypted package storage
|
148
|
-
# what to do about DIFAT for larger packages...
|
149
|
-
if @encrypted_package.size > (109 - v_fat.size) * 512
|
150
|
-
raise ArgumentError, "Your package is too big!"
|
151
|
-
end
|
152
|
-
|
153
|
-
if @encrypted_package.size >= MINI_CUTOFF
|
154
|
-
allocate_stream(v_fat, @encrypted_package, 512)
|
155
|
-
end
|
156
|
-
|
157
|
-
v_fat.concat Array.new(128 - v_fat.size, -1) if v_fat.size < 128 #pack in unused sectors
|
158
|
-
v_fat.pack 'l*'
|
159
|
-
end
|
160
|
-
|
161
|
-
def header
|
162
|
-
@header ||= create_header
|
163
|
-
end
|
164
|
-
|
165
|
-
# The serialization for CBF header
|
166
|
-
HEADER_PACKING = "q x16 l s3 x10 l l x4 l*"
|
167
|
-
|
168
|
-
def create_header
|
169
|
-
header = []
|
170
|
-
header << -2226271756974174256 # identifier pack as q
|
171
|
-
header << 196670 # version pack as L
|
172
|
-
header << 65534 # byte order pack as s
|
173
|
-
header << 9 # sector shift
|
174
|
-
header << 6 # mini-sector shift
|
175
|
-
header << (fat.size/512.0).ceil # this is the number of FAT sectors in the file at index 6 pack as L
|
176
|
-
header << header.last # this is the first directory sector, index of 7 pack as L
|
177
|
-
header << MINI_CUTOFF # minfat cutoff pack as L
|
178
|
-
# MiniFat starts after directories
|
179
|
-
header << (fat.size/512.0).ceil + (@storages.size/4.0).ceil # this is the sector id for the first minifat index 10 pack as L
|
180
|
-
header << (mini_fat.size/512.0).ceil # minifat sector count index 11 pack as L
|
181
|
-
header << -2 # the first DIFAT - set to end of chain until we exceed a single FAT pack as L
|
182
|
-
header << 0 # number of DIFAT sectors, unless we go beyond 109 FAT sectors this will always be 0 pack as L
|
183
|
-
header << 0 # first FAT sector defined in the DIFAT pack as L
|
184
|
-
header.concat Array.new(108, -1) # Difat sectors pack as L108
|
185
|
-
end
|
186
|
-
|
187
|
-
def save
|
188
|
-
|
189
|
-
ole = File.open(@file_name, 'w')
|
190
|
-
ole << header.pack(HEADER_PACKING)
|
191
|
-
ole << fat
|
192
|
-
@storages.each { |s| ole << s.to_s }
|
193
|
-
ole << Array.new((512-(ole.pos % 512)), 0).pack('c*')
|
194
|
-
ole << mini_fat
|
195
|
-
ole << mini_fat_stream
|
196
|
-
ole << fat_stream
|
197
|
-
ole.close
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
201
|
-
end
|
File without changes
|
@@ -1,189 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'digest'
|
3
|
-
require 'base64'
|
4
|
-
require 'openssl'
|
5
|
-
|
6
|
-
module Axlsx
|
7
|
-
|
8
|
-
# The MsOffCrypto class implements ECMA-367 encryption based on the MS-OFF-CRYPTO specification
|
9
|
-
class MsOffCrypto
|
10
|
-
|
11
|
-
# Creates a new MsOffCrypto Object
|
12
|
-
# @param [String] file_name the location of the file you want to encrypt
|
13
|
-
# @param [String] pwd the password to use when encrypting the file
|
14
|
-
def initialize(file_name, pwd)
|
15
|
-
self.password = pwd
|
16
|
-
self.file_name = file_name
|
17
|
-
end
|
18
|
-
|
19
|
-
# Generates a new CBF file based on this instance of ms-off-crypto and overwrites the unencrypted file.
|
20
|
-
def save
|
21
|
-
cfb = Cbf.new(self)
|
22
|
-
cfb.save
|
23
|
-
end
|
24
|
-
|
25
|
-
# returns the raw password used in encryption
|
26
|
-
# @return [String]
|
27
|
-
attr_reader :password
|
28
|
-
|
29
|
-
# sets the password to be used for encryption
|
30
|
-
# @param [String] v the password, @default 'password'
|
31
|
-
# @return [String]
|
32
|
-
def password=(v)
|
33
|
-
@password = v || 'password'
|
34
|
-
end
|
35
|
-
|
36
|
-
# retruns the file name of the archive to be encrypted
|
37
|
-
# @return [String]
|
38
|
-
attr_reader :file_name
|
39
|
-
|
40
|
-
# sets the filename
|
41
|
-
# @return [String]
|
42
|
-
def file_name=(v)
|
43
|
-
#TODO verfify that the file specified exists and is an unencrypted xlsx archive
|
44
|
-
@file_name = v
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
# encrypts and returns the package specified by the file name
|
49
|
-
# @return [String]
|
50
|
-
def encrypted_package
|
51
|
-
@encrypted_package ||= encrypt_package(file_name)
|
52
|
-
end
|
53
|
-
|
54
|
-
# returns the encryption info for this instance of ms-off-crypto
|
55
|
-
# @return [String]
|
56
|
-
def encryption_info
|
57
|
-
@encryption_info ||= create_encryption_info
|
58
|
-
end
|
59
|
-
|
60
|
-
# returns a random salt
|
61
|
-
# @return [String]
|
62
|
-
def salt
|
63
|
-
@salt ||= Digest::SHA1.digest(rand(16**16).to_s)
|
64
|
-
end
|
65
|
-
|
66
|
-
# returns a random verifier
|
67
|
-
# @return [String]
|
68
|
-
def verifier
|
69
|
-
@verifier ||= rand(16**16).to_s
|
70
|
-
end
|
71
|
-
|
72
|
-
# returns the verifier encrytped
|
73
|
-
# @return [String]
|
74
|
-
def encrypted_verifier
|
75
|
-
@encrypted_verifier ||= encrypt(verifier)
|
76
|
-
end
|
77
|
-
|
78
|
-
# returns the verifier hash encrypted
|
79
|
-
# @return [String]
|
80
|
-
def encrypted_verifier_hash
|
81
|
-
@encrypted_verifier_hash ||= encrypt(verifier_hash)
|
82
|
-
end
|
83
|
-
|
84
|
-
# returns a verifier hash
|
85
|
-
# @return [String]
|
86
|
-
def verifier_hash
|
87
|
-
@verifier_hash ||= create_verifier_hash
|
88
|
-
end
|
89
|
-
|
90
|
-
# returns an encryption key
|
91
|
-
# @return [String]
|
92
|
-
def key
|
93
|
-
@key ||= create_key
|
94
|
-
end
|
95
|
-
|
96
|
-
# size of unencrypted package? concated with encrypted package
|
97
|
-
def encrypt_package(file_name)
|
98
|
-
package = File.open(file_name, 'r')
|
99
|
-
crypt_pack = encrypt(package.read)
|
100
|
-
[crypt_pack.size].pack('q') + crypt_pack
|
101
|
-
end
|
102
|
-
|
103
|
-
# Generates an encryption info structure
|
104
|
-
# @return [String]
|
105
|
-
def create_encryption_info
|
106
|
-
header = [3, 0, 2, 0] # version
|
107
|
-
# Header flags copy
|
108
|
-
header.concat [0x24, 0, 0, 0] #flags -- VERY UNSURE ABOUT THIS STILL
|
109
|
-
# header.concat [0, 0, 0, 0] #unused
|
110
|
-
header.concat [0xA4, 0, 0, 0] #length
|
111
|
-
# Header
|
112
|
-
header.concat [0x24, 0, 0, 0] #flags again
|
113
|
-
# header.concat [0, 0, 0, 0] #unused again,
|
114
|
-
header.concat [0x0E, 0x66, 0, 0] #alg id
|
115
|
-
header.concat [0x04, 0x80, 0, 0] #alg hash id
|
116
|
-
header.concat [key.size, 0, 0, 0] #key size
|
117
|
-
header.concat [0x18, 0, 0, 0] #provider type
|
118
|
-
# header.concat [0, 0, 0, 0] #reserved 1
|
119
|
-
# header.concat [0, 0, 0, 0] #reserved 2
|
120
|
-
header.concat [0xA0, 0xC7, 0xDC, 0x2, 0, 0, 0, 0]
|
121
|
-
header.concat "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)".bytes.to_a.pack('s*').bytes.to_a
|
122
|
-
header.concat [0, 0] #null terminator
|
123
|
-
|
124
|
-
#Salt Size
|
125
|
-
header.concat [salt.bytes.to_a.size].pack('l').bytes.to_a
|
126
|
-
#Salt
|
127
|
-
header.concat salt.bytes.to_a.pack('c*').bytes.to_a
|
128
|
-
# encryption verifier
|
129
|
-
header.concat encrypted_verifier.bytes.to_a.pack('c*').bytes.to_a
|
130
|
-
|
131
|
-
# verifier hash size -- MUST BE 32 bytes
|
132
|
-
header.concat [verifier_hash.bytes.to_a.size].pack('l').bytes.to_a
|
133
|
-
|
134
|
-
#encryption verifier hash
|
135
|
-
header.concat encrypted_verifier_hash.bytes.to_a.pack('c*').bytes.to_a
|
136
|
-
|
137
|
-
header.flatten!
|
138
|
-
header.pack('c*')
|
139
|
-
end
|
140
|
-
|
141
|
-
# 2.3.3
|
142
|
-
def create_verifier_hash
|
143
|
-
vh = Digest::SHA1.digest(verifier)
|
144
|
-
vh << Array.new(32 - vh.size, 0).join('')
|
145
|
-
end
|
146
|
-
|
147
|
-
# 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)
|
148
|
-
def create_key
|
149
|
-
sha = Digest::SHA1.new() << (salt + @password)
|
150
|
-
(0..49999).each { |i| sha.update(i.to_s+sha.to_s) }
|
151
|
-
key = sha.update(sha.to_s+'0').digest
|
152
|
-
a = key.bytes.each_with_index.map { |item, i| 0x36 ^ item }
|
153
|
-
x1 = Digest::SHA1.digest((a.concat Array.new(64 - key.size, 0x36)).to_s)
|
154
|
-
a = key.bytes.each_with_index.map { |item, i| 0x5C ^ item }
|
155
|
-
x2 = Digest::SHA1.digest( (a.concat Array.new(64 - key.size, 0x5C) ).to_s)
|
156
|
-
x3 = x1 + x2
|
157
|
-
x3.bytes.to_a[(0..31)].pack('c*')
|
158
|
-
end
|
159
|
-
|
160
|
-
# ensures that the a hashed decryption of the encryption verifier matches the decrypted verifier hash.
|
161
|
-
# @return [Boolean]
|
162
|
-
def verify_password
|
163
|
-
v = Digest::SHA1.digest decrypt(@encrypted_verifier)
|
164
|
-
vh = decrypt(@encrypted_verifier_hash)
|
165
|
-
vh[0..15] == v[0..15]
|
166
|
-
end
|
167
|
-
|
168
|
-
# encrypts the data proved
|
169
|
-
# @param [String] data
|
170
|
-
# @return [String] the encrypted data
|
171
|
-
def encrypt(data)
|
172
|
-
aes = OpenSSL::Cipher.new("AES-128-ECB")
|
173
|
-
aes.encrypt
|
174
|
-
aes.key = key
|
175
|
-
aes.update(data) << aes.final
|
176
|
-
end
|
177
|
-
|
178
|
-
# dencrypts the data proved
|
179
|
-
# @param [String] data
|
180
|
-
# @return [String] the dencrypted data
|
181
|
-
def decrypt(data)
|
182
|
-
aes = OpenSSL::Cipher.new("AES-128-ECB")
|
183
|
-
aes.decrypt
|
184
|
-
aes.key = key
|
185
|
-
aes.update(data) << aes.final
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
189
|
-
end
|
File without changes
|
data/lib/axlsx/util/parser.rb~
DELETED
data/lib/axlsx/util/storage.rb~
DELETED
File without changes
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# encoding: UTF--8
|
2
|
-
module Axlsx
|
3
|
-
|
4
|
-
# The Shared String Table class is responsible for managing and serializing common strings in a workbook.
|
5
|
-
# While the ECMA-376 spec allows for both inline and shared strings it seems that at least some applications like Numbers (Mac)
|
6
|
-
# and Google Docs require that the shared string table is populated in order to interoperate properly.
|
7
|
-
# As a developer, you should never need to directly work against this class. Simply set 'use_shared_strings'
|
8
|
-
# on the package or workbook to generate a package that uses the shared strings table instead of inline strings.
|
9
|
-
# @note Serialization performance is affected by using this serialization method so if you do not need interoperability
|
10
|
-
# it is recomended that you use the default inline string method of serialization.
|
11
|
-
class SharedStringsTable
|
12
|
-
|
13
|
-
# The total number of strings in the workbook including duplicates
|
14
|
-
# Empty cells are treated as blank strings
|
15
|
-
# @return [Integer]
|
16
|
-
attr_reader :count
|
17
|
-
|
18
|
-
# The total number of unique strings in the workbook.
|
19
|
-
# @return [Integer]
|
20
|
-
def unique_count
|
21
|
-
@unique_cells.size
|
22
|
-
end
|
23
|
-
|
24
|
-
# An array of unique cells. Multiple attributes of the cell are used in comparison
|
25
|
-
# each of these unique cells is parsed into the shared string table.
|
26
|
-
# @see Cell#sharable
|
27
|
-
attr_reader :unique_cells
|
28
|
-
|
29
|
-
# Creates a new Shared Strings Table agains an array of cells
|
30
|
-
# @param [Array] cells This is an array of all of the cells in the workbook
|
31
|
-
def initialize(cells)
|
32
|
-
cells = cells.reject { |c| c.type != :string }
|
33
|
-
@count = cells.size
|
34
|
-
@unique_cells = []
|
35
|
-
resolve cells
|
36
|
-
end
|
37
|
-
|
38
|
-
# Interate over all of the cells in the array.
|
39
|
-
# if our unique cells array does not contain a sharable cell,
|
40
|
-
# add the cell to our unique cells array and set the ssti attribute on the index of this cell in the shared strings table
|
41
|
-
# if a sharable cell already exists in our unique_cells array, set the ssti attribute of the cell and move on.
|
42
|
-
# @return [Array] unique cells
|
43
|
-
def resolve(cells)
|
44
|
-
cells.each do |cell|
|
45
|
-
index = @unique_cells.index { |item| item.sharable(cell) }
|
46
|
-
if index == nil
|
47
|
-
cell.ssti = @unique_cells.size
|
48
|
-
@unique_cells << cell
|
49
|
-
else
|
50
|
-
cell.ssti = index
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Generate the xml document for the Shared Strings Table
|
56
|
-
# @return [String]
|
57
|
-
def to_xml
|
58
|
-
builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
|
59
|
-
xml.sst(:xmlns => Axlsx::XML_NS, :count => count, :uniqueCount => unique_count) {
|
60
|
-
@unique_cells.each do |cell|
|
61
|
-
xml.si { xml.t cell.value.to_s }
|
62
|
-
end
|
63
|
-
}
|
64
|
-
end
|
65
|
-
builder.to_xml(:save_with => 0)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|