Commit Graph

67 Commits

Author SHA1 Message Date
Tim Kientzle
60617bf578 A subtle point: "pax interchange format" mandates that all strings
(including pathname, gname, uname) be stored in UTF-8.  This usually
doesn't cause problems on FreeBSD because the "C" locale on FreeBSD
can convert any byte to Unicode/wchar_t and from there to UTF-8.  In
other locales (including the "C" locale on Linux which is really
ASCII), you can get into trouble with pathnames that cannot be
converted to UTF-8.

Libarchive's pax writer truncated pathnames and other strings at the
first nonconvertible character.  (ouch!)  Other archivers have worked
around this by storing unconvertible pathnames as raw binary, a
practice which has been sanctioned by the Austin group.  However,
libarchive's pax reader would segfault reading headers that weren't
proper UTF-8.  (ouch!)  Since bsdtar defaults to pax format, this
affects bsdtar rather heavily.

To correctly support the new "hdrcharset" header that is going into
SUS and to handle conversion failures in general, libarchive's pax reader
and writer have been overhauled fairly extensively.  They used to do
most of the pax header processing using wchar_t (Unicode); they now do
most of it using char so that common logic applies to either UTF-8 or
"binary" strings.

As a bonus, a number of extraneous conversions to/from wchar_t have
been eliminated, which should speed things up just a tad.

Thanks to: Bjoern Jacke for originally reporting this to me
Thanks to: Joerg Sonnenberger for noting a bad typo in my first draft of this
Thanks to: Gunnar Ritter for getting the standard fixed
MFC after: 5 days
2008-03-15 01:43:59 +00:00
Tim Kientzle
20347f62e6 A block in a tar file is 512 bytes. Period.
Remove the entirely pointless symbolic constant
and sizeof(unsigned char).  (The constant
here is doubly wrong, since not only does
it obscure a basic format constant, it was
never intended to be a tar-specific value,
so could conceivably be changed at some point
in the future.)
2008-03-14 20:32:20 +00:00
Tim Kientzle
6f6dfc16c2 Tighten up the heuristic that decides whether or not we should
obey or ignore the size field on a hardlink entry.  In particular,
if we're reading a non-POSIX archive, we should always ignore
the size field.

This should fix both the audio/xmcd port and the math/unixstat port.

Thanks to: Pav Lucistnik for pointing these two ports out to me.
MFC after: 7 days
2008-01-31 07:41:45 +00:00
Tim Kientzle
a0751a90e6 Since the tar bidder can never get called more than once, it
doesn't need to compensate for this situation.

While here, fix a minor longstanding bug that empty tar archives
(which begin with at least 512 zero bytes) never properly reported
their format.  In particular, this fixes the output of:
   bsdtar tvvf /dev/zero

And, of course, a new test to verify that libarchive correctly
recognizes the format of such files.
2008-01-13 23:50:30 +00:00
Tim Kientzle
9dd49f960f Update libarchive to 2.4.10. This includes a number of improvements
that I've been working on but put off committing until after the
RELENG_7 branch, including:

* New manpages: cpio.5 mtree.5
* New archive_entry_strmode()
* New archive_entry_link_resolver()
* New read support: mtree format
* Internal API change:  read format auction only runs once
* Running the auction only once allowed simplifying a lot of bid logic.
* Cpio robustness:  search for next header after a sync error
* Support device nodes on ISO9660 images
* Eliminate a lot of unnecessary copies for uncompressed archives
* Corrected handling of new GNU --sparse --posix formats
* Correctly handle a zero-byte write to a compressed archive
* Fixed memory leaks

Many of these improvements were motivated by the upcoming bsdcpio
front-end.

There have also been extensive improvements to the libarchive_test
test harness, which I'll commit separately.
2007-12-30 04:58:22 +00:00
Tim Kientzle
6fa30d2b87 Fix reading of files that use pax 'size' attribute to store size.
In particular, bsdtar uses the pax 'size' attribute for any file
over 8G.

MFC after: 3 days
2007-10-24 04:01:31 +00:00
Tim Kientzle
68f0154dcf This commit updates libarchive to be compatible with
GNU tar 1.17's implementation of --posix --sparse,
at the cost of losing compatibility with GNU tar 1.16.
Fortunately, the 1.17 implementation actually makes sense,
so the libarchive code is now a bit more straightforward
than before.

Background:  GNU tar 1.16 defined a new way to store
sparse files in --posix archives.  Unfortunately,
the implementation incorrectly inserted several
blocks of null padding after each such entry.
As a result, non-GNU tar implementations saw the
archive as truncated after any sparse entry.
This was fixed in GNU tar 1.17 at the cost of
losing compatibility with GNU tar 1.16 for this
new format (which is not the default, so hopefully
rarely used).  Libarchive recently gained support
for reading the GNU tar 1.16 formats; this commit
updates it to read the GNU tar 1.17 variant instead.

Approved by: re (ksmith for libarchive portion)
Approved by: re (blanket for libarchive_test portion)
MFC after: 5 days
2007-08-18 21:53:25 +00:00
Tim Kientzle
d3bb697513 archive_string_ensure() used to call exit(3) if it
couldn't allocate more memory for a string.  Change
this so it returns NULL in that case, and update
all of its callers to handle the error.  Some of
those callers can now return errors back to the
client instead of calling exit(3).

Approved by: re (bmah)
2007-07-15 19:13:59 +00:00
Tim Kientzle
46dd1e6ee7 Restore the 'break' that was inadvertently removed in 1.57 of this file.
Without this, hardlinks get returned as symlinks.

Approved by: re (Ken Smith)
MFC after: 2 days
2007-07-14 05:53:51 +00:00
Colin Percival
612c3e7724 Correct multiple security issues in how libarchive handles corrupt
tar archives, including a potentially exploitable buffer overflow.

Approved by:	re (kensmith, security blanket)
Reviewed by:	kientzle
Security:	FreeBSD-SA-07:05.libarchive
2007-07-12 15:00:28 +00:00
Tim Kientzle
0ddfde5d16 Read support for the new GNU tar sparse formats added in gtar 1.15 and
gtar 1.16.
2007-06-13 03:35:37 +00:00
Tim Kientzle
b48b40f1f8 libarchive 2.2.3
* "compression_program" support uses an external program
  * Portability: no longer uses "struct stat" as a primary
    data interchange structure internally
  * Part of the above: refactor archive_entry to separate
    out copy_stat() and stat() functions
  * More complete tests for archive_entry
  * Finish archive_entry_clone()
  * Isolate major()/minor()/makedev() in archive_entry; remove
    these from everywhere else.
  * Bug fix: properly handle decompression look-ahead at end-of-data
  * Bug fixes to 'ar' support
  * Fix memory leak in ZIP reader
  * Portability: better timegm() emulation in iso9660 reader
  * New write_disk flags to suppress auto dir creation and not
    overwrite newer files (for future cpio front-end)
  * Simplify trailing-'/' fixup when writing tar and pax
  * Test enhancements:  fix various compiler warnings, improve
    portability, add lots of new tests.
  * Documentation: document new functions, first draft of
    libarchive_internals.3

MFC after: 14 days
Thanks to: Joerg Sonnenberger (compression_program)
Thanks to: Kai Wang (ar)
Thanks to: Colin Percival (many small fixes)
Thanks to: Many others who sent me various patches and problem reports.
2007-05-29 01:00:21 +00:00
Colin Percival
3662c7b8ad Don't test for NULL when it is both unnecessary (the pointer is checked
against NULL when it is first allocated) and pointless (we've already
dereferenced the pointer several times).

Found by:	Coverity Prevent(tm)
CID:		3204
2007-05-21 04:45:24 +00:00
Tim Kientzle
f912fb118f Consolidate numeric limit macros in one place; include them
only on platforms that need them.  FreeBSD doesn't.
2007-04-15 00:53:38 +00:00
Tim Kientzle
782a032689 Make Lint happier. 2007-04-12 04:42:57 +00:00
Colin Percival
41948c2530 Parse SCHILY.dev and SCHILY.ino fields. These are ignored when extracting
files, but used during archive creation.  This change unbreaks
# tar -cf rcp.tar /bin/rcp
# tar -cf rcp-copy.tar @rcp.tar
# cmp rcp.tar rcp-copy.tar
2007-04-03 23:53:55 +00:00
Colin Percival
eeb83a6572 Now that there is always a compression-layer skip function available,
skip over the end-of-entry padding instead of reading and discarding
it.

Considering that tar files normally have a block size of 10kB, this
isn't likely to avoid reading any data, but at least it makes the code
simpler and clearer.
2007-04-02 04:21:22 +00:00
Colin Percival
5998aba99e Provide a dummy compression-layer skip function which just reads data and
discards it, for use when the compression layer code doesn't know how to
skip data (e.g., everything other than the "none" compressor).  This makes
format level code simpler because that code can now assume that the
compression layer always knows how to skip and will always skip exactly
the requested number of bytes.

Discussed with:	kientzle (3 months ago)
2007-03-31 22:59:43 +00:00
Tim Kientzle
f81da3e584 libarchive 2.0
* libarchive_test program exercises many of the core features
  * Refactored old "read_extract" into new "archive_write_disk", which
    uses archive_write methods to put entries onto disk.  In particular,
    you can now use archive_write_disk to create objects on disk
    without having an archive available.
  * Pushed some security checks from bsdtar down into libarchive, where
    they can be better optimized.
  * Rearchitected the logic for creating objects on disk to reduce
    the number of system calls.  Several common cases now use a
    minimum number of system calls.
  * Virtualized some internal interfaces to provide a clearer separation
    of read and write handling and make it simpler to override key
    methods.
  * New "empty" format reader.
  * Corrected return types (this ABI breakage required the "2.0" version bump)
  * Many bug fixes.
2007-03-03 07:37:37 +00:00
Tim Kientzle
63165a380d Fix the copyright notice; it was always intended to be
a vanilla 2-clause BSD license, but somehow some confusing
extra verbage get copied from somewhere.

Also, update the copyright dates to 2007 for all of the files.

Prompted by: several questions about what those extra words really mean
2007-01-09 08:05:56 +00:00
Colin Percival
3c3619cdad Convert compression_skip from taking a size_t skip length request and
returning the length skipped in a ssize_t to using off_t for both.  This
does not break any A[BP]Is, since compression_skip is entirely internal
to libarchive.

If a skip request is > SSIZE_MAX, don't pass it down to the client layer
skip function, since those still uses size_t / ssize_t.  Instead, just
read the data and throw it away.

With this commit, libarchive/bsdtar should now successfully skip archive
entries of >2GB on 32-bit systems, but does so slower than necessary.
The performance will improve with a future A[BP]I breaking commit which
makes client layer skip functions use off_t.

Discussed with:	kientzle
MFC after:	1 week
2007-01-04 12:45:00 +00:00
Colin Percival
b1fa343fae Rewrite and simplify archive_read_format_tar_skip. Compression-layer skip
functions are required to skip the requested distance, so we can avoid
lots of bookkeeping which would otherwise be necessary.

Reviewed by:	kientzle
MFC after:	1 week
2007-01-03 21:47:35 +00:00
Tim Kientzle
fb1856eabd No change in functionality, but fill in a missing error
message when reading a truncated tar archive.
2006-11-13 16:50:18 +00:00
Tim Kientzle
aa1eeda578 Portability and style fixes:
* Actually use the HAVE_<header>_H macros to conditionally include
    system headers.  They've been defined for a long time, but only
    used in a few places.  Now they're used pretty consistently
    throughout.
  * Fill in a lot of missing casts for conversions from void*.
    Although Standard C doesn't require this, some people have been
    trying to use C++ compilers with this code, and they do require it.

Bit-for-bit, the compiled object files are identical, except for
one assert() whose line number changed, so I'm pretty confident I
didn't break anything.  ;-)
2006-11-10 06:39:46 +00:00
Tim Kientzle
c12a9d810e Some minor corrections:
* Expose functions for setting the "skip file" dev/ino information
  * Expose functions for setting/querying the block size on reads
  * Correctly propagate errors out of archive_read_close/archive_write_close
  * Update manpage with information about new functions
2006-09-05 05:59:46 +00:00
Tim Kientzle
693285bc87 Use 'skip' when ignoring data in tar archives. This dramatically
increases performance when extracting a single entry from a large
uncompressed archive, especially on slow devices such as USB hard
drives.

Requires a number of changes:
   * New archive_read_open2() supports a 'skip' client function
   * Old archive_read_open() is implemented as a wrapper now, to
     continue supporting the old API/ABI.
   * _read_open_fd and _read_open_file sprout new 'skip' functions.
   * compression layer gets a new 'skip' operation.
   * compression_none passes skip requests through to client.
   * compression_{gzip,bzip2,compress} simply ignore skip requests.

Thanks to: Benjamin Lutz, who designed and implemented the whole thing.
   I'm just committing it.  ;-)

TODO: Need to update the documentation a little bit.
2006-07-30 00:29:01 +00:00
Tim Kientzle
d3b6573b00 Simplify some of the wide-character handling, inspired
in part by OpenBSD's not-quite-standard-compliant
standard libraries.  (No loss of functionality,
just minor recoding to not rely on certain "standard"
facilities that weren't actually needed.)
2006-05-01 01:02:19 +00:00
Tim Kientzle
2228e32755 POSIX.1e-style Extended Attribute support
This commit implements storing/reading POSIX.1e-style extended
attribute information in "pax" format archives.  An outline of the
storage format is in the tar.5 manpage.  The archive_read_extract()
function has code to restore those archives to disk for Linux; FreeBSD
implementation is forthcoming.

Many thanks to Jaakko Heinonen for finding flaws in earlier
proposals and doing the bulk of the coding in this work.
2006-03-21 16:55:46 +00:00
Tim Kientzle
3bdc359ffe Portability: Use some autoconf magic to include the
correct headers for major()/minor()/makedev() on various
platforms.

Thanks to: Darin Broady
2005-11-08 03:52:42 +00:00
Tim Kientzle
7fb8511e34 Make some purely internal symbols static to reduce link pollution. 2005-10-12 15:38:45 +00:00
Tim Kientzle
a3c4173bb8 When reading GNU-style sparse archive entries, handle
the first sparse block correctly (we used to assume
that the first sparse block was always at offset zero).
2005-10-12 03:27:46 +00:00
Tim Kientzle
c4e21983bc signed/unsigned fixes (thanks to GCC4) and a few related minor style corrections. 2005-09-24 21:15:00 +00:00
Tim Kientzle
8aaa8fe733 Add a lot of error checks, based on the patches provided by Dan Lukes.
Also fixes a memory leak reported by Andrew Turner.

PR: bin/83476
Thanks to: Dan Lukes, Andrew Turner
2005-09-21 04:25:06 +00:00
Tim Kientzle
1dd0aa0c18 Style issue: Don't include <wchar.h> where it is not actually needed.
(wchar_t is defined in stddef.h, and only two files need more than that.)

Portability:  Since the wchar requirements are really quite modest,
it's easy to define basic replacements for wcslen, wcscmp, wcscpy,
etc, for use on systems that lack <wchar.h>.  In particular, this allows
libarchive to be used on older OpenBSD systems.
2005-09-10 22:58:06 +00:00
Tim Kientzle
01122e2ae0 Generate default fake "device" and "inode" numbers for entries
extracted from tar archives.  Otherwise, converting tar archives to
cpio format (with "bsdtar -cf out.cpio @in.tar") convert every entry
into a hard link to a single file.  This simple logic breaks hard
links, but that's better than the alternative.

MFC after: 7 days
2005-08-02 03:17:57 +00:00
Tim Kientzle
81a4ac6ddb A number of improvements to ZIP support.
* Handles entries with compressed size >2GB (signed/unsigned cleanup)
  * Handles entries with compressed size >4GB ("ZIP64" extension)
  * Handles Unix extensions (ctime, atime, mtime, mode, uid, etc)
  * Format-specific "skip data" override allows ZIP reader to skip
    entries without decompressing them, which makes "tar -t"
    a lot faster.
  * Handles "length-at-end" entries generated by, e.g., "zip -r - foo"

Many thanks to: Dan Nelson, who contributed the code and test files for
   the first three items above and suggested the fourth.
2005-04-06 04:19:30 +00:00
Tim Kientzle
516788f9a0 When rejecting rediculously large pax attributes (such as pathnames
over 1MB), issue a warning instead of forcing an internal assertion
failure.
2005-03-13 02:35:52 +00:00
Tim Kientzle
3276f95241 Include wchar.h to improve our chances of finding
WCHAR_MAX.  This might fix a portability problem on HP_UX.

Thanks to: Susan Kim
2004-12-22 06:40:28 +00:00
Tim Kientzle
4256fc3386 Tune the bidding for tar archives. This
improves the recognition of hardlink entries
with/without bodies (which is implemented through
a look-ahead that uses the bid function).

MFC after: 7 days
2004-12-22 00:49:16 +00:00
Tim Kientzle
6b31624278 Allow tar format to read and accept an empty (or non-existent)
file.  In particular, this allows bsdtar to append (-r) to
an empty file.

Thanks to: Ryan Sommers

While I'm here, straighten out a misleading comment about GNU-compatible
sparse file handling.
2004-10-27 05:15:23 +00:00
Tim Kientzle
8a95c5cb6e Some old tar archives rely on "regular-file-plus-trailing-slash" to
denote a directory.  Unfortunately, in the presence of GNU or POSIX
extensions, this code was checking the truncated filename stored in the
regular header rather than the full filename stored in the extended
attribute.  As a result, long filenames with '/' in just the right
position would trigger this check and be erroneously marked as
directories.  Move the check so it only considers the full filename.
Note: the check can't simply be disabled for archives that contain
these extensions because there are some very broken archivers out
there.

Thanks to: Will Froning
MFC after: 3 days
2004-09-04 21:49:42 +00:00
Tim Kientzle
57b665990a Eliminate reliance on non-portable <err.h> by implementing a very
simple errx() function.
Improve behavior when bzlib/zlib are missing by detecting and
issuing an error message on attempts to read gzip/bzip2 compressed
archives.
2004-08-14 03:45:45 +00:00
Tim Kientzle
0a36c0e86b Oops. Use "unsigned long" instead of "int" for the intermediate variables
in wide-character conversions, since it's guaranteed to be large enough.
Thanks to: Andrey Chernov
2004-08-08 02:22:48 +00:00
Tim Kientzle
61913b5f21 Use 'int' for certain wide-character conversions instead of wchar_t.
That quiets some compiler warnings on platforms with 16-bit wchar_t.
With this change, libarchive now compiles cleanly on Win32/cygwin.
2004-08-08 01:21:10 +00:00
Tim Kientzle
1e28302160 Fix the calculation of the most negative int64_t value, which
is used on systems that lack C99 headers (such as FreeBSD 4).
2004-08-07 06:38:40 +00:00
Tim Kientzle
45e13f191f Fix the handling of signed values when parsing base-256 header values.
In particular, this means we can now correctly read gtar archives that
contain timestamps prior to the start of the Epoch.

Also, make the code in this area more portable.  ANSI C99 headers are
not yet ubiquitous (for example, FreeBSD 4 still lacks them), so be
prepared for systems that don't have the INT64_MAX, INT64_MIN, and
UINT64_MAX macros.  This version still requires int64_t and uint64_t be
defined (which can be done in archive_platform.h if necessary), but
doesn't require them to be exactly 64 bits.
2004-07-24 17:46:45 +00:00
Tim Kientzle
527b6597a0 Clean up some consistent confusion between "dev" and "rdev."
Mostly, these were being used correctly even though a lot of
variables and function names were mis-named.

In the process, I found and fixed a couple of latent bugs and
added a guard against adding an archive to itself.
2004-06-27 18:38:13 +00:00
Tim Kientzle
1393f9061e Read gtar-style sparse archives.
This change also pointed out one API deficiency: the
archive_read_data_into_XXX functions were originally defined to return
the total bytes read.  This is, of course, ambiguous when dealing with
non-contiguous files.  Change it to just return a status value.
2004-06-27 01:15:31 +00:00
Tim Kientzle
33e546958b History: A few very, very old tar programs used the filename to
distinguish files from dirs (trailing '/' indicated a dir).  Since
POSIX.1-1987, this convention is no longer necessary.  However, there
are current tar programs that pretend to write POSIX-compliant
archives, yet store directories as "regular files", relying on this
old filename convention to save them.  <sigh> So, move the check for
this old convention so it applies to all tar archives, not just those
identified as "old."

Pointed out by: Broken distfile for audio/faad port
2004-06-07 06:34:51 +00:00
Tim Kientzle
7d9005ce33 Tar bidder should just return a zero bid ("not me!") if
it sees a truncated input the first time it gets called.
(In particular, files shorter than 512 bytes cannot be tar archives.)
This allows the top-level archive_read_next_header code to
generate a proper error message for unrecognized file types.

Pointed out by: numerous ports that expect tar to extract non-tar files ;-(
Thanks to: Kris Kennaway
2004-06-07 04:32:10 +00:00