xz/src/liblzma/common
Lasse Collin 30e95bb44c 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-02-23 20:41:22 +02:00
..
Makefile.inc liblzma: Add lzma_str_to_filters, _from_filters, and _list_filters. 2022-11-28 21:54:24 +02:00
alone_decoder.c liblzma: Use LZMA1EXT feature in lzma_alone_decoder(). 2022-11-28 10:28:20 +02:00
alone_decoder.h liblzma: Be less picky in lzma_alone_decoder(). 2013-03-23 22:25:15 +02:00
alone_encoder.c liblzma: Pass the Filter ID to LZ encoder and decoder. 2022-11-27 18:20:33 +02:00
auto_decoder.c liblzma: Add .lz support to lzma_auto_decoder(). 2022-11-09 14:25:26 +02:00
block_buffer_decoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
block_buffer_encoder.c liblzma: Vaccinate against an ill patch from RHEL/CentOS 7. 2022-09-08 15:01:29 +03:00
block_buffer_encoder.h liblzma: Add lzma_block_uncomp_encode(). 2013-03-23 19:17:33 +02:00
block_decoder.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
block_decoder.h liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
block_encoder.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
block_encoder.h liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
block_header_decoder.c liblzma: Check for unexpected NULL pointers in block_header_decode(). 2022-12-08 17:30:09 +02:00
block_header_encoder.c Rename unaligned_read32ne to read32ne, and similarly for the others. 2019-12-31 00:47:49 +02:00
block_util.c liblzma: Fix comments. 2019-06-03 20:41:54 +03:00
common.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
common.h liblzma: Use __has_attribute(__symver__) to fix Clang detection. 2022-12-01 20:55:21 +02:00
easy_buffer_encoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
easy_decoder_memusage.c Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
easy_encoder.c liblzma: Make lzma_stream_encoder_init() static (second try). 2011-04-11 09:27:57 +03:00
easy_encoder_memusage.c Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
easy_preset.c Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
easy_preset.h Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
file_info.c spelling 2019-05-11 20:52:37 +03:00
filter_buffer_decoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
filter_buffer_encoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
filter_common.c liblzma: Make lzma_validate_chain() available outside filter_common.c. 2022-11-28 21:02:19 +02:00
filter_common.h liblzma: Make lzma_validate_chain() available outside filter_common.c. 2022-11-28 21:02:19 +02:00
filter_decoder.c liblzma: Add LZMA_FILTER_LZMA1EXT to support LZMA1 without end marker. 2022-11-27 23:16:21 +02:00
filter_decoder.h liblzma: Fix comments. 2019-06-03 20:41:54 +03:00
filter_encoder.c liblzma: Update documentation for lzma_filter_encoder. 2022-12-30 23:34:31 +08:00
filter_encoder.h liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
filter_flags_decoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
filter_flags_encoder.c liblzma: Fix comments. 2019-06-03 20:41:54 +03:00
hardware_cputhreads.c liblzma: Vaccinate against an ill patch from RHEL/CentOS 7. 2022-09-08 15:01:29 +03:00
hardware_physmem.c spelling 2019-05-11 20:52:37 +03:00
index.c liblzma: Remove common.h include from common/index.h. 2023-01-05 20:57:25 +08:00
index.h liblzma: Remove common.h include from common/index.h. 2023-01-05 20:57:25 +08:00
index_decoder.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
index_decoder.h liblzma: Remove common.h include from common/index.h. 2023-01-05 20:57:25 +08:00
index_encoder.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
index_encoder.h liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
index_hash.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
lzip_decoder.c liblzma: Avoid null pointer + 0 (undefined behavior in C). 2023-02-23 20:41:22 +02:00
lzip_decoder.h liblzma: Add .lz support to lzma_auto_decoder(). 2022-11-09 14:25:26 +02:00
memcmplen.h liblzma: Fix incorrect #ifdef for x86 SSE2 support. 2022-11-11 14:35:58 +02:00
microlzma_decoder.c liblzma: Use LZMA1EXT feature in lzma_microlzma_decoder(). 2022-11-28 10:48:53 +02:00
microlzma_encoder.c liblzma: Fix lzma_microlzma_encoder() return value. 2022-12-30 23:34:31 +08:00
outqueue.c liblzma: Add new output queue (lzma_outq) features. 2022-03-06 16:41:19 +02:00
outqueue.h liblzma: Add new output queue (lzma_outq) features. 2022-03-06 16:41:19 +02:00
stream_buffer_decoder.c liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
stream_buffer_encoder.c liblzma: Remove common.h include from common/index.h. 2023-01-05 20:57:25 +08:00
stream_decoder.c liblzma: Replaced hardcoded 0x0 index indicator byte with macro 2023-01-02 22:20:04 +08:00
stream_decoder.h liblzma: Make the use of lzma_allocator const-correct. 2012-07-17 18:19:59 +03:00
stream_decoder_mt.c liblzma: Silence warnings from clang -Wconditional-uninitialized. 2023-01-12 03:19:59 +02:00
stream_encoder.c liblzma: Refactor to use lzma_filters_free(). 2022-11-24 01:32:16 +02:00
stream_encoder_mt.c liblzma: Silence warnings from clang -Wconditional-uninitialized. 2023-01-12 03:19:59 +02:00
stream_flags_common.c Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
stream_flags_common.h Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00
stream_flags_decoder.c Rename unaligned_read32ne to read32ne, and similarly for the others. 2019-12-31 00:47:49 +02:00
stream_flags_encoder.c Rename unaligned_read32ne to read32ne, and similarly for the others. 2019-12-31 00:47:49 +02:00
string_conversion.c liblzma: Fix bug in lzma_str_from_filters() not checking filters[] length. 2023-02-03 00:42:27 +08:00
vli_decoder.c spelling 2019-05-11 20:52:37 +03:00
vli_encoder.c Fix incorrect use of "restrict". 2009-09-15 21:07:23 +03:00
vli_size.c Put the interesting parts of XZ Utils into the public domain. 2009-04-13 11:27:40 +03:00