Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
045f728
added lzma static library
lejcik Dec 8, 2023
be00ee5
added zstd static library
lejcik Dec 8, 2023
8857ee1
added support for zstd and xz archives
lejcik Dec 8, 2023
4053035
corrected wrong order of internal files in a .deb archive
lejcik Dec 8, 2023
e52ebce
updated plugin configuration registration
lejcik Dec 8, 2023
859ce65
added porting info for the imported libs
lejcik Dec 8, 2023
cf64eef
tar plugin: updated to version 3.4.0
lejcik Dec 8, 2023
f99ecc2
one more forgotten note
lejcik Dec 8, 2023
60d56e3
reformated with clang-format
lejcik Dec 8, 2023
06e77fb
Merge branch 'main' into plugin-tar-added-zstd-and-lzma-support
lejcik Dec 22, 2023
5a35541
Merge branch 'main' into plugin-tar-added-zstd-and-lzma-support
lejcik Dec 30, 2023
114e951
used vcpkg to handle external dependencies
lejcik Dec 30, 2023
5890216
reverted a few more leftovers
lejcik Dec 30, 2023
a2374fe
updated about-box
lejcik Dec 30, 2023
5343120
reverted salamand.sln
lejcik Jan 2, 2024
c802c64
fixed a warning
lejcik Jan 2, 2024
f0725c7
code improvements from static analysis
lejcik Jan 2, 2024
69410b3
reverted a typo
lejcik Jan 2, 2024
023d3c2
tar project file update
lejcik Jan 2, 2024
b554a2c
got rid of unused function
lejcik Sep 14, 2025
60c2bca
added support for extracting bzip3 archives
lejcik Sep 14, 2025
17c0ae7
tar plugin: updated to version 3.5.0
lejcik Sep 14, 2025
bf09ef7
Merge branch 'main' into plugin-tar-added-zstd-and-lzma-support
lejcik Sep 15, 2025
2f684e6
tar translations
lejcik Feb 22, 2026
0074b15
Merge branch 'main' into plugin-tar-added-zstd-and-lzma-support
lejcik Feb 22, 2026
02284d4
updated vcpkg release hash to version 2026.01.16
lejcik Feb 22, 2026
c335bc6
updated comments translations
lejcik Feb 22, 2026
6b47e0a
updated about message
lejcik Feb 22, 2026
e95e34b
Merge branch 'main' into plugin-tar-added-zstd-and-lzma-support
lejcik May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/plugins/tar/beta.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,10 @@ version 3.30: (2009.02.28) J.Patera
-CDecompressFile::Rewind() did not update StreamPos -> CPIO (e_OldASCII)
archives could not open
-GZIP: files longer than 4 GB before compression complained about premature EOF

version 3.40: (2021.11.12) Vilo
+LZMA: Added support for .XZ archives
+ZSTD: Added support for .ZST archives

version 3.50: (2025.09.14) Vilo
+GZIP3: Added support for .gz3 archives
1 change: 0 additions & 1 deletion src/plugins/tar/bzip/.clang-format

This file was deleted.

226 changes: 112 additions & 114 deletions src/plugins/tar/bzip/bunzip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,146 +2,144 @@

#include "../dlldefs.h"
#include "../fileio.h"
#include "bzlib.h"
#include "bzip.h"

#include "..\tar.rh"
#include "..\tar.rh2"
#include "..\lang\lang.rh"

CBZip::CBZip(const char *filename, HANDLE file, unsigned char *buffer, unsigned long start, unsigned long read, CQuadWord inputSize):
CZippedFile(filename, file, buffer, start, read, inputSize), BZStream(NULL), EndReached(FALSE)
CBZip::CBZip(const char* filename, HANDLE file, unsigned char* buffer, unsigned long start, unsigned long read, CQuadWord inputSize) : CZippedFile(filename, file, buffer, start, read, inputSize)
{
CALL_STACK_MESSAGE2("CBZip::CBZip(%s, , , )", filename);

// if the parent constructor failed, bail out immediately
if (!Ok)
return;
CALL_STACK_MESSAGE2("CBZip::CBZip(%s, , , )", filename);

// this cannot be bzip if we have less than a header...
if (DataEnd - DataStart < 4)
{
Ok = FALSE;
FreeBufAndFile = FALSE;
return;
}
// if the "magic number" is not at the start, it is not a bzip stream
if (DataStart[0] != 'B' || DataStart[1] != 'Z' ||
DataStart[2] != 'h' || DataStart[3] < '0' || DataStart[3] > '9')
{
Ok = FALSE;
FreeBufAndFile = FALSE;
return;
}
// we have bzip, but do not confirm the header yet; the library will verify it again...
// if the parent constructor failed, bail out immediately
if (!Ok)
return;

// prepare the extractor
BZStream = (bz_stream *)malloc(sizeof(bz_stream));
if (BZStream == NULL)
{
Ok = FALSE;
ErrorCode = IDS_ERR_MEMORY;
FreeBufAndFile = FALSE;
return;
}
memset(BZStream, 0, sizeof(bz_stream));
// this cannot be bzip if we have less than a header...
if (DataEnd - DataStart < 4)
{
Ok = FALSE;
FreeBufAndFile = FALSE;
return;
}
// if the "magic number" is not at the start, it is not a bzip stream
if (DataStart[0] != 'B' || DataStart[1] != 'Z' ||
DataStart[2] != 'h' || DataStart[3] < '0' || DataStart[3] > '9')
{
Ok = FALSE;
FreeBufAndFile = FALSE;
return;
}
// we have bzip, but do not confirm the header yet; the library will verify it again...

int ret = BZ2_bzDecompressInit(BZStream, 0, 0);
if (ret != BZ_OK)
{
free(BZStream);
BZStream = NULL;
Ok = FALSE;
FreeBufAndFile = FALSE;
switch (ret)
// prepare the extractor
BZStream = (bz_stream*)malloc(sizeof(bz_stream));
if (BZStream == NULL)
{
case BZ_MEM_ERROR:
Ok = FALSE;
ErrorCode = IDS_ERR_MEMORY;
break;
case BZ_CONFIG_ERROR:
case BZ_PARAM_ERROR:
default:
ErrorCode = IDS_ERR_INTERNAL;
break;
FreeBufAndFile = FALSE;
return;
}
return;
}
// done
}
memset(BZStream, 0, sizeof(bz_stream));

CBZip::~CBZip()
{
CALL_STACK_MESSAGE1("CBZip::~CBZip()");
if (BZStream)
{
int ret = BZ2_bzDecompressEnd(BZStream);
int ret = BZ2_bzDecompressInit(BZStream, 0, 0);
if (ret != BZ_OK)
SalamanderGeneral->ShowMessageBox(LoadStr(IDS_ERR_INTERNAL), LoadStr(IDS_GZERR_TITLE),
MSGBOX_ERROR);
free(BZStream);
}
{
free(BZStream);
BZStream = NULL;
Ok = FALSE;
FreeBufAndFile = FALSE;
switch (ret)
{
case BZ_MEM_ERROR:
ErrorCode = IDS_ERR_MEMORY;
break;
case BZ_CONFIG_ERROR:
case BZ_PARAM_ERROR:
default:
ErrorCode = IDS_ERR_INTERNAL;
break;
}
return;
}
// done
}

BOOL
CBZip::DecompressBlock(unsigned short needed)
CBZip::~CBZip()
{
if (EndReached)
return TRUE;
int ret = BZ_OK;
while (ret != BZ_STREAM_END && ExtrEnd < Window + BUFSIZE)
{
unsigned char *src = DataStart;
// at least one byte must already be buffered
if (DataEnd == DataStart)
src = (unsigned char *)FReadBlock(0);
if (src == NULL)
return FALSE;
if (DataEnd == DataStart)
CALL_STACK_MESSAGE1("CBZip::~CBZip()");
if (BZStream)
{
Ok = FALSE;
ErrorCode = IDS_ERR_EOF;
return FALSE;
int ret = BZ2_bzDecompressEnd(BZStream);
if (ret != BZ_OK)
SalamanderGeneral->ShowMessageBox(LoadStr(IDS_ERR_INTERNAL), LoadStr(IDS_GZERR_TITLE),
MSGBOX_ERROR);
free(BZStream);
}
BZStream->next_in = (char *)DataStart;
BZStream->avail_in = (unsigned int)(DataEnd - DataStart);
BZStream->next_out = (char *)ExtrEnd;
BZStream->avail_out = BUFSIZE - (unsigned int)(ExtrEnd - Window);
ret = BZ2_bzDecompress(BZStream);
if (ret != BZ_OK && ret != BZ_STREAM_END)
}

BOOL CBZip::DecompressBlock(unsigned short needed)
{
if (EndReached)
return TRUE;
int ret = BZ_OK;
while (ret != BZ_STREAM_END && ExtrEnd < Window + BUFSIZE)
{
Ok = FALSE;
switch (ret)
{
case BZ_DATA_ERROR:
case BZ_DATA_ERROR_MAGIC:
ErrorCode = IDS_ERR_CORRUPT;
break;
case BZ_MEM_ERROR:
ErrorCode = IDS_ERR_MEMORY;
break;
case BZ_PARAM_ERROR:
default:
ErrorCode = IDS_ERR_INTERNAL;
break;
}
return FALSE;
unsigned char* src = DataStart;
// at least one byte must already be buffered
if (DataEnd == DataStart)
src = (unsigned char*)FReadBlock(0);
if (src == NULL)
return FALSE;
if (DataEnd == DataStart)
{
Ok = FALSE;
ErrorCode = IDS_ERR_EOF;
return FALSE;
}
BZStream->next_in = (char*)DataStart;
BZStream->avail_in = (unsigned int)GetUnreadInputBufferSize();
BZStream->next_out = (char*)ExtrEnd;
BZStream->avail_out = BUFSIZE - (unsigned int)(ExtrEnd - Window);
ret = BZ2_bzDecompress(BZStream);
if (ret != BZ_OK && ret != BZ_STREAM_END)
{
Ok = FALSE;
switch (ret)
{
case BZ_DATA_ERROR:
case BZ_DATA_ERROR_MAGIC:
ErrorCode = IDS_ERR_CORRUPT;
break;
case BZ_MEM_ERROR:
ErrorCode = IDS_ERR_MEMORY;
break;
case BZ_PARAM_ERROR:
default:
ErrorCode = IDS_ERR_INTERNAL;
break;
}
return FALSE;
}
// commit the consumed input bytes
FReadBlock((unsigned int)(BZStream->next_in - (char*)DataStart));
unsigned short extracted = (unsigned short)((unsigned char*)BZStream->next_out - ExtrEnd);
ExtrEnd = (unsigned char*)BZStream->next_out;
}
// commit the consumed input bytes
FReadBlock((unsigned int)(BZStream->next_in - (char *)DataStart));
unsigned short extracted = (unsigned short)((unsigned char *)BZStream->next_out - ExtrEnd);
ExtrEnd = (unsigned char *)BZStream->next_out;
}
if (ret == BZ_STREAM_END)
EndReached = TRUE;
return TRUE;
if (ret == BZ_STREAM_END)
EndReached = TRUE;
return TRUE;
}

extern "C" {
void bz_internal_error(int errcode);
extern "C"
{
void bz_internal_error(int errcode);
}

void bz_internal_error(int errcode)
{
SalamanderGeneral->ShowMessageBox(LoadStr(IDS_ERR_INTERNAL), LoadStr(IDS_GZERR_TITLE),
MSGBOX_ERROR);
SalamanderGeneral->ShowMessageBox(LoadStr(IDS_ERR_INTERNAL), LoadStr(IDS_GZERR_TITLE),
MSGBOX_ERROR);
}
Loading
Loading