rubyzip 3.0.0.alpha → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +51 -0
- data/LICENSE.md +24 -0
- data/README.md +37 -12
- data/Rakefile +1 -1
- data/lib/zip/central_directory.rb +10 -10
- data/lib/zip/constants.rb +4 -0
- data/lib/zip/crypto/decrypted_io.rb +1 -1
- data/lib/zip/crypto/null_encryption.rb +1 -1
- data/lib/zip/crypto/traditional_encryption.rb +3 -3
- data/lib/zip/dos_time.rb +11 -1
- data/lib/zip/entry.rb +74 -47
- data/lib/zip/entry_set.rb +2 -2
- data/lib/zip/errors.rb +24 -3
- data/lib/zip/extra_field/generic.rb +3 -3
- data/lib/zip/extra_field/ntfs.rb +2 -2
- data/lib/zip/extra_field.rb +2 -2
- data/lib/zip/file.rb +38 -15
- data/lib/zip/file_split.rb +1 -7
- data/lib/zip/filesystem/dir.rb +2 -2
- data/lib/zip/filesystem/zip_file_name_mapper.rb +1 -1
- data/lib/zip/filesystem.rb +1 -1
- data/lib/zip/input_stream.rb +13 -18
- data/lib/zip/ioextras/abstract_input_stream.rb +2 -2
- data/lib/zip/ioextras.rb +1 -1
- data/lib/zip/output_stream.rb +8 -8
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +4 -3
- data/rubyzip.gemspec +16 -15
- data/samples/example_filesystem.rb +1 -1
- data/samples/write_simple.rb +1 -1
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2840381c70e4bc8b3fbbfc003e4caf71dab05301621a411b44dc16cd962ca4fb
|
4
|
+
data.tar.gz: 75199ebb2cf53b8a53b930a0ef908773328b4cab2dadef4839fe8194fced289c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1716ef6a03ee08773e4dba640be0fe0e294e4a955b2535d5049dd62c37cc82e161827c2e226c9b93c883f6789c9f275d30e267733038aee59e2c4a80f55193e1
|
7
|
+
data.tar.gz: b4b320f64167dd5f464e45d61d49b2e49619bc356cd2d59f617dfd8ebe7a1be5724e294bab2498186dde951cfd7453a5a4b09f15fd6f88f9872234956182241a
|
data/Changelog.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# 3.0.0 (Next)
|
2
2
|
|
3
|
+
- Fix `File#write_buffer` to always return the given `io`.
|
4
|
+
- Add `Entry#absolute_time?` and `DOSTime#absolute_time?` methods.
|
5
|
+
- Use explicit named parameters for `File` methods.
|
6
|
+
- Ensure that entries can be extracted safely without path traversal. [#540](https://github.com/rubyzip/rubyzip/issues/540)
|
7
|
+
- Enable Zip64 by default.
|
8
|
+
- Rename `GPFBit3Error` to `StreamingError`.
|
9
|
+
- Ensure that `Entry.ftype` is correct via `InputStream`. [#533](https://github.com/rubyzip/rubyzip/issues/533)
|
10
|
+
- Add `Entry#zip64?` as a better way detect Zip64 entries.
|
11
|
+
- Implement `Zip::FileSystem::ZipFsFile#symlink?`.
|
12
|
+
- Remove `File::add_buffer` from the API.
|
13
|
+
- Fix `OutputStream#put_next_entry` to preserve `StreamableStream`s. [#503](https://github.com/rubyzip/rubyzip/issues/503)
|
14
|
+
- Ensure `File.open_buffer` doesn't rewrite unchanged data.
|
15
|
+
- Add `CentralDirectory#count_entries` and `File::count_entries`.
|
16
|
+
- Fix reading unknown extra fields. [#505](https://github.com/rubyzip/rubyzip/issues/505)
|
17
|
+
- Fix reading zip files with max length file comment. [#508](https://github.com/rubyzip/rubyzip/issues/508)
|
18
|
+
- Fix reading zip64 files with max length file comment. [#509](https://github.com/rubyzip/rubyzip/issues/509)
|
3
19
|
- Don't silently alter zip files opened with `Zip::sort_entries`. [#329](https://github.com/rubyzip/rubyzip/issues/329)
|
4
20
|
- Use named parameters for optional arguments in the public API.
|
5
21
|
- Raise an error if entry names exceed 65,535 characters. [#247](https://github.com/rubyzip/rubyzip/issues/247)
|
@@ -23,6 +39,18 @@
|
|
23
39
|
|
24
40
|
Tooling/internal:
|
25
41
|
|
42
|
+
- Update the README with new Ruby version compatability information.
|
43
|
+
- Fix various issues with JRuby tests.
|
44
|
+
- Update gem dependency versions.
|
45
|
+
- Add Ruby 3.4 to the CI.
|
46
|
+
- Fix mispelled variable names in the crypto classes.
|
47
|
+
- Only use the Zip64 CDIR end locator if needed.
|
48
|
+
- Prevent unnecessary Zip64 data being stored.
|
49
|
+
- Abstract marking various things as 'dirty' into `Dirtyable` for reuse.
|
50
|
+
- Properly test `File#mkdir`.
|
51
|
+
- Remove unused private method `File#directory?`.
|
52
|
+
- Expose the `EntrySet` more cleanly through `CentralDirectory`.
|
53
|
+
- `Zip::File` no longer subclasses `Zip::CentralDirectory`.
|
26
54
|
- Configure Coveralls to not report a failure on minor decreases of test coverage. [#491](https://github.com/rubyzip/rubyzip/issues/491)
|
27
55
|
- Extract the file splitting code out into its own module.
|
28
56
|
- Refactor, and tidy up, the `Zip::Filesystem` classes for improved maintainability.
|
@@ -38,6 +66,29 @@ Tooling/internal:
|
|
38
66
|
- Update rubocop again and run it in CI. [#444](https://github.com/rubyzip/rubyzip/pull/444)
|
39
67
|
- Fix a test that was incorrect on big-endian architectures. [#445](https://github.com/rubyzip/rubyzip/pull/445)
|
40
68
|
|
69
|
+
# 2.4.1 (2025-01-05)
|
70
|
+
|
71
|
+
*This is a re-release of version 2.4 with a full version number string. We need to move to version 2.4.1 due to the canonical version number 2.4 now being taken in Rubygems.*
|
72
|
+
|
73
|
+
Tooling:
|
74
|
+
|
75
|
+
- Opt-in for MFA requirement explicitly on 2.4 branch.
|
76
|
+
|
77
|
+
# 2.4 (2025-01-04) - Yanked
|
78
|
+
|
79
|
+
*Yanked due to incorrect version number format (2.4 vs 2.4.0).*
|
80
|
+
|
81
|
+
- Ensure compatibility with `--enable-frozen-string-literal`.
|
82
|
+
- Ensure `File.open_buffer` doesn't rewrite unchanged data. This is a backport of the fix on the 3.x branch.
|
83
|
+
- Enable use of the version 3 calling style (mainly named parameters) wherever possible, while retaining version 2.x compatibility.
|
84
|
+
- Add (switchable) warning messages to methods that are changed or removed in version 3.x.
|
85
|
+
|
86
|
+
Tooling:
|
87
|
+
|
88
|
+
- Switch to using GitHub Actions (from Travis).
|
89
|
+
- Update Rubocop versions and configuration.
|
90
|
+
- Update actions with latest rubies.
|
91
|
+
|
41
92
|
# 2.3.2 (2021-07-05)
|
42
93
|
|
43
94
|
- A "dummy" release to warn about breaking changes coming in version 3.0. This updated version uses the Gem `post_install_message` instead of printing to `STDERR`.
|
data/LICENSE.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
BSD 2-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2002-2025, The Rubyzip Developers
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
CHANGED
@@ -22,9 +22,9 @@ The public API of some classes has been modernized to use named parameters for o
|
|
22
22
|
|
23
23
|
## Requirements
|
24
24
|
|
25
|
-
Version 3.x requires at least Ruby
|
25
|
+
Version 3.x requires at least Ruby 3.0.
|
26
26
|
|
27
|
-
Version 2.x requires at least Ruby 2.4, and is known to work on Ruby 3.
|
27
|
+
Version 2.x requires at least Ruby 2.4, and is known to work on Ruby 3.x.
|
28
28
|
|
29
29
|
It is not recommended to use any versions of Rubyzip earlier than 2.3 due to security issues.
|
30
30
|
|
@@ -205,6 +205,27 @@ Any attempt to move about in a zip file opened with `Zip::InputStream` could res
|
|
205
205
|
|
206
206
|
Rubyzip supports reading/writing zip files with traditional zip encryption (a.k.a. "ZipCrypto"). AES encryption is not yet supported. It can be used with buffer streams, e.g.:
|
207
207
|
|
208
|
+
#### Version 2.x
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
# Writing.
|
212
|
+
enc = Zip::TraditionalEncrypter.new('password')
|
213
|
+
buffer = Zip::OutputStream.write_buffer(::StringIO.new(''), enc) do |output|
|
214
|
+
output.put_next_entry("my_file.txt")
|
215
|
+
output.write my_data
|
216
|
+
end
|
217
|
+
|
218
|
+
# Reading.
|
219
|
+
dec = Zip::TraditionalDecrypter.new('password')
|
220
|
+
Zip::InputStream.open(buffer, 0, dec) do |input|
|
221
|
+
entry = input.get_next_entry
|
222
|
+
puts "Contents of '#{entry.name}':"
|
223
|
+
puts input.read
|
224
|
+
end
|
225
|
+
```
|
226
|
+
|
227
|
+
#### Version 3.x
|
228
|
+
|
208
229
|
```ruby
|
209
230
|
# Writing.
|
210
231
|
enc = Zip::TraditionalEncrypter.new('password')
|
@@ -338,12 +359,14 @@ end
|
|
338
359
|
|
339
360
|
### Zip64 Support
|
340
361
|
|
341
|
-
|
362
|
+
Since version 3.0, Zip64 support is enabled for writing by default. To disable it do this:
|
342
363
|
|
343
364
|
```ruby
|
344
365
|
Zip.write_zip64_support = false
|
345
366
|
```
|
346
367
|
|
368
|
+
Prior to version 3.0, Zip64 support is disabled for writing by default.
|
369
|
+
|
347
370
|
_NOTE_: If Zip64 write support is enabled then any extractor subsequently used may also require Zip64 support to read from the resultant archive.
|
348
371
|
|
349
372
|
### Block Form
|
@@ -365,21 +388,24 @@ Rubyzip is known to run on a number of platforms and under a number of different
|
|
365
388
|
|
366
389
|
### Version 2.3.x
|
367
390
|
|
368
|
-
Rubyzip 2.3 is known to work on MRI 2.4 to 3.
|
391
|
+
Rubyzip 2.3 is known to work on MRI 2.4 to 3.4 on Linux and Mac, and JRuby and Truffleruby on Linux. There are known issues with Windows which have been fixed on the development branch. Please [let us know](https://github.com/rubyzip/rubyzip/pulls) if you know Rubyzip 2.3 works on a platform/Ruby combination not listed here, or [raise an issue](https://github.com/rubyzip/rubyzip/issues) if you see a failure where we think it should work.
|
369
392
|
|
370
393
|
### Next (version 3.0.0)
|
371
394
|
|
372
395
|
Please see the table below for what we think the current situation is. Note: an empty cell means "unknown", not "does not work".
|
373
396
|
|
374
|
-
| OS/Ruby |
|
375
|
-
|
376
|
-
|Ubuntu
|
377
|
-
|Mac OS
|
378
|
-
|Windows
|
379
|
-
|Windows Server 2019| CI | | | | | | | | | | | |
|
397
|
+
| OS/Ruby | 3.0 | 3.1 | 3.2 | 3.3 | 3.4 | Head | JRuby 9.4.9.0 | JRuby Head | Truffleruby 24.1.1 | Truffleruby Head |
|
398
|
+
|---------|-----|-----|-----|-----|-----|------|---------------|------------|--------------------|------------------|
|
399
|
+
|Ubuntu 22.04| CI | CI | CI | CI | CI | ci | CI | ci | CI | ci |
|
400
|
+
|Mac OS 14.7.2| CI | CI | CI | CI | CI | ci | x | | x | |
|
401
|
+
|Windows Server 2022| CI | | | | CI mswin</br>CI ucrt | | | | | |
|
380
402
|
|
381
403
|
Key: `CI` - tested in CI, should work; `ci` - tested in CI, might fail; `x` - known working; `o` - known failing.
|
382
404
|
|
405
|
+
Rubies 3.1+ are also tested separately with YJIT turned on (Ubuntu and Mac OS).
|
406
|
+
|
407
|
+
See [the Actions tab](https://github.com/rubyzip/rubyzip/actions) in GitHub for full details.
|
408
|
+
|
383
409
|
Please [raise a PR](https://github.com/rubyzip/rubyzip/pulls) if you know Rubyzip works on a platform/Ruby combination not listed here, or [raise an issue](https://github.com/rubyzip/rubyzip/issues) if you see a failure where we think it should work.
|
384
410
|
|
385
411
|
## Developing
|
@@ -422,8 +448,7 @@ See https://github.com/rubyzip/rubyzip/graphs/contributors for a comprehensive l
|
|
422
448
|
|
423
449
|
## License
|
424
450
|
|
425
|
-
Rubyzip is distributed under the same license as ruby.
|
426
|
-
http://www.ruby-lang.org/en/LICENSE.txt
|
451
|
+
Rubyzip is distributed under the same license as Ruby. In practice this means you can use it under the terms of the Ruby License or the 2-Clause BSD License. See https://www.ruby-lang.org/en/about/license.txt and LICENSE.md for details.
|
427
452
|
|
428
453
|
## Research notice
|
429
454
|
Please note that this repository is participating in a study into sustainability
|
data/Rakefile
CHANGED
@@ -19,7 +19,7 @@ RDoc::Task.new do |rdoc|
|
|
19
19
|
rdoc.rdoc_files.include('README.md', 'lib/**/*.rb')
|
20
20
|
rdoc.options << '--markup=markdown'
|
21
21
|
rdoc.options << '--tab-width=2'
|
22
|
-
rdoc.options << "-t Rubyzip version #{
|
22
|
+
rdoc.options << "-t Rubyzip version #{Zip::VERSION}"
|
23
23
|
end
|
24
24
|
|
25
25
|
RuboCop::RakeTask.new
|
@@ -28,7 +28,7 @@ module Zip
|
|
28
28
|
|
29
29
|
mark_dirty :<<, :comment=, :delete
|
30
30
|
|
31
|
-
def initialize(entries = EntrySet.new, comment = '')
|
31
|
+
def initialize(entries = EntrySet.new, comment = '') # :nodoc:
|
32
32
|
super(dirty_on_create: false)
|
33
33
|
@entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries)
|
34
34
|
@comment = comment
|
@@ -39,7 +39,7 @@ module Zip
|
|
39
39
|
read_central_directory_entries(io)
|
40
40
|
end
|
41
41
|
|
42
|
-
def write_to_stream(io)
|
42
|
+
def write_to_stream(io) # :nodoc:
|
43
43
|
cdir_offset = io.tell
|
44
44
|
@entry_set.each { |entry| entry.write_c_dir_entry(io) }
|
45
45
|
eocd_offset = io.tell
|
@@ -61,7 +61,7 @@ module Zip
|
|
61
61
|
@size
|
62
62
|
end
|
63
63
|
|
64
|
-
def ==(other)
|
64
|
+
def ==(other) # :nodoc:
|
65
65
|
return false unless other.kind_of?(CentralDirectory)
|
66
66
|
|
67
67
|
@entry_set.entries.sort == other.entries.sort && comment == other.comment
|
@@ -69,7 +69,7 @@ module Zip
|
|
69
69
|
|
70
70
|
private
|
71
71
|
|
72
|
-
def write_e_o_c_d(io, offset, cdir_size)
|
72
|
+
def write_e_o_c_d(io, offset, cdir_size) # :nodoc:
|
73
73
|
tmp = [
|
74
74
|
END_OF_CD_SIG,
|
75
75
|
0, # @numberOfThisDisk
|
@@ -84,7 +84,7 @@ module Zip
|
|
84
84
|
io << @comment
|
85
85
|
end
|
86
86
|
|
87
|
-
def write_64_e_o_c_d(io, offset, cdir_size)
|
87
|
+
def write_64_e_o_c_d(io, offset, cdir_size) # :nodoc:
|
88
88
|
tmp = [
|
89
89
|
ZIP64_END_OF_CD_SIG,
|
90
90
|
44, # size of zip64 end of central directory record (excludes signature and field itself)
|
@@ -110,7 +110,7 @@ module Zip
|
|
110
110
|
io << tmp.pack('VVQ<V')
|
111
111
|
end
|
112
112
|
|
113
|
-
def unpack_64_e_o_c_d(buffer)
|
113
|
+
def unpack_64_e_o_c_d(buffer) # :nodoc:
|
114
114
|
_, # ZIP64_END_OF_CD_SIG. We know we have this at this point.
|
115
115
|
@size_of_zip64_e_o_c_d,
|
116
116
|
@version_made_by,
|
@@ -134,14 +134,14 @@ module Zip
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
def unpack_64_eocd_locator(buffer)
|
137
|
+
def unpack_64_eocd_locator(buffer) # :nodoc:
|
138
138
|
_, # ZIP64_EOCD_LOCATOR_SIG. We know we have this at this point.
|
139
139
|
_, zip64_eocd_offset, = buffer.unpack('VVQ<V')
|
140
140
|
|
141
141
|
zip64_eocd_offset
|
142
142
|
end
|
143
143
|
|
144
|
-
def unpack_e_o_c_d(buffer)
|
144
|
+
def unpack_e_o_c_d(buffer) # :nodoc:
|
145
145
|
_, # END_OF_CD_SIG. We know we have this at this point.
|
146
146
|
num_disk,
|
147
147
|
num_disk_cdir,
|
@@ -165,7 +165,7 @@ module Zip
|
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
|
-
def read_central_directory_entries(io)
|
168
|
+
def read_central_directory_entries(io) # :nodoc:
|
169
169
|
# `StringIO` doesn't raise `EINVAL` if you seek beyond the current end,
|
170
170
|
# so we need to catch that *and* query `io#eof?` here.
|
171
171
|
eof = false
|
@@ -209,7 +209,7 @@ module Zip
|
|
209
209
|
io.read(e_len)
|
210
210
|
end
|
211
211
|
|
212
|
-
def read_eocds(io)
|
212
|
+
def read_eocds(io) # :nodoc:
|
213
213
|
base_location, data = eocd_data(io)
|
214
214
|
|
215
215
|
eocd_location = data.rindex([END_OF_CD_SIG].pack('V'))
|
data/lib/zip/constants.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Zip
|
4
|
+
# :stopdoc:
|
5
|
+
|
4
6
|
RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/i
|
5
7
|
|
6
8
|
CENTRAL_DIRECTORY_ENTRY_SIGNATURE = 0x02014b50
|
@@ -116,4 +118,6 @@ module Zip
|
|
116
118
|
COMPRESSION_METHOD_PPMD => 'PPMd version I, Rev 1',
|
117
119
|
COMPRESSION_METHOD_AES => 'AES encryption'
|
118
120
|
}.freeze
|
121
|
+
|
122
|
+
# :startdoc:
|
119
123
|
end
|
@@ -28,7 +28,7 @@ module Zip
|
|
28
28
|
|
29
29
|
def update_keys(num)
|
30
30
|
@key0 = ~Zlib.crc32(num, ~@key0)
|
31
|
-
@key1 = ((@key1 + (@key0 & 0xff)) * 134_775_813 + 1) & 0xffffffff
|
31
|
+
@key1 = (((@key1 + (@key0 & 0xff)) * 134_775_813) + 1) & 0xffffffff
|
32
32
|
@key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2)
|
33
33
|
end
|
34
34
|
|
@@ -55,8 +55,8 @@ module Zip
|
|
55
55
|
data.unpack('C*').map { |x| encode x }.pack('C*')
|
56
56
|
end
|
57
57
|
|
58
|
-
def data_descriptor(crc32, compressed_size,
|
59
|
-
[0x08074b50, crc32, compressed_size,
|
58
|
+
def data_descriptor(crc32, compressed_size, uncompressed_size)
|
59
|
+
[0x08074b50, crc32, compressed_size, uncompressed_size].pack('VVVV')
|
60
60
|
end
|
61
61
|
|
62
62
|
def reset!
|
data/lib/zip/dos_time.rb
CHANGED
@@ -16,6 +16,14 @@ module Zip
|
|
16
16
|
# bits 5-8 month (1-12)
|
17
17
|
# bits 9-15 year (four digit year minus 1980)
|
18
18
|
|
19
|
+
attr_writer :absolute_time # :nodoc:
|
20
|
+
|
21
|
+
def absolute_time?
|
22
|
+
# If absolute time is not set, we can assume it is an absolute time
|
23
|
+
# because times do have timezone information by default.
|
24
|
+
@absolute_time.nil? ? true : @absolute_time
|
25
|
+
end
|
26
|
+
|
19
27
|
def to_binary_dos_time
|
20
28
|
(sec / 2) +
|
21
29
|
(min << 5) +
|
@@ -53,7 +61,9 @@ module Zip
|
|
53
61
|
month = (0b111100000 & bin_dos_date) >> 5
|
54
62
|
year = ((0b1111111000000000 & bin_dos_date) >> 9) + 1980
|
55
63
|
|
56
|
-
local(year, month, day, hour, minute, second)
|
64
|
+
time = local(year, month, day, hour, minute, second)
|
65
|
+
time.absolute_time = false
|
66
|
+
time
|
57
67
|
end
|
58
68
|
|
59
69
|
if defined? JRUBY_VERSION && Gem::Version.new(JRUBY_VERSION) < '9.2.18.0'
|