diff options
Diffstat (limited to 'contrib/file/src/is_tar.c')
-rw-r--r-- | contrib/file/src/is_tar.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/contrib/file/src/is_tar.c b/contrib/file/src/is_tar.c index 82b08051fbdd..fa83e1e24195 100644 --- a/contrib/file/src/is_tar.c +++ b/contrib/file/src/is_tar.c @@ -28,7 +28,7 @@ /* * is_tar() -- figure out whether file is a tar archive. * - * Stolen (by the author!) from the public domain tar program: + * Stolen (by the author!) from the file_public domain tar program: * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). * * @(#)list.c 1.18 9/23/86 Public Domain - gnu @@ -40,7 +40,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $") +FILE_RCSID("@(#)$File: is_tar.c,v 1.50 2022/12/26 17:31:14 christos Exp $") #endif #include "magic.h" @@ -50,8 +50,8 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $") #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) -private int is_tar(const unsigned char *, size_t); -private int from_oct(const char *, size_t); /* Decode octal number */ +file_private int is_tar(const unsigned char *, size_t); +file_private int from_oct(const char *, size_t); /* Decode octal number */ static const char tartype[][32] = { /* should be equal to messages */ "tar archive", /* found in ../magic/Magdir/archive */ @@ -59,7 +59,7 @@ static const char tartype[][32] = { /* should be equal to messages */ "POSIX tar archive (GNU)", /* */ }; -protected int +file_protected int file_is_tar(struct magic_set *ms, const struct buffer *b) { const unsigned char *buf = CAST(const unsigned char *, b->fbuf); @@ -95,18 +95,31 @@ file_is_tar(struct magic_set *ms, const struct buffer *b) * 2 for Unix Std (POSIX) tar file, * 3 for GNU tar file. */ -private int +file_private int is_tar(const unsigned char *buf, size_t nbytes) { + static const char gpkg_match[] = "/gpkg-1"; + const union record *header = RCAST(const union record *, RCAST(const void *, buf)); size_t i; int sum, recsum; const unsigned char *p, *ep; + const char *nulp; if (nbytes < sizeof(*header)) return 0; + /* If the file looks like Gentoo GLEP 78 binary package (GPKG), + * don't waste time on further checks and fall back to magic rules. + */ + nulp = CAST(const char *, + memchr(header->header.name, 0, sizeof(header->header.name))); + if (nulp != NULL && nulp >= header->header.name + sizeof(gpkg_match) && + memcmp(nulp - sizeof(gpkg_match) + 1, gpkg_match, + sizeof(gpkg_match)) == 0) + return 0; + recsum = from_oct(header->header.chksum, sizeof(header->header.chksum)); sum = 0; @@ -140,7 +153,7 @@ is_tar(const unsigned char *buf, size_t nbytes) * * Result is -1 if the field is invalid (all blank, or non-octal). */ -private int +file_private int from_oct(const char *where, size_t digs) { int value; |