1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-14 21:47:19 +02:00

Merge branch 'master' into gniibe/t6275

This commit is contained in:
NIIBE Yutaka 2023-01-24 15:29:51 +09:00
commit 8e2207ecb9
No known key found for this signature in database
GPG key ID: 640114AF89DE6054
104 changed files with 2231 additions and 1412 deletions

View file

@ -83,7 +83,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert (! initialized);
/* We accept both OpenPGP-style and gcrypt-style algorithm ids.
* Assert that they are compatible. */
* Assert that they are compatible. At some places gcrypt ids are
* used which can't be encoded in an OpenPGP algo octet; we also
* assert this. */
log_assert ((int) GCRY_PK_RSA == (int) PUBKEY_ALGO_RSA);
log_assert ((int) GCRY_PK_RSA_E == (int) PUBKEY_ALGO_RSA_E);
log_assert ((int) GCRY_PK_RSA_S == (int) PUBKEY_ALGO_RSA_S);
@ -91,6 +93,9 @@ gnupg_initialize_compliance (int gnupg_module_name)
log_assert ((int) GCRY_PK_DSA == (int) PUBKEY_ALGO_DSA);
log_assert ((int) GCRY_PK_ECC == (int) PUBKEY_ALGO_ECDH);
log_assert ((int) GCRY_PK_ELG == (int) PUBKEY_ALGO_ELGAMAL);
log_assert ((int) GCRY_PK_ECDSA > 255);
log_assert ((int) GCRY_PK_ECDH > 255);
log_assert ((int) GCRY_PK_EDDSA > 255);
log_assert ((int) GCRY_CIPHER_NONE == (int) CIPHER_ALGO_NONE);
log_assert ((int) GCRY_CIPHER_IDEA == (int) CIPHER_ALGO_IDEA);
log_assert ((int) GCRY_CIPHER_3DES == (int) CIPHER_ALGO_3DES);
@ -159,6 +164,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA:
case GCRY_PK_ECDSA:
case GCRY_PK_ECDH:
case GCRY_PK_EDDSA:
algotype = is_ecc;
break;
@ -211,7 +219,9 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
result = (curvename
&& (algo == PUBKEY_ALGO_ECDH
|| algo == PUBKEY_ALGO_ECDSA)
|| algo == PUBKEY_ALGO_ECDSA
|| algo == GCRY_PK_ECDH
|| algo == GCRY_PK_ECDSA)
&& (!strcmp (curvename, "brainpoolP256r1")
|| !strcmp (curvename, "brainpoolP384r1")
|| !strcmp (curvename, "brainpoolP512r1")));
@ -292,6 +302,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break;
case PUBKEY_ALGO_ECDH:
case GCRY_PK_ECDH:
if (use == PK_USE_DECRYPTION)
result = 1;
else if (use == PK_USE_ENCRYPTION)
@ -316,6 +327,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
break;
case PUBKEY_ALGO_ECDSA:
case GCRY_PK_ECDSA:
if (use == PK_USE_VERIFICATION)
result = 1;
else
@ -341,6 +353,10 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
case PUBKEY_ALGO_EDDSA:
if (use == PK_USE_VERIFICATION)
result = 1;
else /* We may not create such signatures in de-vs mode. */
result = 0;
break;
default:

View file

@ -45,7 +45,7 @@ enum gnupg_compliance_mode
enum pk_use_case
{
PK_USE_ENCRYPTION, PK_USE_DECRYPTION,
PK_USE_SIGNING, PK_USE_VERIFICATION,
PK_USE_SIGNING, PK_USE_VERIFICATION
};
/* Flags to distinguish public key algorithm variants. */

View file

@ -1110,6 +1110,20 @@ spawn_detached (gnupg_process_t process,
return 0;
}
void
gnupg_spawn_helper (struct spawn_cb_arg *sca)
{
int *user_except = sca->arg;
#ifdef HAVE_W32_SYSTEM
if (user_except[0] == -1)
sca->ask_inherit = 0;
else
sca->ask_inherit = 1;
#else
sca->except_fds = user_except;
#endif
}
gpg_err_code_t
gnupg_process_spawn (const char *pgmname, const char *argv1[],
unsigned int flags,

View file

@ -249,6 +249,9 @@ struct spawn_cb_arg {
#define GNUPG_PROCESS_STREAM_NONBLOCK (1 << 16)
/* Spawn helper. */
void gnupg_spawn_helper (struct spawn_cb_arg *sca);
/* Spawn PGMNAME. */
gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[],
unsigned int flags,

View file

@ -305,20 +305,6 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink)
}
static void
setup_close_all (struct spawn_cb_arg *sca)
{
int *user_except = sca->arg;
#ifdef HAVE_W32_SYSTEM
if (user_except[0] == -1)
sca->ask_inherit = 0;
else
sca->ask_inherit = 1;
#else
sca->except_fds = user_except;
#endif
}
/* Run the program PGMNAME with the command line arguments given in
* the NULL terminates array ARGV. If INPUT is not NULL it will be
* fed to stdin of the process. stderr is logged using log_info and
@ -433,7 +419,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[],
: GNUPG_PROCESS_STDIN_NULL)
| GNUPG_PROCESS_STDOUT_PIPE
| GNUPG_PROCESS_STDERR_PIPE),
setup_close_all, exceptclose, &proc);
gnupg_spawn_helper, exceptclose, &proc);
gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK,
input? &infp : NULL, &outfp, &errfp);
if (extrapipe[0] != -1)

View file

@ -30,6 +30,9 @@
#include <config.h>
#ifdef HAVE_W32_SYSTEM
# if _WIN32_WINNT < 0x0600
# define _WIN32_WINNT 0x0600 /* Required for SetProcessDEPPolicy. */
# endif
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# endif
@ -213,7 +216,21 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
log_set_socket_dir_cb (gnupg_socketdir);
#if HAVE_W32_SYSTEM
/* For Standard Windows we use our own parser for the command line
/* Make sure that Data Execution Prevention is enabled. */
if (GetSystemDEPPolicy () >= 2)
{
DWORD flags;
BOOL perm;
if (!GetProcessDEPPolicy (GetCurrentProcess (), &flags, &perm))
log_info ("error getting DEP policy: %s\n",
w32_strerror (GetLastError()));
else if (!(flags & PROCESS_DEP_ENABLE)
&& !SetProcessDEPPolicy (PROCESS_DEP_ENABLE))
log_info ("Warning: Enabling DEP failed: %s (%d,%d)\n",
w32_strerror (GetLastError ()), (int)flags, (int)perm);
}
/* On Windows we use our own parser for the command line
* so that we can return an array of utf-8 encoded strings. */
prepare_w32_commandline (argcp, argvp);
#else

View file

@ -1,7 +1,7 @@
/* iobuf.c - File Handling for OpenPGP.
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
* 2009, 2010, 2011 Free Software Foundation, Inc.
* Copyright (C) 2015 g10 Code GmbH
* Copyright (C) 2015, 2023 g10 Code GmbH
*
* This file is part of GnuPG.
*
@ -27,6 +27,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
*/
#include <config.h>
@ -35,7 +36,6 @@
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -95,6 +95,9 @@ typedef struct
int eof_seen;
int delayed_rc;
int print_only_name; /* Flags indicating that fname is not a real file. */
char peeked[32]; /* Read ahead buffer. */
byte npeeked; /* Number of bytes valid in peeked. */
byte upeeked; /* Number of bytes used from peeked. */
char fname[1]; /* Name of the file. */
} file_filter_ctx_t;
@ -207,7 +210,7 @@ fd_cache_invalidate (const char *fname)
close_cache_t cc;
int rc = 0;
assert (fname);
log_assert (fname);
if (DBG_IOBUF)
log_debug ("fd_cache_invalidate (%s)\n", fname);
@ -370,7 +373,7 @@ fd_cache_close (const char *fname, gnupg_fd_t fp)
{
close_cache_t cc;
assert (fp);
log_assert (fp);
if (!fname || !*fname)
{
#ifdef HAVE_W32_SYSTEM
@ -411,7 +414,7 @@ fd_cache_open (const char *fname, const char *mode)
{
close_cache_t cc;
assert (fname);
log_assert (fname);
for (cc = close_cache; cc; cc = cc->next)
{
if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
@ -458,7 +461,16 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
if (control == IOBUFCTRL_UNDERFLOW)
{
log_assert (size); /* We need a buffer. */
if (a->eof_seen)
if (a->npeeked > a->upeeked)
{
nbytes = a->npeeked - a->upeeked;
if (nbytes > size)
nbytes = size;
memcpy (buf, a->peeked + a->upeeked, nbytes);
a->upeeked += nbytes;
*ret_len = nbytes;
}
else if (a->eof_seen)
{
rc = -1;
*ret_len = 0;
@ -596,6 +608,73 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
a->delayed_rc = 0;
a->keep_open = 0;
a->no_cache = 0;
a->npeeked = 0;
a->upeeked = 0;
}
else if (control == IOBUFCTRL_PEEK)
{
/* Peek on the input. */
#ifdef HAVE_W32_SYSTEM
unsigned long nread;
nbytes = 0;
if (!ReadFile (f, a->peeked, sizeof a->peeked, &nread, NULL))
{
int ec = (int) GetLastError ();
if (ec != ERROR_BROKEN_PIPE)
{
rc = gpg_error_from_errno (ec);
log_error ("%s: read error: ec=%d\n", a->fname, ec);
}
a->npeeked = 0;
}
else if (!nread)
{
a->eof_seen = 1;
a->npeeked = 0;
}
else
{
a->npeeked = nread;
}
#else /* Unix */
int n;
peek_more:
do
{
n = read (f, a->peeked + a->npeeked, sizeof a->peeked - a->npeeked);
}
while (n == -1 && errno == EINTR);
if (n > 0)
{
a->npeeked += n;
if (a->npeeked < sizeof a->peeked)
goto peek_more;
}
else if (!n) /* eof */
{
if (a->npeeked)
a->delayed_rc = -1;
else
a->eof_seen = 1;
}
else /* error */
{
rc = gpg_error_from_syserror ();
if (gpg_err_code (rc) != GPG_ERR_EPIPE)
log_error ("%s: read error: %s\n", a->fname, gpg_strerror (rc));
if (a->npeeked)
a->delayed_rc = rc;
}
#endif /* Unix */
size = a->npeeked < size? a->npeeked : size;
memcpy (buf, a->peeked, size);
*ret_len = size;
rc = 0; /* Return success - the user needs to check ret_len. */
}
else if (control == IOBUFCTRL_DESC)
{
@ -632,7 +711,7 @@ file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
if (control == IOBUFCTRL_UNDERFLOW)
{
assert (size); /* We need a buffer. */
log_assert (size); /* We need a buffer. */
if (a->eof_seen)
{
rc = -1;
@ -751,7 +830,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
if (control == IOBUFCTRL_UNDERFLOW)
{
assert (size); /* need a buffer */
log_assert (size); /* need a buffer */
if (a->eof_seen)
{
rc = -1;
@ -846,7 +925,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
size_t n = 0;
p = buf;
assert (size); /* need a buffer */
log_assert (size); /* need a buffer */
if (a->eof) /* don't read any further */
rc = -1;
while (!rc && size)
@ -974,7 +1053,7 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
{ /* the complicated openpgp scheme */
size_t blen, n, nbytes = size + a->buflen;
assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
log_assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
if (nbytes < OP_MIN_PARTIAL_CHUNK)
{
/* not enough to write a partial block out; so we store it */
@ -998,12 +1077,12 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
blen /= 2;
c--;
/* write the partial length header */
assert (c <= 0x1f); /*;-) */
log_assert (c <= 0x1f); /*;-) */
c |= 0xe0;
iobuf_put (chain, c);
if ((n = a->buflen))
{ /* write stuff from the buffer */
assert (n == OP_MIN_PARTIAL_CHUNK);
log_assert (n == OP_MIN_PARTIAL_CHUNK);
if (iobuf_write (chain, a->buffer, n))
rc = gpg_error_from_syserror ();
a->buflen = 0;
@ -1020,8 +1099,8 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
/* store the rest in the buffer */
if (!rc && nbytes)
{
assert (!a->buflen);
assert (nbytes < OP_MIN_PARTIAL_CHUNK);
log_assert (!a->buflen);
log_assert (nbytes < OP_MIN_PARTIAL_CHUNK);
if (!a->buffer)
a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
memcpy (a->buffer, p, nbytes);
@ -1183,8 +1262,8 @@ iobuf_alloc (int use, size_t bufsize)
iobuf_t a;
static int number = 0;
assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
|| use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
log_assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
|| use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
if (bufsize == 0)
{
log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
@ -1304,7 +1383,7 @@ iobuf_temp_with_content (const char *buffer, size_t length)
int i;
a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
assert (length == a->d.size);
log_assert (length == a->d.size);
/* memcpy (a->d.buf, buffer, length); */
for (i=0; i < length; i++)
a->d.buf[i] = buffer[i];
@ -1335,7 +1414,7 @@ do_open (const char *fname, int special_filenames,
int fd;
byte desc[MAX_IOBUF_DESC];
assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
log_assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
if (special_filenames
/* NULL or '-'. */
@ -1576,6 +1655,25 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
return fd_cache_synchronize (ptrval);
}
}
else if (cmd == IOBUF_IOCTL_PEEK)
{
/* Peek at a justed opened file. Use this only directly after a
* file has been opened for reading. Don't use it after you did
* a seek. This works only if just file filter has been
* pushed. Expects a buffer wit size INTVAL at PTRVAL and returns
* the number of bytes put into the buffer. */
if (DBG_IOBUF)
log_debug ("iobuf-%d.%d: ioctl '%s' peek\n",
a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc));
if (a->filter == file_filter && ptrval && intval)
{
file_filter_ctx_t *fcx = a->filter_ov;
size_t len = intval;
if (!file_filter (fcx, IOBUFCTRL_PEEK, NULL, ptrval, &len))
return (int)len;
}
}
return -1;
@ -1755,13 +1853,13 @@ iobuf_pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
{
/* This should be the last filter in the pipeline. */
assert (! a->chain);
log_assert (! a->chain);
return 0;
}
if (!a->filter)
{ /* this is simple */
b = a->chain;
assert (b);
log_assert (b);
xfree (a->d.buf);
xfree (a->real_fname);
memcpy (a, b, sizeof *a);
@ -1856,14 +1954,14 @@ underflow_target (iobuf_t a, int clear_pending_eof, size_t target)
buffer. */
return -1;
assert (a->use == IOBUF_INPUT);
log_assert (a->use == IOBUF_INPUT);
a->e_d.used = 0;
/* If there is still some buffered data, then move it to the start
of the buffer and try to fill the end of the buffer. (This is
useful if we are called from iobuf_peek().) */
assert (a->d.start <= a->d.len);
log_assert (a->d.start <= a->d.len);
a->d.len -= a->d.start;
if (a->d.len)
memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
@ -2027,7 +2125,7 @@ underflow_target (iobuf_t a, int clear_pending_eof, size_t target)
}
}
assert (a->d.start <= a->d.len);
log_assert (a->d.start <= a->d.len);
if (a->e_d.used > 0)
return 0;
if (a->d.start < a->d.len)
@ -2107,7 +2205,7 @@ iobuf_readbyte (iobuf_t a)
return -1;
}
assert (a->d.start <= a->d.len);
log_assert (a->d.start <= a->d.len);
if (a->nlimit && a->nbytes >= a->nlimit)
return -1; /* forced EOF */
@ -2119,7 +2217,7 @@ iobuf_readbyte (iobuf_t a)
else if ((c = underflow (a, 1)) == -1)
return -1; /* EOF */
assert (a->d.start <= a->d.len);
log_assert (a->d.start <= a->d.len);
/* Note: if underflow doesn't return EOF, then it returns the first
byte that was read and advances a->d.start appropriately. */
@ -2244,8 +2342,8 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
{
int n = 0;
assert (buflen > 0);
assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
log_assert (buflen > 0);
log_assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
if (buflen > a->d.size)
/* We can't peek more than we can buffer. */
@ -2261,7 +2359,7 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
/* Underflow consumes the first character (it's the return
value). unget() it by resetting the "file position". */
assert (a->d.start == 1);
log_assert (a->d.start == 1);
a->d.start = 0;
}
@ -2296,7 +2394,7 @@ iobuf_writebyte (iobuf_t a, unsigned int c)
if ((rc=filter_flush (a)))
return rc;
assert (a->d.len < a->d.size);
log_assert (a->d.len < a->d.size);
a->d.buf[a->d.len++] = c;
return 0;
}
@ -2397,8 +2495,8 @@ iobuf_writestr (iobuf_t a, const char *buf)
int
iobuf_write_temp (iobuf_t dest, iobuf_t source)
{
assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
log_assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
log_assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
iobuf_flush_temp (source);
return iobuf_write (dest, source->d.buf, source->d.len);
@ -2782,7 +2880,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
NUL character in the buffer. This requires at least 2 bytes. We
don't complicate the code by handling the stupid corner case, but
simply assert that it can't happen. */
assert (!buffer || length >= 2 || maxlen >= 2);
log_assert (!buffer || length >= 2 || maxlen >= 2);
if (!buffer || length <= 1)
/* must allocate a new buffer */
@ -2853,7 +2951,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
/* p is pointing at the last byte in the buffer. We
always terminate the line with "\n\0" so overwrite
the previous byte with a \n. */
assert (p > buffer);
log_assert (p > buffer);
p[-1] = '\n';
/* Indicate truncation. */

View file

@ -106,6 +106,7 @@ enum
IOBUFCTRL_FLUSH = 4,
IOBUFCTRL_DESC = 5,
IOBUFCTRL_CANCEL = 6,
IOBUFCTRL_PEEK = 7,
IOBUFCTRL_USER = 16
};
@ -116,7 +117,8 @@ typedef enum
IOBUF_IOCTL_KEEP_OPEN = 1, /* Uses intval. */
IOBUF_IOCTL_INVALIDATE_CACHE = 2, /* Uses ptrval. */
IOBUF_IOCTL_NO_CACHE = 3, /* Uses intval. */
IOBUF_IOCTL_FSYNC = 4 /* Uses ptrval. */
IOBUF_IOCTL_FSYNC = 4, /* Uses ptrval. */
IOBUF_IOCTL_PEEK = 5 /* Uses intval and ptrval. */
} iobuf_ioctl_t;
enum iobuf_use

View file

@ -154,6 +154,14 @@ map_static_macro_string (const char *string)
membuf_t mb;
char *p;
/* We use a hack if we don't use the fixed gpgrt 1.47
* (commit 885a287a57cf060b4c5b441822c09d23b8dee2bd) */
#if GPGRT_VERSION_NUMBER < 0x012f00
if (string && !strncmp (string, "Project-Id-Version:", 19)
&& strstr (string, "PO-Revision-Date:"))
return "";
#endif
if ((s = already_mapped (string)))
return s;
s = string;

View file

@ -418,7 +418,7 @@ decode_c_string (const char *src)
/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed
* packet. LEN should be at least 6. */
static int
is_openpgp_compressed_packet (unsigned char *buf, size_t len)
is_openpgp_compressed_packet (const unsigned char *buf, size_t len)
{
int c, ctb, pkttype;
int lenbytes;
@ -460,63 +460,64 @@ is_openpgp_compressed_packet (unsigned char *buf, size_t len)
/*
* Check if the file is compressed.
* Check if the file is compressed. You need to pass the first bytes
* of the file as (BUF,BUFLEN). Returns true if the buffer seems to
* be compressed.
*/
int
is_file_compressed (const char *s, int *ret_rc)
is_file_compressed (const byte *buf, unsigned int buflen)
{
iobuf_t a;
byte buf[6];
int i;
int rc = 0;
int overflow;
int i;
struct magic_compress_s {
size_t len;
byte magic[4];
} magic[] = {
{ 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
{ 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
{ 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
};
struct magic_compress_s
{
byte len;
byte extchk;
byte magic[5];
} magic[] =
{
{ 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
{ 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
{ 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
{ 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */
{ 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */
{ 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */
};
if ( iobuf_is_pipe_filename (s) || !ret_rc )
return 0; /* We can't check stdin or no file was given */
a = iobuf_open( s );
if ( a == NULL ) {
*ret_rc = gpg_error_from_syserror ();
return 0;
}
iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
if ( iobuf_get_filelength( a, &overflow ) < 6 && !overflow) {
*ret_rc = 0;
goto leave;
if ( buflen < 6 )
{
return 0; /* Too short to check - assume uncompressed. */
}
if ( iobuf_read( a, buf, 6 ) == -1 ) {
*ret_rc = a->error;
goto leave;
}
for ( i = 0; i < DIM( magic ); i++ ) {
if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) {
*ret_rc = 0;
rc = 1;
goto leave;
for ( i = 0; i < DIM (magic); i++ )
{
if (!memcmp( buf, magic[i].magic, magic[i].len))
{
switch (magic[i].extchk)
{
case 0:
return 1; /* Is compressed. */
case 1:
if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5))
return 1; /* JFIF: this likely a compressed JPEG. */
break;
case 2:
if (buflen > 8
&& buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a)
return 1; /* This is a PNG. */
break;
default:
break;
}
}
}
if (is_openpgp_compressed_packet (buf, 6))
{
*ret_rc = 0;
rc = 1;
}
if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen))
{
return 1; /* Already compressed. */
}
leave:
iobuf_close( a );
return rc;
return 0; /* Not detected as compressed. */
}

View file

@ -359,7 +359,7 @@ char *try_make_printable_string (const void *p, size_t n, int delim);
char *make_printable_string (const void *p, size_t n, int delim);
char *decode_c_string (const char *src);
int is_file_compressed (const char *s, int *ret_rc);
int is_file_compressed (const byte *buf, unsigned int buflen);
int match_multistr (const char *multistr,const char *match);

View file

@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0"
#define W32INFO_PRODUCTVERSION "@VERSION@\0"
#define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \
2021 g10 Code GmbH\0"
2023 g10 Code GmbH\0"