fix: limit broker XLSX extraction
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [Frontend 0.12.0 / Backend 0.11.0 / Shared 0.6.0] - 2026-08-26
|
||||
|
||||
### Added
|
||||
|
||||
- Import VTB Broker XLSX reports with cash movements, trades, and positions in one operation.
|
||||
|
||||
## [Frontend 0.11.3] - 2026-08-26
|
||||
|
||||
### Added
|
||||
|
||||
@@ -20,19 +20,25 @@ function zipFiles(buffer: Buffer): Map<string, Buffer> {
|
||||
if (buffer.readUInt32LE(offset) !== 0x02014b50) throw new Error('Повреждён XLSX-архив');
|
||||
const method = buffer.readUInt16LE(offset + 10);
|
||||
const compressedSize = buffer.readUInt32LE(offset + 20);
|
||||
const uncompressedSize = buffer.readUInt32LE(offset + 24);
|
||||
const nameLength = buffer.readUInt16LE(offset + 28);
|
||||
const extraLength = buffer.readUInt16LE(offset + 30);
|
||||
const commentLength = buffer.readUInt16LE(offset + 32);
|
||||
const localOffset = buffer.readUInt32LE(offset + 42);
|
||||
const name = buffer.subarray(offset + 46, offset + 46 + nameLength).toString('utf8');
|
||||
totalSize += uncompressedSize;
|
||||
if (totalSize > MAX_XLSX_UNCOMPRESSED_BYTES) throw new Error('XLSX-отчёт слишком большой после распаковки');
|
||||
if (buffer.readUInt32LE(localOffset) !== 0x04034b50) throw new Error('Повреждён XLSX-архив');
|
||||
const localNameLength = buffer.readUInt16LE(localOffset + 26);
|
||||
const localExtraLength = buffer.readUInt16LE(localOffset + 28);
|
||||
const data = buffer.subarray(localOffset + 30 + localNameLength + localExtraLength, localOffset + 30 + localNameLength + localExtraLength + compressedSize);
|
||||
files.set(name, method === 0 ? data : method === 8 ? zlib.inflateRawSync(data) : (() => { throw new Error('Неподдерживаемое сжатие XLSX'); })());
|
||||
let content: Buffer;
|
||||
try {
|
||||
content = method === 0 ? data : method === 8 ? zlib.inflateRawSync(data, { maxOutputLength: MAX_XLSX_UNCOMPRESSED_BYTES - totalSize }) : (() => { throw new Error('Неподдерживаемое сжатие XLSX'); })();
|
||||
} catch (error) {
|
||||
if (error instanceof Error && /maxOutputLength|larger than/i.test(error.message)) throw new Error('XLSX-отчёт слишком большой после распаковки');
|
||||
throw error;
|
||||
}
|
||||
totalSize += content.length;
|
||||
if (totalSize > MAX_XLSX_UNCOMPRESSED_BYTES) throw new Error('XLSX-отчёт слишком большой после распаковки');
|
||||
files.set(name, content);
|
||||
offset += 46 + nameLength + extraLength + commentLength;
|
||||
}
|
||||
return files;
|
||||
|
||||
Reference in New Issue
Block a user