EXtremeZip 2026.11.3 → 2026.11.4
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/lib/extremeunzip.zzaqsu.rb +27 -8
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cbe00c05a59f7a202e6eef09269c3fe2323118640acbc27f5a95cb508cf89f79
|
|
4
|
+
data.tar.gz: 20cae2e991e7b0ccdc4cf9d4f6f8b00cf7ea21f93b869e4437fcc014444bf2ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a61884e664036a6ccf8ae5633aca0639d7b57128d74b54bb08d197fb9cbdb144009cd698f8792d3210c81a49db6610b9b1ab272201a8aabce94deb5423c1f28d
|
|
7
|
+
data.tar.gz: f424c90e022c7ac41ae576a04e272ac74cba55c416c96147f7b61f50e4324427c03b7b5cf92aedd6bdc798242cc09f41fd1e471eb5eec669d8fda54fde6ac5b5
|
data/lib/extremeunzip.zzaqsu.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'victoriafresh'
|
|
|
2
2
|
require 'cbor'
|
|
3
3
|
require 'lzma'
|
|
4
4
|
require 'get_process_mem'
|
|
5
|
+
require 'digest'
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def checkMemoryUsage(lineNumber)
|
|
@@ -56,8 +57,6 @@ class ExtremeUnZip
|
|
|
56
57
|
|
|
57
58
|
if expected_block_length.nil?
|
|
58
59
|
expected_block_length = length
|
|
59
|
-
elsif length != expected_block_length
|
|
60
|
-
puts "Warning: unexpected block length detected. Expected: #{expected_block_length}, got: #{length}"
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
# ✅ Read directly from file on disk
|
|
@@ -65,14 +64,19 @@ class ExtremeUnZip
|
|
|
65
64
|
currentBlock = currentBlockFile.read(length)
|
|
66
65
|
|
|
67
66
|
# ✅ Write to persistent temp file (not Tempfile)
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
# 文件名必须全局唯一:用 pid + 块序号。
|
|
68
|
+
# 原先用 Time.now.to_i(秒级) + rand(1000..9999),同一秒内写入多个块时会碰撞:
|
|
69
|
+
# 后写的块用 'wb' 截断覆盖先写的块(数据静默损坏),
|
|
70
|
+
# 且前一个块的 ensure 会删掉同名文件,导致后一个块读时 No such file or directory。
|
|
71
|
+
# 现改用 pid + 块序号,并用 'wx'排他创建(已存在直接报错,绝不覆盖)。
|
|
72
|
+
path = "#{tempBlocksDirPath}/block_#{Process.pid}_#{index}.dat"
|
|
73
|
+
File.open(path, 'wx') do |f|
|
|
70
74
|
f.binmode
|
|
71
75
|
f.write(currentBlock)
|
|
72
76
|
end
|
|
73
77
|
|
|
74
|
-
# Store path
|
|
75
|
-
compressedVfsDataList << path
|
|
78
|
+
# Store path and its digest, so the read-back phase can detect any corruption.
|
|
79
|
+
compressedVfsDataList << [path, Digest::SHA256.hexdigest(currentBlock)]
|
|
76
80
|
|
|
77
81
|
# ✅ Immediately release currentBlock
|
|
78
82
|
currentBlock = nil
|
|
@@ -118,18 +122,30 @@ class ExtremeUnZip
|
|
|
118
122
|
File.open(dataFileName, 'wb') do |dataFile|
|
|
119
123
|
begin
|
|
120
124
|
# Process one block at a time
|
|
121
|
-
compressedVfsDataList.each_with_index do |temp_path, index|
|
|
125
|
+
compressedVfsDataList.each_with_index do |(temp_path, expected_digest), index|
|
|
122
126
|
puts("data block counter: #{dataBlockCounter}")
|
|
123
127
|
checkMemoryUsage(30)
|
|
124
128
|
|
|
125
129
|
currentRawData = nil
|
|
126
130
|
|
|
127
131
|
begin
|
|
132
|
+
compressedData = nil
|
|
128
133
|
File.open(temp_path, 'rb') do |f|
|
|
129
134
|
compressedData = f.read
|
|
130
135
|
currentRawData = LZMA.decompress(compressedData)
|
|
131
136
|
end
|
|
132
137
|
|
|
138
|
+
# Verify the temp block still holds the exact bytes we wrote.
|
|
139
|
+
# Guards against silent corruption (e.g. filename collisions).
|
|
140
|
+
if expected_digest
|
|
141
|
+
actual_digest = Digest::SHA256.hexdigest(compressedData)
|
|
142
|
+
if actual_digest != expected_digest
|
|
143
|
+
raise "Block content corrupted at block #{index}: #{temp_path}. " \
|
|
144
|
+
"expected #{expected_digest}, got #{actual_digest}. " \
|
|
145
|
+
"The temp block was overwritten or mixed up."
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
133
149
|
if previous_block_length.nil?
|
|
134
150
|
previous_block_length = currentRawData.length
|
|
135
151
|
expected_block_length ||= previous_block_length
|
|
@@ -138,12 +154,15 @@ class ExtremeUnZip
|
|
|
138
154
|
puts "Warning: decompressed block length is zero at block #{index}. Generating fake data of expected length."
|
|
139
155
|
currentRawData = "\x00" * expected_block_length
|
|
140
156
|
else
|
|
141
|
-
puts "
|
|
157
|
+
puts "Note: block #{index} has a different length (#{currentRawData.length}, expected #{previous_block_length}). This is normal for the last block."
|
|
142
158
|
end
|
|
143
159
|
end
|
|
144
160
|
|
|
145
161
|
dataFile.syswrite(currentRawData)
|
|
146
162
|
puts "After writing block #{index}, raw data file size: #{File.size(dataFileName)}"
|
|
163
|
+
rescue Errno::ENOENT => e
|
|
164
|
+
raise "Block file missing at block #{index}: #{temp_path} (#{e.message}). " \
|
|
165
|
+
"The exz file may be corrupted, or the temp block was removed unexpectedly."
|
|
147
166
|
rescue RuntimeError => e
|
|
148
167
|
puts "Warning: the exz file may be incomplete at block #{index}. Error: #{e.message}"
|
|
149
168
|
|