freebsd-ports/archivers/unshield/files/patch-unshield-v2-format
Alexey Dokuchaev 786b1f0d38 - Add support for new InstallShield header format instead of calling abort()
(sic!) on such files.  When header format could not be detected, try to use
  the newest algorithm instead the oldest one; this should make the port more
  "future proof"
- Allow to specify header format via command line (-i <version>) to override
  default detection logic
- Bump port revision and reformat Makefile header while I am here

Obtained from:	SynCE bug tracker at sf.net (ID: 3163039)
Approved by:	maintainer (sunpoet)
2012-01-18 03:00:40 +00:00

212 lines
5.6 KiB
Text

--- lib/component.c.orig
+++ lib/component.c
@@ -40,11 +40,13 @@
case 7:
case 8:
case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ default:
p += 0x6b;
break;
-
- default:
- abort();
}
self->file_group_count = READ_UINT16(p); p += 2;
--- lib/file.c.orig
+++ lib/file.c
@@ -77,6 +77,11 @@
case 7:
case 8:
case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ default:
saved_p = p = header->data +
header->common.cab_descriptor_offset +
header->cab.file_table_offset +
@@ -117,10 +122,6 @@
assert((p - saved_p) == 0x57);
break;
-
- default:
- unshield_error("Unknown major version: %i", header->major_version);
- abort();
}
if (!(fd->flags & FILE_COMPRESSED) &&
@@ -363,6 +364,11 @@
case 7:
case 8:
case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ default:
{
uint8_t six_header[VOLUME_HEADER_SIZE_V6];
uint8_t* p = six_header;
@@ -389,10 +395,6 @@
reader->volume_header.last_file_size_compressed_high = READ_UINT32(p); p += 4;
}
break;
-
- default:
- abort();
- goto exit;
}
#if VERBOSE >= 2
--- lib/libunshield.c.orig
+++ lib/libunshield.c
@@ -205,7 +205,7 @@
/**
Read all header files
*/
-static bool unshield_read_headers(Unshield* unshield)/*{{{*/
+static bool unshield_read_headers(Unshield* unshield, int version)/*{{{*/
{
int i;
bool iterate = true;
@@ -268,8 +268,21 @@
unshield_error("Failed to read common header from header file %i", i);
goto error;
}
-
- header->major_version = (header->common.version >> 12) & 0xf;
+
+ if (version != -1)
+ {
+ header->major_version = version;
+ }
+ else if (header->common.version >> 24 == 1)
+ {
+ header->major_version = (header->common.version >> 12) & 0xf;
+ }
+ else if (header->common.version >> 24 == 2)
+ {
+ header->major_version = (header->common.version & 0xffff);
+ if (header->major_version != 0)
+ header->major_version = header->major_version / 100;
+ }
#if 0
if (header->major_version < 5)
@@ -326,6 +339,11 @@
Unshield* unshield_open(const char* filename)/*{{{*/
{
+ unshield_open_force_version(filename, -1);
+}/*}}}*/
+
+Unshield* unshield_open_force_version(const char* filename, int version)/*{{{*/
+{
Unshield* unshield = NEW1(Unshield);
if (!unshield)
{
@@ -339,7 +357,7 @@
goto error;
}
- if (!unshield_read_headers(unshield))
+ if (!unshield_read_headers(unshield, version))
{
unshield_error("Failed to read header files");
goto error;
--- lib/libunshield.h.orig
+++ lib/libunshield.h
@@ -33,6 +33,7 @@
*/
Unshield* unshield_open(const char* filename);
+Unshield* unshield_open_force_version(const char* filename, int version);
void unshield_close(Unshield* unshield);
/*
--- man/unshield.1.orig
+++ man/unshield.1
@@ -2,7 +2,7 @@
.SH NAME
unshield \- extract CAB files from an InstallShield installer archive
.SH SYNOPSIS
-unshield [\-c COMPONENT] [\-d DIRECTORY] [\-D LEVEL] [\-g GROUP] [\-h] [\-j] [\-L] [\-n] [\-o] [\-O] [\-r] [\-v] [\-V] c|g|l|t|x CABFILE
+unshield [\-c COMPONENT] [\-d DIRECTORY] [\-D LEVEL] [\-g GROUP] [\-h] [\-i VERSION] [\-j] [\-L] [\-n] [\-o] [\-O] [\-r] [\-v] [\-V] c|g|l|t|x CABFILE
.SH DESCRIPTION
Unshield extracts CAB files from InstallShield installers, used to
install software on Microsoft Windows based machines.
@@ -27,6 +27,11 @@
\fB\-h\fR
Show help message
.TP
+\fB\-i\fR VERSION
+Force InstallShield version number (don't autodetect)\n
+.br
+Use this option if you have a very old archive (generated with InstallShield <= 4) and / or the automatic detection fails
+.TP
\fB\-j\fR
Junk paths (do not make directories)
.TP
--- src/unshield.c.orig
+++ src/unshield.c
@@ -58,6 +58,7 @@
static int log_level = UNSHIELD_LOG_LEVEL_LOWEST;
static int exit_status = 0;
static FORMAT format = FORMAT_NEW;
+static int is_version = -1;
static bool make_sure_directory_exists(const char* directory)/*{{{*/
{
@@ -108,7 +109,7 @@
fprintf(stderr,
"Syntax:\n"
"\n"
- "\t%s [-c COMPONENT] [-d DIRECTORY] [-D LEVEL] [-g GROUP] [-GhlOrV] c|g|l|t|x CABFILE\n"
+ "\t%s [-c COMPONENT] [-d DIRECTORY] [-D LEVEL] [-g GROUP] [-i VERSION] [-GhlOrV] c|g|l|t|x CABFILE\n"
"\n"
"Options:\n"
"\t-c COMPONENT Only list/extract this component\n"
@@ -120,6 +121,7 @@
"\t 3 - Errors, warnings and debug messages\n"
"\t-g GROUP Only list/extract this file group\n"
"\t-h Show this help message\n"
+ "\t-i VERSION Force InstallShield version number (don't autodetect)\n"
"\t-j Junk paths (do not make directories)\n"
"\t-L Make file and directory names lowercase\n"
"\t-O Use old compression\n"
@@ -152,7 +154,7 @@
{
int c;
- while ((c = getopt(argc, argv, "c:d:D:g:hjLnoOrV")) != -1)
+ while ((c = getopt(argc, argv, "c:d:D:g:hi:jLnoOrV")) != -1)
{
switch (c)
{
@@ -172,6 +174,10 @@
file_group_name = optarg;
break;
+ case 'i':
+ is_version = atoi(optarg);
+ break;
+
case 'j':
junk_paths = true;
break;
@@ -532,7 +538,7 @@
cabfile = argv[last_optind];
- unshield = unshield_open(cabfile);
+ unshield = unshield_open_force_version(cabfile, is_version);
if (!unshield)
{
fprintf(stderr, "Failed to open %s as an InstallShield Cabinet File\n", cabfile);