Commit Graph

471 Commits

Author SHA1 Message Date
Lasse Collin 31d3912f29 liblzma: Omit an unneeded array from the x86 filter
Fixes: 6aa2a6deeb
(cherry picked from commit de06b9f0c0)
2024-05-27 16:57:13 +03:00
Lasse Collin 891602da97 liblzma: Silence a warning from Coverity static analysis
It is logical why it cannot know for sure that the value has
to be at most 4 if it is less than 16.

The x86 filter is based on a very old LZMA SDK version. Newer
ones have quite a different implementation for the same filter.

Thanks to Sam James.

(cherry picked from commit 6aa2a6deeb)
2024-05-27 16:57:13 +03:00
Lasse Collin 702b9ed690 Fix typos
Thanks to xx on #tukaani.

(cherry picked from commit 4e9023857d)
2024-05-22 00:34:26 +03:00
Lasse Collin 37314d4d18 Update maintainer and author info.
The other maintainer suddenly disappeared.

(cherry picked from commit 77a294d98a)
(cherry picked from commit 37c46f7b67)
2024-05-22 00:34:26 +03:00
Lasse Collin 02d0318629 liblzma: Fix incorrect function type error from sanitizer
Clang 17 with -fsanitize=address,undefined:

    src/liblzma/common/filter_common.c:366:8: runtime error:
        call to function encoder_find through pointer to incorrect
        function type 'const lzma_filter_coder *(*)(unsigned long)'
    src/liblzma/common/filter_encoder.c:187: note:
        encoder_find defined here

Use a wrapper function to get the correct type neatly.
This reduces the number of casts needed too.

This issue could be a problem with control flow integrity (CFI)
methods that check the function type on indirect function calls.

Fixes: 3b34851de1
(cherry picked from commit 278563ef8f)
(cherry picked from commit 64e0a5f726)
2024-05-22 00:34:26 +03:00
Lasse Collin ecbc34d90b liblzma: index_decoder: Fix missing initializations on LZMA_PROG_ERROR
If the arguments to lzma_index_decoder() or lzma_index_buffer_decode()
were such that LZMA_PROG_ERROR was returned, the lzma_index **i
argument wasn't touched even though the API docs say that *i = NULL
is done if an error occurs. This obviously won't be done even now
if i == NULL but otherwise it is best to do it due to the wording
in the API docs.

In practice this matters very little: The problem can occur only
if the functions are called with invalid arguments, that is,
the calling application must already have a bug.

(cherry picked from commit 71eed2520e)
(cherry picked from commit 214569ace8)
2024-05-22 00:34:26 +03:00
Lasse Collin 639d053823 liblzma: Minor comment edits.
(cherry picked from commit 3217b82b3e)
(cherry picked from commit 32e256c12a)
2024-05-22 00:34:26 +03:00
Sergey Kosukhin 7de966a02b liblzma: Fix building with NVHPC (NVIDIA HPC SDK).
NVHPC compiler has several issues that make it impossible to
build liblzma:
  - the compiler fails to produce valid code for delta_decode if the
    vectorization is enabled, which results in failed tests.

This introduces NVHPC-specific workarounds that address the issues.

(This commit was contributed under 0BSD but the author confirmed
that it is fine to backport it to the public domain branches. See
https://github.com/tukaani-project/xz/pull/90#issuecomment-2100185936
and the next two messages.)

(cherry picked from commit 096bc0e3f8)
(cherry picked from commit 65ac20807c)
2024-05-22 00:34:26 +03:00
Lasse Collin fda91a5d77 liblzma: Fix compilation of price_tablegen.c.
It is built and run only manually so this didn't matter
unless one wanted to regenerate the price_table.c.

(cherry picked from commit 8e4ec79483)
(cherry picked from commit 65b5ee0716)
2024-05-07 19:57:27 +03:00
Lasse Collin 594b64742f liblzma: Sync the AUTHORS fix about SHA-256 to lzma.h.
(based on commit 23de53421e)

(cherry picked from commit f200c338f8)
2024-05-07 19:57:27 +03:00
Lasse Collin 6aba0e2a5e Fix SHA-256 authors.
The initial commit 5d018dc035
in 2007 had a comment in sha256.c that the code is based on
Crypto++ Library 5.5.1. In 2009 the Authors list in sha256.c
and the AUTHORS file was updated with information that the
code had come from Crypto++ but via 7-Zip. I know I had viewed
7-Zip's SHA-256 code but back then the C code has been identical
enough with Crypto++, so I don't why I thought the author info
would need that extra step via 7-Zip for this single file.

Another error is that I had mixed sha.* and shacal2.* files
when checking for author info in Crypto++. The shacal2.* files
aren't related to liblzma's sha256.c and thus Kevin Springle's
code in Crypto++ isn't either.

(cherry picked from commit 76946dc433)
(cherry picked from commit 402fb45c74)
2024-05-07 19:57:27 +03:00
Lasse Collin 74d36a57c5 liblzma: Set all values in lzma_lz_encoder to NULL after allocation.
This is unlikely to be a bug in an existing application since it relies
on calling lzma_filters_update() on an LZMA1 encoder in the first place.
For instance, it does not affect xz because lzma_filters_update() can
only be used when encoding to the .xz format.

(based on commit 8191720eac)
2024-05-07 19:56:46 +03:00
Jia Tan 176ae9073c liblzma: Make parameter names in function definition match declaration.
lzma_raw_encoder() and lzma_raw_encoder_init() used "options" as the
parameter name instead of "filters" (used by the declaration). "filters"
is more clear since the parameter represents the list of filters passed
to the raw encoder, each of which contains filter options.

(cherry picked from commit 27ab54af84)
2024-05-07 17:57:51 +03:00
Jia Tan 94c8503486 liblzma: Improve lzma encoder init function consistency.
lzma_encoder_init() did not check for NULL options, but
lzma2_encoder_init() did. This is more of a code style improvement than
anything else to help make lzma_encoder_init() and lzma2_encoder_init()
more similar.

(cherry picked from commit 019afd72e0)
2024-05-07 17:57:51 +03:00
Jia Tan 9c47c0ea18 liblzma: Add missing comments to lz_encoder.h.
(cherry picked from commit 84196e8c09)
2024-05-07 17:50:45 +03:00
Lasse Collin 290c954289 liblzma: Fix compilation of fastpos_tablegen.c.
The macro lzma_attr_visibility_hidden has to be defined to make
fastpos.h usable. The visibility attribute is irrelevant to
fastpos_tablegen.c so simply #define the macro to an empty value.

fastpos_tablegen.c is never built by the included build systems
and so the problem wasn't noticed earlier. It's just a standalone
program for generating fastpos_table.c.

Fixes: https://github.com/tukaani-project/xz/pull/69
Thanks to GitHub user Jamaika1.

(cherry picked from commit d90ed84db9)
2024-05-07 17:50:45 +03:00
Lasse Collin d7bff1341e liblzma: Use lzma_always_inline in memcmplen.h.
(cherry picked from commit 068ee436f4)
2024-05-07 17:50:45 +03:00
Lasse Collin ce8d257cbb liblzma: #define lzma_always_inline in common.h.
(cherry picked from commit 6cdf0a7b79)
2024-05-07 17:50:45 +03:00
Lasse Collin 47b3d2761e liblzma: Use lzma_attr_visibility_hidden on private extern declarations.
These variables are internal to liblzma and not exposed in the API.

(cherry picked from commit 33daad3961)
2024-05-07 17:50:45 +03:00
Lasse Collin 44c98e9399 liblzma: #define lzma_attr_visibility_hidden in common.h.
In ELF shared libs:

-fvisibility=hidden affects definitions of symbols but not
declarations.[*] This doesn't affect direct calls to functions
inside liblzma as a linker can replace a call to lzma_foo@plt
with a call directly to lzma_foo when -fvisibility=hidden is used.

[*] It has to be like this because otherwise every installed
    header file would need to explictly set the symbol visibility
    to default.

When accessing extern variables that aren't defined in the
same translation unit, compiler assumes that the variable has
the default visibility and thus indirection is needed. Unlike
function calls, linker cannot optimize this.

Using __attribute__((__visibility__("hidden"))) with the extern
variable declarations tells the compiler that indirection isn't
needed because the definition is in the same shared library.

About 15+ years ago, someone told me that it would be good if
the CRC tables would be defined in the same translation unit
as the C code of the CRC functions. While I understood that it
could help a tiny amount, I didn't want to change the code because
a separate translation unit for the CRC tables was needed for the
x86 assembly code anyway. But when visibility attributes are
supported, simply marking the extern declaration with the
hidden attribute will get identical result. When there are only
a few affected variables, this is trivial to do. I wish I had
understood this back then already.

(cherry picked from commit 6961a5ac7d)
2024-05-07 17:50:45 +03:00
Lasse Collin 7834108dfe liblzma: Refer to MinGW-w64 instead of MinGW in the API headers.
MinGW (formely a MinGW.org Project, later the MinGW.OSDN Project
at <https://osdn.net/projects/mingw/>) has GCC 9.2.0 as the
most recent GCC package (released 2021-02-02). The project might
still be alive but majority of people have switched to MinGW-w64.
Thus it seems clearer to refer to MinGW-w64 in our API headers too.
Building with MinGW is likely to still work but I haven't tested it
in the recent years.

(cherry picked from commit 5b9e167649)
2024-05-07 17:47:12 +03:00
Lasse Collin 3c026350e8 liblzma: Add Cflags.private to liblzma.pc.in for MSYS2.
It properly adds -DLZMA_API_STATIC when compiling code that
will be linked against static liblzma. Having it there on
systems other than Windows does no harm.

See: https://www.msys2.org/docs/pkgconfig/
(cherry picked from commit 4083c8e950)
2024-05-07 16:26:35 +03:00
Lasse Collin a3de1b841e liblzma: Move a few __attribute__ uses in function declarations.
The API headers have many attributes but these were left
as is for now.

(cherry picked from commit e3478ae4f3)
2024-05-07 15:58:21 +03:00
Lasse Collin 015e62b18d Remove incorrect uses of __attribute__((__malloc__)).
xrealloc() is obviously incorrect, modern GCC docs even
mention realloc() as an example where this attribute
cannot be used.

liblzma's lzma_alloc() and lzma_alloc_zero() would be
correct uses most of the time but custom allocators
may use a memory pool or otherwise hold the pointer
so aliasing issues could happen in theory.

The xstrdup() case likely was correct but I removed it anyway.
Now there are no __malloc__ attributes left in the code.
The allocations aren't in hot paths so this should make
no practical difference.

(cherry picked from commit 359e5c6cb1)
2024-05-07 15:44:54 +03:00
Jia Tan 519896fc94 liblzma: Update assert in vli_ceil4().
The argument to vli_ceil4() should always guarantee the return value
is also a valid lzma_vli. Thus the highest three valid lzma_vli values
are invalid arguments. All uses of the function ensure this so the
assert is updated to match this.

(cherry picked from commit 773f1e8622)
2024-05-07 15:31:30 +03:00
Jia Tan 591ac56d42 liblzma: Add overflow check for Unpadded size in lzma_index_append().
This was not a security bug since there was no path to overflow
UINT64_MAX in lzma_index_append() or when it calls index_file_size().
The bug was discovered by a failing assert() in vli_ceil4() when called
from index_file_size() when unpadded_sum (the sum of the compressed size
of current Stream and the unpadded_size parameter) exceeds LZMA_VLI_MAX.

Previously, the unpadded_size parameter was checked to be not greater
than UNPADDED_SIZE_MAX, but no check was done once compressed_base was
added.

This could not have caused an integer overflow in index_file_size() when
called by lzma_index_append(). The calculation for file_size breaks down
into the sum of:

- Compressed base from all previous Streams
- 2 * LZMA_STREAM_HEADER_SIZE (size of the current Streams header and
  footer)
- stream_padding (can be set by lzma_index_stream_padding())
- Compressed base from the current Stream
- Unpadded size (parameter to lzma_index_append())

The sum of everything except for Unpadded size must be less than
LZMA_VLI_MAX. This is guarenteed by overflow checks in the functions
that can set these values including lzma_index_stream_padding(),
lzma_index_append(), and lzma_index_cat(). The maximum value for
Unpadded size is enforced by lzma_index_append() to be less than or
equal UNPADDED_SIZE_MAX. Thus, the sum cannot exceed UINT64_MAX since
LZMA_VLI_MAX is half of UINT64_MAX.

Thanks to Joona Kannisto for reporting this.

(cherry picked from commit 68bda971bb)
2024-05-07 15:31:30 +03:00
Jia Tan 9d4bf2d06f liblzma: Prevent an empty translation unit in Windows builds.
To workaround Automake lacking Windows resource compiler support, an
empty source file is compiled to overwrite the resource files for static
library builds. Translation units without an external declaration are
not allowed by the C standard and result in a warning when used with
-Wempty-translation-unit (Clang) or -pedantic (GCC).

(cherry picked from commit 19899340cf)
2024-05-07 15:28:35 +03:00
Lasse Collin 5a87d91321 liblzma: Tweak #if condition in memcmplen.h.
Maybe ICC always #defines _MSC_VER on Windows but now
it's very clear which code will get used.

(cherry picked from commit b406828a6d)
2024-05-07 15:28:35 +03:00
Lasse Collin 0c53f52657 liblzma: Omit unnecessary parenthesis in a preprocessor directive.
(cherry picked from commit ef4a07ad94)
2024-05-07 15:28:35 +03:00
Jia Tan eede1df4af liblzma: Prevent warning for MSYS2 Windows build.
In lzma_memcmplen(), the <intrin.h> header file is only included if
_MSC_VER and _M_X64 are both defined but _BitScanForward64() was
previously used if _M_X64 was defined. GCC for MSYS2 defines _M_X64 but
not _MSC_VER so _BitScanForward64() was used without including
<intrin.h>.

Now, lzma_memcmplen() will use __builtin_ctzll() for MSYS2 GCC builds as
expected.

(cherry picked from commit 64ee0caaea)
2024-05-07 15:28:35 +03:00
Jia Tan 5f9bf81044 liblzma: Prevent uninitialzed warning in mt stream encoder.
This change only impacts the compiler warning since it was impossible
for the wait_abs struct in stream_encode_mt() to be used before it was
initialized since mythread_condtime_set() will always be called before
mythread_cond_timedwait().

Since the mythread.h code is different between the POSIX and
Windows versions, this warning was only present on Windows builds.

Thanks to Arthur S for reporting the warning and providing an initial
patch.

(cherry picked from commit 1155471651)
2024-05-07 15:23:51 +03:00
Jia Tan 774145adfd Bump version and soname for 5.2.12. 2023-05-04 21:55:11 +08:00
Jia Tan b02e74eb73 Windows: Include <intrin.h> when needed.
Legacy Windows did not need to #include <intrin.h> to use the MSVC
intrinsics. Newer versions likely just issue a warning, but the MSVC
documentation says to include the header file for the intrinsics we use.

GCC and Clang can "pretend" to be MSVC on Windows, so extra checks are
needed in tuklib_integer.h to only include <intrin.h> when it will is
actually needed.
2023-05-03 22:33:10 +03:00
Lasse Collin 3bd906f1f3 liblzma: Update project maintainers in lzma.h.
AUTHORS was updated earlier, lzma.h was simply forgotten.
2023-05-03 22:33:10 +03:00
Jia Tan 0ab5527c46 liblzma: Cleans up old commented out code. 2023-05-03 22:33:10 +03:00
Jia Tan 275e36013d Build: Removes redundant check for LZMA1 filter support. 2023-05-03 22:33:10 +03:00
Jia Tan 3e206e5c43 Bump version and soname for 5.2.11. 2023-03-18 22:25:59 +08:00
Lasse Collin 090ea9ddd3 Change a few HTTP URLs to HTTPS.
The xz man page timestamp was intentionally left unchanged.
2023-03-18 22:00:28 +08:00
Lasse Collin 09363bea46 liblzma: Avoid null pointer + 0 (undefined behavior in C).
In the C99 and C17 standards, section 6.5.6 paragraph 8 means that
adding 0 to a null pointer is undefined behavior. As of writing,
"clang -fsanitize=undefined" (Clang 15) diagnoses this. However,
I'm not aware of any compiler that would take advantage of this
when optimizing (Clang 15 included). It's good to avoid this anyway
since compilers might some day infer that pointer arithmetic implies
that the pointer is not NULL. That is, the following foo() would then
unconditionally return 0, even for foo(NULL, 0):

    void bar(char *a, char *b);

    int foo(char *a, size_t n)
    {
        bar(a, a + n);
        return a == NULL;
    }

In contrast to C, C++ explicitly allows null pointer + 0. So if
the above is compiled as C++ then there is no undefined behavior
in the foo(NULL, 0) call.

To me it seems that changing the C standard would be the sane
thing to do (just add one sentence) as it would ensure that a huge
amount of old code won't break in the future. Based on web searches
it seems that a large number of codebases (where null pointer + 0
occurs) are being fixed instead to be future-proof in case compilers
will some day optimize based on it (like making the above foo(NULL, 0)
return 0) which in the worst case will cause security bugs.

Some projects don't plan to change it. For example, gnulib and thus
many GNU tools currently require that null pointer + 0 is defined:

    https://lists.gnu.org/archive/html/bug-gnulib/2021-11/msg00000.html

    https://www.gnu.org/software/gnulib/manual/html_node/Other-portability-assumptions.html

In XZ Utils null pointer + 0 issue should be fixed after this
commit. This adds a few if-statements and thus branches to avoid
null pointer + 0. These check for size > 0 instead of ptr != NULL
because this way bugs where size > 0 && ptr == NULL will likely
get caught quickly. None of them are in hot spots so it shouldn't
matter for performance.

A little less readable version would be replacing

    ptr + offset

with

    offset != 0 ? ptr + offset : ptr

or creating a macro for it:

    #define my_ptr_add(ptr, offset) \
            ((offset) != 0 ? ((ptr) + (offset)) : (ptr))

Checking for offset != 0 instead of ptr != NULL allows GCC >= 8.1,
Clang >= 7, and Clang-based ICX to optimize it to the very same code
as ptr + offset. That is, it won't create a branch. So for hot code
this could be a good solution to avoid null pointer + 0. Unfortunately
other compilers like ICC 2021 or MSVC 19.33 (VS2022) will create a
branch from my_ptr_add().

Thanks to Marcin Kowalczyk for reporting the problem:
https://github.com/tukaani-project/xz/issues/36
2023-03-11 21:47:47 +02:00
Jia Tan 050c6dbf96 liblzma: Fix documentation for LZMA_MEMLIMIT_ERROR.
LZMA_MEMLIMIT_ERROR was missing the "<" character needed to put
documentation after a member.
2023-03-11 21:45:26 +02:00
Lasse Collin 2ca95b7cfe liblzma: Silence warnings from clang -Wconditional-uninitialized.
This is similar to 2ce4f36f17.
The actual initialization of the variables is done inside
mythread_sync() macro. Clang doesn't seem to see that
the initialization code inside the macro is always executed.
2023-03-11 21:38:31 +02:00
Lasse Collin f900dd937f Fix warnings from clang -Wdocumentation. 2023-03-11 21:37:49 +02:00
Jia Tan 2155fef528 liblzma: Update documentation for lzma_filter_encoder. 2023-03-11 21:34:26 +02:00
Lasse Collin f7c2cc5561 Bump version and soname for 5.2.10. 2022-12-13 13:03:20 +02:00
Lasse Collin 7623b22d1d liblzma: Check for unexpected NULL pointers in block_header_decode().
The API docs gave an impression that such checks are done
but they actually weren't done. In practice it made little
difference since the calling code has a bug if these are NULL.

Thanks to Jia Tan for the original patch that checked for
block->filters == NULL.
2022-12-12 15:47:17 +02:00
Lasse Collin ef315163ef liblzma: Use __has_attribute(__symver__) to fix Clang detection.
If someone sets up Clang to define __GNUC__ to 10 or greater
then symvers broke. __has_attribute is supported by such GCC
and Clang versions that don't support __symver__ so this should
be much better and simpler way to detect if __symver__ is
actually supported.

Thanks to Tomasz Gajc for the bug report.
2022-12-12 15:47:17 +02:00
Lasse Collin d8a898eb99 Bump version and soname for 5.2.9. 2022-11-30 18:33:05 +02:00
Lasse Collin 841448e36d liblzma: Remove two FIXME comments. 2022-11-29 10:46:06 +02:00
Lasse Collin b61da00c7f Build: Don't put GNU/Linux-specific symbol versions into static liblzma.
It not only makes no sense to put symbol versions into a static library
but it can also cause breakage.

By default Libtool #defines PIC if building a shared library and
doesn't define it for static libraries. This is documented in the
Libtool manual. It can be overriden using --with-pic or --without-pic.
configure.ac detects if --with-pic or --without-pic is used and then
gives an error if neither --disable-shared nor --disable-static was
used at the same time. Thus, in normal situations it works to build
both shared and static library at the same time on GNU/Linux,
only --with-pic or --without-pic requires that only one type of
library is built.

Thanks to John Paul Adrian Glaubitz from Debian for reporting
the problem that occurred on ia64:
https://www.mail-archive.com/xz-devel@tukaani.org/msg00610.html
2022-11-24 23:50:46 +02:00
Lasse Collin 872623def5 liblzma: Fix another invalid free() after memory allocation failure.
This time it can happen when lzma_stream_encoder_mt() is used
to reinitialize an existing multi-threaded Stream encoder
and one of 1-4 tiny allocations in lzma_filters_copy() fail.

It's very similar to the previous bug
10430fbf38, happening with
an array of lzma_filter structures whose old options are freed
but the replacement never arrives due to a memory allocation
failure in lzma_filters_copy().
2022-11-24 10:58:04 +02:00