xlsxrb 0.1.8 → 0.1.9
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/CHANGELOG.md +15 -2
- data/README.md +50 -13
- data/Rakefile +20 -2
- data/docs/DEVELOPMENT.md +11 -3
- data/docs/QUALITY_ASSURANCE.md +3 -4
- data/docs/SPEC_SOURCES.md +7 -1
- data/docs/wasm/ruby.wasm +0 -0
- data/lib/xlsxrb/elements/row.rb +2 -2
- data/lib/xlsxrb/elements/workbook.rb +1 -1
- data/lib/xlsxrb/elements/worksheet.rb +4 -4
- data/lib/xlsxrb/ooxml/cfb.rb +490 -0
- data/lib/xlsxrb/ooxml/crypto/agile.rb +285 -0
- data/lib/xlsxrb/ooxml/crypto/standard.rb +152 -0
- data/lib/xlsxrb/ooxml/crypto.rb +60 -0
- data/lib/xlsxrb/stream_row.rb +2 -2
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb.rb +129 -38
- data/sig/generated/xlsxrb/elements/worksheet.rbs +8 -5
- data/sig/generated/xlsxrb/ooxml/cfb.rbs +121 -0
- data/sig/generated/xlsxrb/ooxml/crypto/agile.rbs +46 -0
- data/sig/generated/xlsxrb/ooxml/crypto/standard.rbs +28 -0
- data/sig/generated/xlsxrb/ooxml/crypto.rbs +17 -0
- data/sig/generated/xlsxrb/stream_row.rbs +4 -2
- data/sig/generated/xlsxrb.rbs +40 -18
- data/vendor/sdk_runner/Program.cs +3 -1
- metadata +9 -1
data/lib/xlsxrb.rb
CHANGED
|
@@ -22,6 +22,7 @@ require_relative "xlsxrb/version"
|
|
|
22
22
|
require_relative "xlsxrb/ooxml/zip_generator"
|
|
23
23
|
require_relative "xlsxrb/ooxml/writer"
|
|
24
24
|
require_relative "xlsxrb/ooxml/reader"
|
|
25
|
+
require_relative "xlsxrb/ooxml/crypto"
|
|
25
26
|
require_relative "xlsxrb/ooxml"
|
|
26
27
|
require_relative "xlsxrb/elements"
|
|
27
28
|
require_relative "xlsxrb/stream_row"
|
|
@@ -42,6 +43,9 @@ module Xlsxrb
|
|
|
42
43
|
class ParseError < Error; end
|
|
43
44
|
class ValidationError < Error; end
|
|
44
45
|
class ZipError < Error; end
|
|
46
|
+
class EncryptedFileError < Error; end
|
|
47
|
+
class InvalidPasswordError < EncryptedFileError; end
|
|
48
|
+
class DecryptionError < EncryptedFileError; end
|
|
45
49
|
|
|
46
50
|
TRACER = OpenTelemetry.tracer_provider.tracer("xlsxrb", Xlsxrb::VERSION)
|
|
47
51
|
|
|
@@ -385,14 +389,48 @@ module Xlsxrb
|
|
|
385
389
|
# puts doc_sheet["A1"].value # coordinate random access
|
|
386
390
|
#
|
|
387
391
|
# @param source [String, IO] File path, binary content string (starting with PK..), or IO object.
|
|
392
|
+
# @param password [String, nil] Optional password to decrypt password-protected XLSX files.
|
|
388
393
|
# @yield [sheet] Yields each streaming sheet.
|
|
389
394
|
# @yieldparam sheet [StreamSheet] The streaming worksheet object.
|
|
390
395
|
# @return [Elements::Workbook, void] Returns Elements::Workbook when no block is given.
|
|
391
396
|
# @api public
|
|
392
|
-
#: (
|
|
393
|
-
#: (
|
|
394
|
-
def self.read(source, &)
|
|
395
|
-
|
|
397
|
+
#: (untyped source, ?password: String?) { (StreamSheet) -> void } -> void
|
|
398
|
+
#: (untyped source, ?password: String?) -> Elements::Workbook
|
|
399
|
+
def self.read(source, password: nil, &)
|
|
400
|
+
if source.is_a?(String)
|
|
401
|
+
if source.start_with?("PK\x03\x04") || source.include?("\x00") || Ooxml::Cfb::Reader.cfb?(source)
|
|
402
|
+
if Ooxml::Cfb::Reader.cfb?(source)
|
|
403
|
+
decrypted_zip = Ooxml::Crypto.decrypt(source, password)
|
|
404
|
+
source = StringIO.new(decrypted_zip)
|
|
405
|
+
else
|
|
406
|
+
source = StringIO.new(source)
|
|
407
|
+
end
|
|
408
|
+
elsif File.file?(source)
|
|
409
|
+
first_bytes = begin
|
|
410
|
+
File.binread(source, 8)
|
|
411
|
+
rescue StandardError
|
|
412
|
+
nil
|
|
413
|
+
end
|
|
414
|
+
if Ooxml::Cfb::Reader.cfb?(first_bytes)
|
|
415
|
+
encrypted_data = File.binread(source)
|
|
416
|
+
decrypted_zip = Ooxml::Crypto.decrypt(encrypted_data, password)
|
|
417
|
+
source = StringIO.new(decrypted_zip)
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
elsif source.respond_to?(:read) && source.respond_to?(:pos) && source.respond_to?(:seek)
|
|
421
|
+
begin
|
|
422
|
+
cur_pos = source.pos
|
|
423
|
+
first_bytes = source.read(8)
|
|
424
|
+
source.seek(cur_pos)
|
|
425
|
+
if Ooxml::Cfb::Reader.cfb?(first_bytes)
|
|
426
|
+
full_data = source.read
|
|
427
|
+
decrypted_zip = Ooxml::Crypto.decrypt(full_data, password)
|
|
428
|
+
source = StringIO.new(decrypted_zip)
|
|
429
|
+
end
|
|
430
|
+
rescue StandardError
|
|
431
|
+
# Fall through to standard reader if seeking fails
|
|
432
|
+
end
|
|
433
|
+
end
|
|
396
434
|
|
|
397
435
|
attributes = source.is_a?(String) ? { "filepath" => source } : {}
|
|
398
436
|
Xlsxrb.in_span("Xlsxrb.read", attributes: attributes) do
|
|
@@ -431,23 +469,26 @@ module Xlsxrb
|
|
|
431
469
|
|
|
432
470
|
# Writes an XLSX file or IO stream (streaming or in-memory), or returns a binary string.
|
|
433
471
|
#
|
|
434
|
-
# @overload write(target, strict_excel_mode: true, &block)
|
|
472
|
+
# @overload write(target, password: nil, strict_excel_mode: true, &block)
|
|
435
473
|
# Streaming write: yields a StreamWriter context for high-speed, zero-allocation XLSX generation.
|
|
436
474
|
# @param target [String, IO] Destination file path or writable IO object.
|
|
475
|
+
# @param password [String, nil] Optional password to encrypt the generated XLSX file.
|
|
437
476
|
# @param strict_excel_mode [Boolean] Whether to enforce Excel specifications.
|
|
438
477
|
# @yield [stream_writer]
|
|
439
478
|
# @yieldparam stream_writer [Xlsxrb::StreamWriter]
|
|
440
479
|
# @return [void]
|
|
441
480
|
#
|
|
442
|
-
# @overload write(workbook)
|
|
481
|
+
# @overload write(workbook, password: nil)
|
|
443
482
|
# In-memory write: exports the workbook to an in-memory binary String.
|
|
444
483
|
# @param workbook [Elements::Workbook] The workbook to write.
|
|
484
|
+
# @param password [String, nil] Optional password to encrypt the binary string.
|
|
445
485
|
# @return [String] Binary data representing the XLSX file.
|
|
446
486
|
#
|
|
447
|
-
# @overload write(target, workbook)
|
|
487
|
+
# @overload write(target, workbook, password: nil)
|
|
448
488
|
# In-memory write: writes the workbook to a file path or IO stream.
|
|
449
489
|
# @param target [String, IO] Destination file path or writable IO object.
|
|
450
490
|
# @param workbook [Elements::Workbook] The workbook to write.
|
|
491
|
+
# @param password [String, nil] Optional password to encrypt the output file.
|
|
451
492
|
# @return [void]
|
|
452
493
|
#
|
|
453
494
|
# @example Streaming write to file
|
|
@@ -455,6 +496,11 @@ module Xlsxrb
|
|
|
455
496
|
# writer.sheet("Sheet1") { |s| s.row(["Hello", "World"]) }
|
|
456
497
|
# end
|
|
457
498
|
#
|
|
499
|
+
# @example Password-protected streaming write
|
|
500
|
+
# Xlsxrb.write("protected.xlsx", password: "secret_password") do |writer|
|
|
501
|
+
# writer.sheet("Confidential") { |s| s.row(["Private Data", 100]) }
|
|
502
|
+
# end
|
|
503
|
+
#
|
|
458
504
|
# @example In-memory export to binary string
|
|
459
505
|
# binary_data = Xlsxrb.write(workbook)
|
|
460
506
|
#
|
|
@@ -462,22 +508,41 @@ module Xlsxrb
|
|
|
462
508
|
# Xlsxrb.write("output.xlsx", workbook)
|
|
463
509
|
#
|
|
464
510
|
# @api public
|
|
465
|
-
#: (Elements::Workbook workbook) -> String
|
|
466
|
-
#: (
|
|
467
|
-
#: (
|
|
468
|
-
def self.write(target_or_workbook, workbook_or_nil = nil, strict_excel_mode: true, &block)
|
|
511
|
+
#: (Elements::Workbook workbook, ?password: String?, ?encryption_mode: Symbol) -> String
|
|
512
|
+
#: (untyped target, Elements::Workbook | untyped workbook, ?password: String?, ?encryption_mode: Symbol) -> void
|
|
513
|
+
#: (untyped target_or_workbook, ?Elements::Workbook | untyped workbook_or_nil, ?password: String?, ?encryption_mode: Symbol, ?strict_excel_mode: bool) ?{ (StreamWriter) -> void } -> untyped
|
|
514
|
+
def self.write(target_or_workbook, workbook_or_nil = nil, password: nil, encryption_mode: :standard, strict_excel_mode: true, &block)
|
|
469
515
|
if block_given?
|
|
470
516
|
target = target_or_workbook
|
|
471
517
|
raise Error, "target is required" if target.nil?
|
|
472
518
|
|
|
473
519
|
attributes = target.is_a?(String) ? { "filepath" => target } : {}
|
|
474
520
|
return Xlsxrb.in_span("Xlsxrb.write", attributes: attributes) do
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
stream_writer.
|
|
479
|
-
|
|
480
|
-
|
|
521
|
+
if password && !password.empty?
|
|
522
|
+
buf = StringIO.new
|
|
523
|
+
buf.binmode
|
|
524
|
+
stream_writer = StreamWriter.new(buf, strict_excel_mode: strict_excel_mode)
|
|
525
|
+
begin
|
|
526
|
+
yield stream_writer
|
|
527
|
+
stream_writer.close
|
|
528
|
+
plain_bytes = buf.string.b
|
|
529
|
+
encrypted_bytes = Ooxml::Crypto.encrypt(plain_bytes, password, mode: encryption_mode)
|
|
530
|
+
if target.is_a?(String)
|
|
531
|
+
File.binwrite(target, encrypted_bytes)
|
|
532
|
+
elsif target.respond_to?(:write)
|
|
533
|
+
target.write(encrypted_bytes)
|
|
534
|
+
end
|
|
535
|
+
ensure
|
|
536
|
+
stream_writer.cleanup!
|
|
537
|
+
end
|
|
538
|
+
else
|
|
539
|
+
stream_writer = StreamWriter.new(target, strict_excel_mode: strict_excel_mode)
|
|
540
|
+
begin
|
|
541
|
+
yield stream_writer
|
|
542
|
+
stream_writer.close
|
|
543
|
+
ensure
|
|
544
|
+
stream_writer.cleanup!
|
|
545
|
+
end
|
|
481
546
|
end
|
|
482
547
|
end
|
|
483
548
|
end
|
|
@@ -488,7 +553,7 @@ module Xlsxrb
|
|
|
488
553
|
|
|
489
554
|
io = StringIO.new
|
|
490
555
|
io.binmode
|
|
491
|
-
write(io, wb)
|
|
556
|
+
write(io, wb, password: password, encryption_mode: encryption_mode)
|
|
492
557
|
return io.string.b
|
|
493
558
|
end
|
|
494
559
|
|
|
@@ -532,19 +597,44 @@ module Xlsxrb
|
|
|
532
597
|
|
|
533
598
|
# Extract workbook-level facade metadata
|
|
534
599
|
wb_facade = workbook.unmapped_data[:facade] || {}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
600
|
+
|
|
601
|
+
if password && !password.empty?
|
|
602
|
+
buf = StringIO.new
|
|
603
|
+
buf.binmode
|
|
604
|
+
Ooxml::WorkbookWriter.write(
|
|
605
|
+
buf,
|
|
606
|
+
sheets: sheet_data,
|
|
607
|
+
shared_strings: sst,
|
|
608
|
+
shared_strings_index: sst_index,
|
|
609
|
+
styles: workbook.styles,
|
|
610
|
+
defined_names: wb_facade[:defined_names],
|
|
611
|
+
core_properties: wb_facade[:core_properties],
|
|
612
|
+
app_properties: wb_facade[:app_properties],
|
|
613
|
+
custom_properties: wb_facade[:custom_properties],
|
|
614
|
+
workbook_protection: wb_facade[:workbook_protection],
|
|
615
|
+
workbook_properties: wb_facade[:workbook_properties]
|
|
616
|
+
)
|
|
617
|
+
encrypted_bytes = Ooxml::Crypto.encrypt(buf.string.b, password, mode: encryption_mode)
|
|
618
|
+
if target.is_a?(String)
|
|
619
|
+
File.binwrite(target, encrypted_bytes)
|
|
620
|
+
elsif target.respond_to?(:write)
|
|
621
|
+
target.write(encrypted_bytes)
|
|
622
|
+
end
|
|
623
|
+
else
|
|
624
|
+
Ooxml::WorkbookWriter.write(
|
|
625
|
+
target,
|
|
626
|
+
sheets: sheet_data,
|
|
627
|
+
shared_strings: sst,
|
|
628
|
+
shared_strings_index: sst_index,
|
|
629
|
+
styles: workbook.styles,
|
|
630
|
+
defined_names: wb_facade[:defined_names],
|
|
631
|
+
core_properties: wb_facade[:core_properties],
|
|
632
|
+
app_properties: wb_facade[:app_properties],
|
|
633
|
+
custom_properties: wb_facade[:custom_properties],
|
|
634
|
+
workbook_protection: wb_facade[:workbook_protection],
|
|
635
|
+
workbook_properties: wb_facade[:workbook_properties]
|
|
636
|
+
)
|
|
637
|
+
end
|
|
548
638
|
end
|
|
549
639
|
end
|
|
550
640
|
|
|
@@ -563,22 +653,23 @@ module Xlsxrb
|
|
|
563
653
|
#
|
|
564
654
|
# @param source [String, IO] The source file path or IO object.
|
|
565
655
|
# @param target [String, IO, nil] The target file path or IO object. If nil, overwrites source.
|
|
656
|
+
# @param password [String, nil] Optional password for reading and writing protected files.
|
|
566
657
|
# @yield [workbook] Yields the parsed workbook.
|
|
567
658
|
# @yieldparam workbook [Elements::Workbook] The parsed workbook.
|
|
568
659
|
# @yieldreturn [Elements::Workbook] The modified workbook.
|
|
569
660
|
# @return [void]
|
|
570
661
|
# @api public
|
|
571
|
-
#: (untyped source, ?untyped target) ?{ (Elements::Workbook) -> untyped } -> void
|
|
572
|
-
def self.modify(source, target = nil)
|
|
662
|
+
#: (untyped source, ?untyped target, ?password: String?) ?{ (Elements::Workbook) -> untyped } -> void
|
|
663
|
+
def self.modify(source, target = nil, password: nil)
|
|
573
664
|
raise Error, "source is required" if source.nil?
|
|
574
665
|
raise Error, "block is required" unless block_given?
|
|
575
666
|
|
|
576
|
-
workbook = read(source).load
|
|
667
|
+
workbook = read(source, password: password).load
|
|
577
668
|
result_workbook = yield workbook
|
|
578
669
|
result_workbook = workbook unless result_workbook.is_a?(Elements::Workbook)
|
|
579
670
|
|
|
580
671
|
write_target = target || source
|
|
581
|
-
write(write_target, result_workbook)
|
|
672
|
+
write(write_target, result_workbook, password: password)
|
|
582
673
|
end
|
|
583
674
|
|
|
584
675
|
# Represents a sheet being streamed sequentially from an XLSX file.
|
|
@@ -627,7 +718,7 @@ module Xlsxrb
|
|
|
627
718
|
# @return [Enumerator, void]
|
|
628
719
|
# @api public
|
|
629
720
|
#: () { (StreamRow | Elements::Row) -> void } -> void
|
|
630
|
-
#:
|
|
721
|
+
#: () -> Enumerator[StreamRow | Elements::Row, void]
|
|
631
722
|
def each_row
|
|
632
723
|
return enum_for(:each_row) unless block_given?
|
|
633
724
|
|
|
@@ -647,7 +738,7 @@ module Xlsxrb
|
|
|
647
738
|
# @return [Enumerator, void]
|
|
648
739
|
# @api public
|
|
649
740
|
#: () { (Elements::Cell) -> void } -> void
|
|
650
|
-
#:
|
|
741
|
+
#: () -> Enumerator[Elements::Cell, void]
|
|
651
742
|
def each_cell(&)
|
|
652
743
|
return enum_for(:each_cell) unless block_given?
|
|
653
744
|
|
|
@@ -663,7 +754,7 @@ module Xlsxrb
|
|
|
663
754
|
# @return [Enumerator, void]
|
|
664
755
|
# @api public
|
|
665
756
|
#: () { (StreamRow | Elements::Row) -> void } -> void
|
|
666
|
-
#:
|
|
757
|
+
#: () -> Enumerator[StreamRow | Elements::Row, void]
|
|
667
758
|
def each(&)
|
|
668
759
|
each_row(&)
|
|
669
760
|
end
|
|
@@ -31,8 +31,8 @@ module Xlsxrb
|
|
|
31
31
|
# @param charts [Array<Hash>] Charts in the sheet.
|
|
32
32
|
# @param unmapped_data [Hash] Additional metadata for round-tripping.
|
|
33
33
|
# @param errors [Array<String>, nil] Validation errors.
|
|
34
|
-
# : (name: String
|
|
35
|
-
def initialize: (name: String
|
|
34
|
+
# : (name: String?, ?rows: Array[Elements::Row], ?columns: Array[Elements::Column], ?charts: Array[Hash[Symbol, untyped]], ?unmapped_data: Hash[untyped, untyped], ?errors: Array[String]?) -> void
|
|
35
|
+
def initialize: (name: String?, ?rows: Array[Elements::Row], ?columns: Array[Elements::Column], ?charts: Array[Hash[Symbol, untyped]], ?unmapped_data: Hash[untyped, untyped], ?errors: Array[String]?) -> void
|
|
36
36
|
|
|
37
37
|
# Iterate over rows in the worksheet.
|
|
38
38
|
#
|
|
@@ -46,8 +46,9 @@ module Xlsxrb
|
|
|
46
46
|
# @return [Enumerator, void]
|
|
47
47
|
# @api public
|
|
48
48
|
# : () { (Elements::Row) -> void } -> void
|
|
49
|
-
# :
|
|
49
|
+
# : () -> Enumerator[Elements::Row, void]
|
|
50
50
|
def each: () { (Elements::Row) -> void } -> void
|
|
51
|
+
| () -> Enumerator[Elements::Row, void]
|
|
51
52
|
|
|
52
53
|
# Iterate over rows in the worksheet.
|
|
53
54
|
#
|
|
@@ -61,8 +62,9 @@ module Xlsxrb
|
|
|
61
62
|
# @return [Enumerator, void]
|
|
62
63
|
# @api public
|
|
63
64
|
# : () { (Elements::Row) -> void } -> void
|
|
64
|
-
# :
|
|
65
|
+
# : () -> Enumerator[Elements::Row, void]
|
|
65
66
|
def each_row: () { (Elements::Row) -> void } -> void
|
|
67
|
+
| () -> Enumerator[Elements::Row, void]
|
|
66
68
|
|
|
67
69
|
# Iterate over all cells across rows.
|
|
68
70
|
#
|
|
@@ -71,8 +73,9 @@ module Xlsxrb
|
|
|
71
73
|
# @return [Enumerator, void]
|
|
72
74
|
# @api public
|
|
73
75
|
# : () { (Elements::Cell) -> void } -> void
|
|
74
|
-
# :
|
|
76
|
+
# : () -> Enumerator[Elements::Cell, void]
|
|
75
77
|
def each_cell: () { (Elements::Cell) -> void } -> void
|
|
78
|
+
| () -> Enumerator[Elements::Cell, void]
|
|
76
79
|
|
|
77
80
|
# Returns whether the worksheet is valid according to OOXML specifications.
|
|
78
81
|
#
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Generated from lib/xlsxrb/ooxml/cfb.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Xlsxrb
|
|
4
|
+
module Ooxml
|
|
5
|
+
# Pure-Ruby Compound File Binary (CFB / OLE Structured Storage) implementation for [MS-CFB] / [MS-OFFCRYPTO].
|
|
6
|
+
module Cfb
|
|
7
|
+
MAGIC: untyped
|
|
8
|
+
|
|
9
|
+
FREESECT: ::Integer
|
|
10
|
+
|
|
11
|
+
ENDOFCHAIN: ::Integer
|
|
12
|
+
|
|
13
|
+
FATSECT: ::Integer
|
|
14
|
+
|
|
15
|
+
DIFATSECT: ::Integer
|
|
16
|
+
|
|
17
|
+
NOSTREAM: ::Integer
|
|
18
|
+
|
|
19
|
+
OBJ_UNKNOWN: ::Integer
|
|
20
|
+
|
|
21
|
+
OBJ_STORAGE: ::Integer
|
|
22
|
+
|
|
23
|
+
OBJ_STREAM: ::Integer
|
|
24
|
+
|
|
25
|
+
OBJ_ROOT: ::Integer
|
|
26
|
+
|
|
27
|
+
MINI_STREAM_CUTOFF: ::Integer
|
|
28
|
+
|
|
29
|
+
SECTOR_SIZE: ::Integer
|
|
30
|
+
|
|
31
|
+
MINI_SECTOR_SIZE: ::Integer
|
|
32
|
+
|
|
33
|
+
# Represents a directory entry in a Compound File.
|
|
34
|
+
class DirEntry
|
|
35
|
+
attr_accessor name: untyped
|
|
36
|
+
|
|
37
|
+
attr_accessor type: untyped
|
|
38
|
+
|
|
39
|
+
attr_accessor color: untyped
|
|
40
|
+
|
|
41
|
+
attr_accessor left_sibling_id: untyped
|
|
42
|
+
|
|
43
|
+
attr_accessor right_sibling_id: untyped
|
|
44
|
+
|
|
45
|
+
attr_accessor child_id: untyped
|
|
46
|
+
|
|
47
|
+
attr_accessor clsid: untyped
|
|
48
|
+
|
|
49
|
+
attr_accessor state_flags: untyped
|
|
50
|
+
|
|
51
|
+
attr_accessor created_time: untyped
|
|
52
|
+
|
|
53
|
+
attr_accessor modified_time: untyped
|
|
54
|
+
|
|
55
|
+
attr_accessor start_sector: untyped
|
|
56
|
+
|
|
57
|
+
attr_accessor size: untyped
|
|
58
|
+
|
|
59
|
+
attr_accessor entry_id: untyped
|
|
60
|
+
|
|
61
|
+
def initialize: (?name: untyped, ?type: untyped, ?start_sector: untyped, ?size: untyped) -> untyped
|
|
62
|
+
|
|
63
|
+
def stream?: () -> untyped
|
|
64
|
+
|
|
65
|
+
def root?: () -> untyped
|
|
66
|
+
|
|
67
|
+
def storage?: () -> untyped
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Reads streams from a Compound File Binary buffer.
|
|
71
|
+
class Reader
|
|
72
|
+
attr_reader entries: untyped
|
|
73
|
+
|
|
74
|
+
def self.cfb?: (untyped data) -> untyped
|
|
75
|
+
|
|
76
|
+
def initialize: (untyped data) -> untyped
|
|
77
|
+
|
|
78
|
+
def stream_names: () -> untyped
|
|
79
|
+
|
|
80
|
+
def read_stream: (untyped name) -> untyped
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def parse_header: () -> untyped
|
|
85
|
+
|
|
86
|
+
def sector_offset: (untyped sector_id) -> untyped
|
|
87
|
+
|
|
88
|
+
def read_sector: (untyped sector_id) -> untyped
|
|
89
|
+
|
|
90
|
+
def build_fat: () -> untyped
|
|
91
|
+
|
|
92
|
+
def load_difat_and_fat: () -> untyped
|
|
93
|
+
|
|
94
|
+
def parse_directory: () -> untyped
|
|
95
|
+
|
|
96
|
+
def load_mini_stream: () -> untyped
|
|
97
|
+
|
|
98
|
+
def read_regular_stream_data: (untyped start_sector, untyped total_size) -> untyped
|
|
99
|
+
|
|
100
|
+
def read_mini_stream_data: (untyped start_mini_sector, untyped total_size) -> untyped
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Writes named streams into a Compound File Binary (v3, 512-byte sectors) format with Mini Stream support.
|
|
104
|
+
class Writer
|
|
105
|
+
def self.write: (untyped streams) -> untyped
|
|
106
|
+
|
|
107
|
+
def initialize: (untyped streams) -> untyped
|
|
108
|
+
|
|
109
|
+
def build: () -> untyped
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def serialize_dir_entry: (untyped entry) -> untyped
|
|
114
|
+
|
|
115
|
+
def insert_entry_to_tree: (untyped entries, untyped root_node, untyped new_node) -> untyped
|
|
116
|
+
|
|
117
|
+
def compare_entry_names: (untyped a_name, untyped b_name) -> untyped
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Generated from lib/xlsxrb/ooxml/crypto/agile.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Xlsxrb
|
|
4
|
+
module Ooxml
|
|
5
|
+
module Crypto
|
|
6
|
+
# Implements Microsoft Office Agile Encryption specified in [MS-OFFCRYPTO] Section 2.3.4.
|
|
7
|
+
class Agile
|
|
8
|
+
BLOCK_KEY_VERIFIER_INPUT: untyped
|
|
9
|
+
|
|
10
|
+
BLOCK_KEY_VERIFIER_VALUE: untyped
|
|
11
|
+
|
|
12
|
+
BLOCK_KEY_KEY: untyped
|
|
13
|
+
|
|
14
|
+
BLOCK_KEY_INTEGRITY_KEY: untyped
|
|
15
|
+
|
|
16
|
+
BLOCK_KEY_INTEGRITY_VALUE: untyped
|
|
17
|
+
|
|
18
|
+
SEGMENT_SIZE: ::Integer
|
|
19
|
+
|
|
20
|
+
# Decrypts an encrypted package given the EncryptionInfo stream data and EncryptedPackage stream data.
|
|
21
|
+
def self.decrypt: (untyped encryption_info_bytes, untyped encrypted_package_bytes, untyped password) -> untyped
|
|
22
|
+
|
|
23
|
+
# Encrypts a plain zip payload with the given password into EncryptionInfo and EncryptedPackage streams.
|
|
24
|
+
def self.encrypt: (untyped plain_bytes, untyped password) -> untyped
|
|
25
|
+
|
|
26
|
+
private def self.parse_encryption_info: (untyped bytes) -> untyped
|
|
27
|
+
|
|
28
|
+
private def self.digest_for: (untyped name) -> untyped
|
|
29
|
+
|
|
30
|
+
private def self.cipher_name_for: (untyped algo, untyped key_bits) -> untyped
|
|
31
|
+
|
|
32
|
+
private def self.derive_h_final: (untyped digest, untyped password, untyped salt, untyped spin_count) -> untyped
|
|
33
|
+
|
|
34
|
+
private def self.derive_key: (untyped digest, untyped h_final, untyped block_key, untyped key_bytes) -> untyped
|
|
35
|
+
|
|
36
|
+
private def self.aes_decrypt: (untyped cipher_name, untyped key, untyped init_vector, untyped data) -> untyped
|
|
37
|
+
|
|
38
|
+
private def self.aes_encrypt: (untyped cipher_name, untyped key, untyped init_vector, untyped data) -> untyped
|
|
39
|
+
|
|
40
|
+
private def self.aes_decrypt_block: (untyped cipher_name, untyped key, untyped init_vector, untyped data) -> untyped
|
|
41
|
+
|
|
42
|
+
private def self.aes_encrypt_block: (untyped cipher_name, untyped key, untyped init_vector, untyped data) -> untyped
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Generated from lib/xlsxrb/ooxml/crypto/standard.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Xlsxrb
|
|
4
|
+
module Ooxml
|
|
5
|
+
module Crypto
|
|
6
|
+
# Implements Microsoft Office Standard Encryption specified in [MS-OFFCRYPTO] Section 2.3.6.
|
|
7
|
+
class Standard
|
|
8
|
+
CSP_NAME: untyped
|
|
9
|
+
|
|
10
|
+
ITERATION_COUNT: ::Integer
|
|
11
|
+
|
|
12
|
+
# Decrypts a Standard-encrypted package.
|
|
13
|
+
def self.decrypt: (untyped encryption_info_bytes, untyped encrypted_package_bytes, untyped password) -> untyped
|
|
14
|
+
|
|
15
|
+
# Encrypts plain zip data into Standard Encryption streams.
|
|
16
|
+
def self.encrypt: (untyped plain_bytes, untyped password) -> untyped
|
|
17
|
+
|
|
18
|
+
private def self.parse_encryption_info: (untyped bytes) -> untyped
|
|
19
|
+
|
|
20
|
+
private def self.derive_key: (untyped password, untyped salt, ?untyped block_num) -> untyped
|
|
21
|
+
|
|
22
|
+
private def self.aes_ecb_encrypt: (untyped key, untyped data) -> untyped
|
|
23
|
+
|
|
24
|
+
private def self.aes_ecb_decrypt: (untyped key, untyped data) -> untyped
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Generated from lib/xlsxrb/ooxml/crypto.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module Xlsxrb
|
|
4
|
+
module Ooxml
|
|
5
|
+
# High-level encryption and decryption facade for [MS-OFFCRYPTO] Excel document protection.
|
|
6
|
+
module Crypto
|
|
7
|
+
# Checks if the binary data is an encrypted Compound File Binary package.
|
|
8
|
+
def self.encrypted?: (untyped data) -> untyped
|
|
9
|
+
|
|
10
|
+
# Decrypts an encrypted XLSX (CFB) package with the given password.
|
|
11
|
+
def self.decrypt: (untyped cfb_data, untyped password) -> untyped
|
|
12
|
+
|
|
13
|
+
# Encrypts a plain ZIP payload with the given password into an encrypted CFB package.
|
|
14
|
+
def self.encrypt: (untyped plain_zip_data, untyped password, ?mode: untyped) -> untyped
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -44,8 +44,9 @@ module Xlsxrb
|
|
|
44
44
|
# @return [Enumerator, void]
|
|
45
45
|
# @api public
|
|
46
46
|
# : () { (Elements::Cell) -> void } -> void
|
|
47
|
-
# :
|
|
47
|
+
# : () -> Enumerator[Elements::Cell, void]
|
|
48
48
|
def each_cell: () { (Elements::Cell) -> void } -> void
|
|
49
|
+
| () -> Enumerator[Elements::Cell, void]
|
|
49
50
|
|
|
50
51
|
# Iterate over cells in this streaming row.
|
|
51
52
|
#
|
|
@@ -54,8 +55,9 @@ module Xlsxrb
|
|
|
54
55
|
# @return [Enumerator, void]
|
|
55
56
|
# @api public
|
|
56
57
|
# : () { (Elements::Cell) -> void } -> void
|
|
57
|
-
# :
|
|
58
|
+
# : () -> Enumerator[Elements::Cell, void]
|
|
58
59
|
def each: () { (Elements::Cell) -> void } -> void
|
|
60
|
+
| () -> Enumerator[Elements::Cell, void]
|
|
59
61
|
|
|
60
62
|
# Returns all cells as an Array. Cached on first access.
|
|
61
63
|
#
|