Release v1.4.20 with comprehensive audit fixes (140 issues) and expanded test coverage

- Speed calculation: raised minimum elapsed floor to 0.5s preventing unrealistic spikes
- Reconnect: exponential backoff with consecutive counter, clock regression protection
- Download engine: retry byte tracking (itemContributedBytes), mkdir before createWriteStream, content-length validation
- Fire-and-forget promises: all void promises now have .catch() error handlers
- Session recovery: normalize stale active statuses to queued on crash recovery, clear speedBps
- Storage: config backup (.bak) before overwrite, EXDEV cross-device rename fallback with type guard
- IPC security: input validation on all string/array IPC handlers, CSP headers in production
- Main process: clipboard memory limit (50KB), installer timing increased to 800ms
- Debrid: attribute-order-independent meta tag regex for Rapidgator filename extraction
- Constants: named constants for magic numbers (MAX_MANIFEST_FILE_BYTES, MAX_LINK_ARTIFACT_BYTES, etc.)
- Extractor/integrity: use shared constants, document password visibility and TOCTOU limitations
- Tests: 103 tests total (55 new), covering utils, storage, integrity, cleanup, extractor, debrid, update

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe
2026-02-28 06:23:24 +01:00
co-authored by Claude Opus 4.6
parent 556f0672dc
commit 63fd402083
17 changed files with 814 additions and 47 deletions
+2 -1
View File
@@ -2,6 +2,7 @@ import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
import { ParsedHashEntry } from "../shared/types";
import { MAX_MANIFEST_FILE_BYTES } from "./constants";
export function parseHashLine(line: string): ParsedHashEntry | null {
const text = String(line || "").trim();
@@ -53,7 +54,7 @@ export function readHashManifest(packageDir: string): Map<string, ParsedHashEntr
let lines: string[];
try {
const stat = fs.statSync(filePath);
if (stat.size > 5 * 1024 * 1024) {
if (stat.size > MAX_MANIFEST_FILE_BYTES) {
continue;
}
lines = fs.readFileSync(filePath, "utf8").split(/\r?\n/);