1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

gpgtar: Improve error messages.

* tools/gpgtar.h (struct tarinfo_s): New.
* tools/gpgtar.c (cmd, skip_crypto, files_from, null_names): Move
global vars more to the top.
(set_cmd): Rename 'cmd' to 'c'.
* tools/gpgtar-list.c (parse_header): Add arg 'info' and improve error
messages.
(read_header): Add arg 'info' and update counter.
(skip_data): Ditto.
(gpgtar_list): Pass info object to read functions.
(gpgtar_read_header): Add arg 'info'.
* tools/gpgtar-extract.c (gpgtar_extract): add arg 'info' and pass on.
(extract_regular): Add arg 'info' and update counter.
--

This now prints the block number of a header with error.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-03-06 17:46:40 +01:00
parent 05eff1f662
commit 72feb8fa82
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 89 additions and 43 deletions

View file

@ -77,12 +77,15 @@ parse_xoctal (const void *data, size_t length, const char *filename)
static tar_header_t
parse_header (const void *record, const char *filename)
parse_header (const void *record, const char *filename, tarinfo_t info)
{
const struct ustar_raw_header *raw = record;
size_t n, namelen, prefixlen;
tar_header_t header;
int use_prefix;
int anyerror = 0;
info->headerblock = info->nblocks - 1;
use_prefix = (!memcmp (raw->magic, "ustar", 5)
&& (raw->magic[5] == ' ' || !raw->magic[5]));
@ -91,27 +94,31 @@ parse_header (const void *record, const char *filename)
for (namelen=0; namelen < sizeof raw->name && raw->name[namelen]; namelen++)
;
if (namelen == sizeof raw->name)
log_info ("%s: warning: name not terminated by a nul byte\n", filename);
{
log_info ("%s: warning: name not terminated by a nul\n", filename);
anyerror = 1;
}
for (n=namelen+1; n < sizeof raw->name; n++)
if (raw->name[n])
{
log_info ("%s: warning: garbage after name\n", filename);
anyerror = 1;
break;
}
if (use_prefix && raw->prefix[0])
{
for (prefixlen=0; (prefixlen < sizeof raw->prefix
&& raw->prefix[prefixlen]); prefixlen++)
;
if (prefixlen == sizeof raw->prefix)
log_info ("%s: warning: prefix not terminated by a nul byte\n",
filename);
log_info ("%s: warning: prefix not terminated by a nul (block %llu)\n",
filename, info->headerblock);
for (n=prefixlen+1; n < sizeof raw->prefix; n++)
if (raw->prefix[n])
{
log_info ("%s: warning: garbage after prefix\n", filename);
anyerror = 1;
break;
}
}
@ -156,25 +163,32 @@ parse_header (const void *record, const char *filename)
default: header->typeflag = TF_UNKNOWN; break;
}
/* Compute the number of data records following this header. */
if (header->typeflag == TF_REGULAR || header->typeflag == TF_UNKNOWN)
header->nrecords = (header->size + RECORDSIZE-1)/RECORDSIZE;
else
header->nrecords = 0;
if (anyerror)
{
log_info ("%s: header block %llu is corrupt"
" (size=%llu type=%d nrec=%llu)\n",
filename, info->headerblock,
header->size, header->typeflag, header->nrecords);
/* log_printhex (record, RECORDSIZE, " "); */
}
return header;
}
/* Read the next block, assming it is a tar header. Returns a header
/* Read the next block, assuming it is a tar header. Returns a header
object on success in R_HEADER, or an error. If the stream is
consumed, R_HEADER is set to NULL. In case of an error an error
message has been printed. */
static gpg_error_t
read_header (estream_t stream, tar_header_t *r_header)
read_header (estream_t stream, tarinfo_t info, tar_header_t *r_header)
{
gpg_error_t err;
char record[RECORDSIZE];
@ -183,6 +197,7 @@ read_header (estream_t stream, tar_header_t *r_header)
err = read_record (stream, record);
if (err)
return err;
info->nblocks++;
for (i=0; i < RECORDSIZE && !record[i]; i++)
;
@ -193,6 +208,7 @@ read_header (estream_t stream, tar_header_t *r_header)
err = read_record (stream, record);
if (err)
return err;
info->nblocks++;
for (i=0; i < RECORDSIZE && !record[i]; i++)
;
@ -207,7 +223,7 @@ read_header (estream_t stream, tar_header_t *r_header)
}
}
*r_header = parse_header (record, es_fname_get (stream));
*r_header = parse_header (record, es_fname_get (stream), info);
return *r_header ? 0 : gpg_error_from_syserror ();
}
@ -215,7 +231,7 @@ read_header (estream_t stream, tar_header_t *r_header)
/* Skip the data records according to HEADER. Prints an error message
on error and return -1. */
static int
skip_data (estream_t stream, tar_header_t header)
skip_data (estream_t stream, tarinfo_t info, tar_header_t header)
{
char record[RECORDSIZE];
unsigned long long n;
@ -224,6 +240,7 @@ skip_data (estream_t stream, tar_header_t header)
{
if (read_record (stream, record))
return -1;
info->nblocks++;
}
return 0;
@ -278,6 +295,10 @@ gpgtar_list (const char *filename, int decrypt)
estream_t stream;
estream_t cipher_stream = NULL;
tar_header_t header = NULL;
struct tarinfo_s tarinfo_buffer;
tarinfo_t tarinfo = &tarinfo_buffer;
memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer);
if (filename)
{
@ -339,13 +360,13 @@ gpgtar_list (const char *filename, int decrypt)
for (;;)
{
err = read_header (stream, &header);
err = read_header (stream, tarinfo, &header);
if (err || header == NULL)
goto leave;
print_header (header, es_stdout);
if (skip_data (stream, header))
if (skip_data (stream, tarinfo, header))
goto leave;
xfree (header);
header = NULL;
@ -362,9 +383,9 @@ gpgtar_list (const char *filename, int decrypt)
}
gpg_error_t
gpgtar_read_header (estream_t stream, tar_header_t *r_header)
gpgtar_read_header (estream_t stream, tarinfo_t info, tar_header_t *r_header)
{
return read_header (stream, r_header);
return read_header (stream, info, r_header);
}
void