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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/extremeunzip.zzaqsu.rb +27 -8
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f085ace2b71050f5964d0b63ce0df0c216963f194e5e30b2e1df4764ed75b9ad
4
- data.tar.gz: e16b2526e07cb4a74419a89ce970c6faa21040ac4a7ed473e8cf205f43d414c5
3
+ metadata.gz: cbe00c05a59f7a202e6eef09269c3fe2323118640acbc27f5a95cb508cf89f79
4
+ data.tar.gz: 20cae2e991e7b0ccdc4cf9d4f6f8b00cf7ea21f93b869e4437fcc014444bf2ec
5
5
  SHA512:
6
- metadata.gz: c16f294337d3776ad8bc56e15548f1eb9e4c1b427fd4277ea2ee27544bd1c2911a92257b5cd4c0a2c8fc2ca21ef36aaa10fb9010688c1ea95a0a9defc89c9ca5
7
- data.tar.gz: 4826eebde7f19e2daa7e2af6d4102fe5c792bb8f83cc6d056fbc05464e1b2f04cc3b55a2885aaca40ddd9735d0dd7a4ff60bf56f4964d09cd46b75ed7ef7713d
6
+ metadata.gz: a61884e664036a6ccf8ae5633aca0639d7b57128d74b54bb08d197fb9cbdb144009cd698f8792d3210c81a49db6610b9b1ab272201a8aabce94deb5423c1f28d
7
+ data.tar.gz: f424c90e022c7ac41ae576a04e272ac74cba55c416c96147f7b61f50e4324427c03b7b5cf92aedd6bdc798242cc09f41fd1e471eb5eec669d8fda54fde6ac5b5
@@ -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
- path = "#{tempBlocksDirPath}/block_#{Time.now.to_i}_#{rand(1000..9999)}.dat"
69
- File.open(path, 'wb') do |f|
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 only
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 "Warning: unexpected decompressed block length detected at block #{index}. Previous length: #{previous_block_length}, current length: #{currentRawData.length}"
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
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: EXtremeZip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2026.11.3
4
+ version: 2026.11.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hxcan Cai