diff options
24 files changed, 280 insertions, 183 deletions
diff --git a/contrib/meson/meson.build b/contrib/meson/meson.build index 65a4c26..d1e97d9 100644 --- a/contrib/meson/meson.build +++ b/contrib/meson/meson.build @@ -7,6 +7,10 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# +# This is a dummy meson file. +# The intention is that it can be easily moved to the root of the project +# (together with meson_options.txt) and packaged for wrapdb. + project('lz4', ['c'], license: ['BSD', 'GPLv2'], default_options : ['c_std=c99', @@ -14,112 +18,4 @@ project('lz4', ['c'], version: 'DUMMY', meson_version: '>=0.47.0') -cc = meson.get_compiler('c') -pkgconfig = import('pkgconfig') -python3 = import('python').find_installation() -c_std = get_option('c_std') -default_library = get_option('default_library') - -host_machine_os = host_machine.system() -os_windows = 'windows' -os_linux = 'linux' -os_darwin = 'darwin' -os_freebsd = 'freebsd' -os_sun = 'sunos' - -cc_id = cc.get_id() -compiler_gcc = 'gcc' -compiler_clang = 'clang' -compiler_msvc = 'msvc' - -lz4_version = meson.project_version() - -lz4_h_file = join_paths(meson.current_source_dir(), '../../lib/lz4.h') -GetLz4LibraryVersion_py = files('GetLz4LibraryVersion.py') -r = run_command(python3, GetLz4LibraryVersion_py, lz4_h_file) -if r.returncode() == 0 - lz4_version = r.stdout().strip() - message('Project version is now: @0@'.format(lz4_version)) -else - error('Cannot find project version in @0@'.format(lz4_h_file)) -endif - -lz4_libversion = lz4_version - -# ============================================================================= -# Installation directories -# ============================================================================= - -lz4_prefix = get_option('prefix') -lz4_bindir = get_option('bindir') -lz4_datadir = get_option('datadir') -lz4_mandir = get_option('mandir') -lz4_docdir = join_paths(lz4_datadir, 'doc', meson.project_name()) - -# ============================================================================= -# Project options -# ============================================================================= - -buildtype = get_option('buildtype') - -# Built-in options -use_debug = get_option('debug') - -# Custom options -debug_level = get_option('debug_level') -use_backtrace = get_option('backtrace') - -bin_programs = get_option('bin_programs') -bin_contrib = get_option('bin_contrib') -bin_tests = get_option('bin_tests') -bin_examples = get_option('bin_examples') -#feature_multi_thread = get_option('multi_thread') - -# ============================================================================= -# Dependencies -# ============================================================================= - -#libm_dep = cc.find_library('m', required: bin_tests) -#thread_dep = dependency('threads', required: feature_multi_thread) -#use_multi_thread = thread_dep.found() - -# ============================================================================= -# Compiler flags -# ============================================================================= - -add_project_arguments(['-DXXH_NAMESPACE=LZ4_'], language: 'c') - -if [compiler_gcc, compiler_clang].contains(cc_id) - common_warning_flags = [] - # Should use Meson's own --werror build option - #common_warning_flags += ['-Werror'] - if c_std == 'c89' or c_std == 'gnu89' - common_warning_flags += ['-pedantic', '-Wno-long-long', '-Wno-variadic-macros'] - elif c_std == 'c99' or c_std == 'gnu99' - common_warning_flags += ['-pedantic'] - endif - cc_compile_flags = cc.get_supported_arguments(common_warning_flags) - add_project_arguments(cc_compile_flags, language: 'c') -endif - -# ============================================================================= -# Subdirs -# ============================================================================= - -subdir('lib') - -if bin_programs - subdir('programs') -endif - -if bin_tests - subdir('tests') -endif - -if bin_contrib - subdir('contrib') -endif - -if bin_examples - subdir('examples') -endif +subdir('meson') diff --git a/contrib/meson/GetLz4LibraryVersion.py b/contrib/meson/meson/GetLz4LibraryVersion.py index d8abfcb..d8abfcb 100644 --- a/contrib/meson/GetLz4LibraryVersion.py +++ b/contrib/meson/meson/GetLz4LibraryVersion.py diff --git a/contrib/meson/InstallSymlink.py b/contrib/meson/meson/InstallSymlink.py index 3f2998c..3f2998c 100644 --- a/contrib/meson/InstallSymlink.py +++ b/contrib/meson/meson/InstallSymlink.py diff --git a/contrib/meson/contrib/gen_manual/meson.build b/contrib/meson/meson/contrib/gen_manual/meson.build index 38180e9..a872bd6 100644 --- a/contrib/meson/contrib/gen_manual/meson.build +++ b/contrib/meson/meson/contrib/gen_manual/meson.build @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -lz4_root_dir = '../../../..' +lz4_root_dir = '../../../../..' add_languages('cpp') cxx = meson.get_compiler('cpp') diff --git a/contrib/meson/contrib/meson.build b/contrib/meson/meson/contrib/meson.build index 5249a4c..5249a4c 100644 --- a/contrib/meson/contrib/meson.build +++ b/contrib/meson/meson/contrib/meson.build diff --git a/contrib/meson/examples/meson.build b/contrib/meson/meson/examples/meson.build index 3c13214..493049d 100644 --- a/contrib/meson/examples/meson.build +++ b/contrib/meson/meson/examples/meson.build @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -lz4_root_dir = '../../..' +lz4_root_dir = '../../../..' #examples_c_args = ['-Wextra', '-Wundef', '-Wshadow', '-Wcast-align', '-Wstrict-prototypes'] diff --git a/contrib/meson/lib/meson.build b/contrib/meson/meson/lib/meson.build index e782334..131edcb 100644 --- a/contrib/meson/lib/meson.build +++ b/contrib/meson/meson/lib/meson.build @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -lz4_root_dir = '../../..' +lz4_root_dir = '../../../..' liblz4_includes = [include_directories(join_paths(lz4_root_dir, 'lib'))] liblz4_sources = [join_paths(lz4_root_dir, 'lib/lz4.c'), diff --git a/contrib/meson/meson/meson.build b/contrib/meson/meson/meson.build new file mode 100644 index 0000000..387e7bd --- /dev/null +++ b/contrib/meson/meson/meson.build @@ -0,0 +1,118 @@ +# ############################################################################# +# Copyright (c) 2018-present lzutao <taolzu(at)gmail.com> +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ############################################################################# + +cc = meson.get_compiler('c') +pkgconfig = import('pkgconfig') +python3 = import('python').find_installation() +c_std = get_option('c_std') +default_library = get_option('default_library') + +host_machine_os = host_machine.system() +os_windows = 'windows' +os_linux = 'linux' +os_darwin = 'darwin' +os_freebsd = 'freebsd' +os_sun = 'sunos' + +cc_id = cc.get_id() +compiler_gcc = 'gcc' +compiler_clang = 'clang' +compiler_msvc = 'msvc' + +lz4_version = meson.project_version() + +lz4_h_file = join_paths(meson.current_source_dir(), '../../../lib/lz4.h') +GetLz4LibraryVersion_py = files('GetLz4LibraryVersion.py') +r = run_command(python3, GetLz4LibraryVersion_py, lz4_h_file) +if r.returncode() == 0 + lz4_version = r.stdout().strip() + message('Project version is now: @0@'.format(lz4_version)) +else + error('Cannot find project version in @0@'.format(lz4_h_file)) +endif + +lz4_libversion = lz4_version + +# ============================================================================= +# Installation directories +# ============================================================================= + +lz4_prefix = get_option('prefix') +lz4_bindir = get_option('bindir') +lz4_datadir = get_option('datadir') +lz4_mandir = get_option('mandir') +lz4_docdir = join_paths(lz4_datadir, 'doc', meson.project_name()) + +# ============================================================================= +# Project options +# ============================================================================= + +buildtype = get_option('buildtype') + +# Built-in options +use_debug = get_option('debug') + +# Custom options +debug_level = get_option('debug_level') +use_backtrace = get_option('backtrace') + +bin_programs = get_option('bin_programs') +bin_contrib = get_option('bin_contrib') +bin_tests = get_option('bin_tests') +bin_examples = get_option('bin_examples') +#feature_multi_thread = get_option('multi_thread') + +# ============================================================================= +# Dependencies +# ============================================================================= + +#libm_dep = cc.find_library('m', required: bin_tests) +#thread_dep = dependency('threads', required: feature_multi_thread) +#use_multi_thread = thread_dep.found() + +# ============================================================================= +# Compiler flags +# ============================================================================= + +add_project_arguments(['-DXXH_NAMESPACE=LZ4_'], language: 'c') + +if [compiler_gcc, compiler_clang].contains(cc_id) + common_warning_flags = [] + # Should use Meson's own --werror build option + #common_warning_flags += ['-Werror'] + if c_std == 'c89' or c_std == 'gnu89' + common_warning_flags += ['-pedantic', '-Wno-long-long', '-Wno-variadic-macros'] + elif c_std == 'c99' or c_std == 'gnu99' + common_warning_flags += ['-pedantic'] + endif + cc_compile_flags = cc.get_supported_arguments(common_warning_flags) + add_project_arguments(cc_compile_flags, language: 'c') +endif + +# ============================================================================= +# Subdirs +# ============================================================================= + +subdir('lib') + +if bin_programs + subdir('programs') +endif + +if bin_tests + subdir('tests') +endif + +if bin_contrib + subdir('contrib') +endif + +if bin_examples + subdir('examples') +endif diff --git a/contrib/meson/programs/meson.build b/contrib/meson/meson/programs/meson.build index df64eb0..705dbf5 100644 --- a/contrib/meson/programs/meson.build +++ b/contrib/meson/meson/programs/meson.build @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -lz4_root_dir = '../../..' +lz4_root_dir = '../../../..' lz4_includes = include_directories(join_paths(lz4_root_dir, 'programs')) lz4_sources = [join_paths(lz4_root_dir, 'programs/bench.c'), diff --git a/contrib/meson/tests/meson.build b/contrib/meson/meson/tests/meson.build index 392bcf2..7800475 100644 --- a/contrib/meson/tests/meson.build +++ b/contrib/meson/meson/tests/meson.build @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -lz4_root_dir = '../../..' +lz4_root_dir = '../../../..' programs_dir_inc = include_directories(join_paths(lz4_root_dir, 'programs')) lib_dir_inc = include_directories(join_paths(lz4_root_dir, 'lib')) diff --git a/examples/frameCompress.c b/examples/frameCompress.c index a189329..aac4a3b 100644 --- a/examples/frameCompress.c +++ b/examples/frameCompress.c @@ -32,12 +32,12 @@ static void safe_fwrite(void* buf, size_t eltSize, size_t nbElt, FILE* f) { size_t const writtenSize = fwrite(buf, eltSize, nbElt, f); size_t const expectedSize = eltSize * nbElt; - assert(expectedSize / nbElt == eltSize); /* check overflow */ + if (nbElt>0) assert(expectedSize / nbElt == eltSize); /* check overflow */ if (writtenSize < expectedSize) { if (ferror(f)) /* note : ferror() must follow fwrite */ fprintf(stderr, "Write failed \n"); else - fprintf(stderr, "Short write \n"); + fprintf(stderr, "Write too short \n"); exit(1); } } @@ -249,6 +249,10 @@ static int g_debuglog_enable = 1; typedef uint64_t U64; typedef uintptr_t uptrval; #else +# include <limits.h> +# if UINT_MAX != 4294967295UL +# error "LZ4 code (when not C++ or C99) assumes that sizeof(int) == 4" +# endif typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; @@ -1625,8 +1629,8 @@ typedef enum { loop_error = -2, initial_error = -1, ok = 0 } variable_length_err LZ4_FORCE_INLINE unsigned read_variable_length(const BYTE**ip, const BYTE* lencheck, int loop_check, int initial_check, variable_length_error* error) { - unsigned length = 0; - unsigned s; + U32 length = 0; + U32 s; if (initial_check && unlikely((*ip) >= lencheck)) { /* overflow detection */ *error = initial_error; return length; diff --git a/ossfuzz/compress_frame_fuzzer.c b/ossfuzz/compress_frame_fuzzer.c index 75c609f..bb14fc2 100644 --- a/ossfuzz/compress_frame_fuzzer.c +++ b/ossfuzz/compress_frame_fuzzer.c @@ -13,13 +13,18 @@ #include "lz4.h" #include "lz4frame.h" #include "lz4_helpers.h" +#include "fuzz_data_producer.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - uint32_t seed = FUZZ_seed(&data, &size); - LZ4F_preferences_t const prefs = FUZZ_randomPreferences(&seed); + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); + LZ4F_preferences_t const prefs = FUZZ_dataProducer_preferences(producer); + size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + size_t const compressBound = LZ4F_compressFrameBound(size, &prefs); - size_t const dstCapacity = FUZZ_rand32(&seed, 0, compressBound); + size_t const dstCapacity = FUZZ_getRange_from_uint32(dstCapacitySeed, 0, compressBound); + char* const dst = (char*)malloc(dstCapacity); char* const rt = (char*)malloc(size); @@ -37,6 +42,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) free(dst); free(rt); + FUZZ_dataProducer_free(producer); return 0; } diff --git a/ossfuzz/compress_fuzzer.c b/ossfuzz/compress_fuzzer.c index 9d72e72..edc8aad 100644 --- a/ossfuzz/compress_fuzzer.c +++ b/ossfuzz/compress_fuzzer.c @@ -16,14 +16,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); - size_t const dstCapacity = FUZZ_dataProducer_uint32( - producer, 0, LZ4_compressBound(size)); + size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const compressBound = LZ4_compressBound(size); + size_t const dstCapacity = FUZZ_getRange_from_uint32(dstCapacitySeed, 0, compressBound); + char* const dst = (char*)malloc(dstCapacity); char* const rt = (char*)malloc(size); - /* Restrict to remaining data from producer */ - size = FUZZ_dataProducer_remainingBytes(producer); - FUZZ_ASSERT(dst); FUZZ_ASSERT(rt); diff --git a/ossfuzz/compress_hc_fuzzer.c b/ossfuzz/compress_hc_fuzzer.c index 5f22104..7d8e45a 100644 --- a/ossfuzz/compress_hc_fuzzer.c +++ b/ossfuzz/compress_hc_fuzzer.c @@ -17,15 +17,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); - size_t const dstCapacity = FUZZ_dataProducer_uint32( - producer, 0, LZ4_compressBound(size)); + size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size_t const levelSeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const dstCapacity = FUZZ_getRange_from_uint32(dstCapacitySeed, 0, size); + int const level = FUZZ_getRange_from_uint32(levelSeed, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX); + char* const dst = (char*)malloc(dstCapacity); char* const rt = (char*)malloc(size); - int const level = FUZZ_dataProducer_uint32( - producer, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX); - - /* Restrict to remaining data from producer */ - size = FUZZ_dataProducer_remainingBytes(producer); FUZZ_ASSERT(dst); FUZZ_ASSERT(rt); diff --git a/ossfuzz/decompress_frame_fuzzer.c b/ossfuzz/decompress_frame_fuzzer.c index 60d2ea1..0fcbb16 100644 --- a/ossfuzz/decompress_frame_fuzzer.c +++ b/ossfuzz/decompress_frame_fuzzer.c @@ -31,20 +31,22 @@ static void decompress(LZ4F_dctx* dctx, void* dst, size_t dstCapacity, int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); - size_t const dstCapacity = FUZZ_dataProducer_uint32( - producer, 0, 4 * size); + size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size_t const dictSizeSeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const dstCapacity = FUZZ_getRange_from_uint32( + dstCapacitySeed, 0, 4 * size); size_t const largeDictSize = 64 * 1024; - size_t const dictSize = FUZZ_dataProducer_uint32( - producer, 0, largeDictSize); + size_t const dictSize = FUZZ_getRange_from_uint32( + dictSizeSeed, 0, largeDictSize); + char* const dst = (char*)malloc(dstCapacity); char* const dict = (char*)malloc(dictSize); LZ4F_decompressOptions_t opts; LZ4F_dctx* dctx; LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION); - /* Restrict to remaining data from producer */ - size = FUZZ_dataProducer_remainingBytes(producer); - FUZZ_ASSERT(dctx); FUZZ_ASSERT(dst); FUZZ_ASSERT(dict); diff --git a/ossfuzz/decompress_fuzzer.c b/ossfuzz/decompress_fuzzer.c index bc4190b..6f48e30 100644 --- a/ossfuzz/decompress_fuzzer.c +++ b/ossfuzz/decompress_fuzzer.c @@ -15,8 +15,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); - size_t const dstCapacity = FUZZ_dataProducer_uint32( - producer, 0, 4 * size); + size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const dstCapacity = FUZZ_getRange_from_uint32(dstCapacitySeed, 0, 4 * size); size_t const smallDictSize = size + 1; size_t const largeDictSize = 64 * 1024 - 1; size_t const dictSize = MAX(smallDictSize, largeDictSize); @@ -26,9 +28,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) char* const dataAfterDict = dict + dictSize; char* const smallDict = dataAfterDict - smallDictSize; - /* Restrict to remaining data from producer */ - size = FUZZ_dataProducer_remainingBytes(producer); - FUZZ_ASSERT(dst); FUZZ_ASSERT(dict); diff --git a/ossfuzz/fuzz_data_producer.c b/ossfuzz/fuzz_data_producer.c index 992f5a7..cc06958 100644 --- a/ossfuzz/fuzz_data_producer.c +++ b/ossfuzz/fuzz_data_producer.c @@ -17,26 +17,59 @@ FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer) { free(producer); } -uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer, uint32_t min, - uint32_t max) { - FUZZ_ASSERT(min <= max); - - uint32_t range = max - min; - uint32_t rolling = range; - uint32_t result = 0; - - while (rolling > 0 && producer->size > 0) { - uint8_t next = *(producer->data + producer->size - 1); - producer->size -= 1; - result = (result << 8) | next; - rolling >>= 8; - } - - if (range == 0xffffffff) { - return result; - } - - return min + result % (range + 1); +uint32_t FUZZ_dataProducer_retrieve32(FUZZ_dataProducer_t *producer) { + const uint8_t* data = producer->data; + const size_t size = producer->size; + if (size == 0) { + return 0; + } else if (size < 4) { + producer->size -= 1; + return (uint32_t)data[size - 1]; + } else { + producer->size -= 4; + return *(data + size - 4); + } +} + +uint32_t FUZZ_getRange_from_uint32(uint32_t seed, uint32_t min, uint32_t max) +{ + uint32_t range = max - min; + if (range == 0xffffffff) { + return seed; + } + return min + seed % (range + 1); +} + +uint32_t FUZZ_dataProducer_range32(FUZZ_dataProducer_t* producer, + uint32_t min, uint32_t max) +{ + size_t const seed = FUZZ_dataProducer_retrieve32(producer); + return FUZZ_getRange_from_uint32(seed, min, max); +} + +LZ4F_frameInfo_t FUZZ_dataProducer_frameInfo(FUZZ_dataProducer_t* producer) +{ + LZ4F_frameInfo_t info = LZ4F_INIT_FRAMEINFO; + info.blockSizeID = FUZZ_dataProducer_range32(producer, LZ4F_max64KB - 1, LZ4F_max4MB); + if (info.blockSizeID < LZ4F_max64KB) { + info.blockSizeID = LZ4F_default; + } + info.blockMode = FUZZ_dataProducer_range32(producer, LZ4F_blockLinked, LZ4F_blockIndependent); + info.contentChecksumFlag = FUZZ_dataProducer_range32(producer, LZ4F_noContentChecksum, + LZ4F_contentChecksumEnabled); + info.blockChecksumFlag = FUZZ_dataProducer_range32(producer, LZ4F_noBlockChecksum, + LZ4F_blockChecksumEnabled); + return info; +} + +LZ4F_preferences_t FUZZ_dataProducer_preferences(FUZZ_dataProducer_t* producer) +{ + LZ4F_preferences_t prefs = LZ4F_INIT_PREFERENCES; + prefs.frameInfo = FUZZ_dataProducer_frameInfo(producer); + prefs.compressionLevel = FUZZ_dataProducer_range32(producer, 0, LZ4HC_CLEVEL_MAX + 3) - 3; + prefs.autoFlush = FUZZ_dataProducer_range32(producer, 0, 1); + prefs.favorDecSpeed = FUZZ_dataProducer_range32(producer, 0, 1); + return prefs; } size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){ diff --git a/ossfuzz/fuzz_data_producer.h b/ossfuzz/fuzz_data_producer.h index 8df5257..b96dcba 100644 --- a/ossfuzz/fuzz_data_producer.h +++ b/ossfuzz/fuzz_data_producer.h @@ -4,6 +4,8 @@ #include <stdlib.h> #include "fuzz_helpers.h" +#include "lz4frame.h" +#include "lz4hc.h" /* Struct used for maintaining the state of the data */ typedef struct FUZZ_dataProducer_s FUZZ_dataProducer_t; @@ -14,9 +16,21 @@ FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size); /* Frees the data producer */ void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer); +/* Returns 32 bits from the end of data */ +uint32_t FUZZ_dataProducer_retrieve32(FUZZ_dataProducer_t *producer); + /* Returns value between [min, max] */ -uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer, uint32_t min, +uint32_t FUZZ_getRange_from_uint32(uint32_t seed, uint32_t min, uint32_t max); + +/* Combination of above two functions for non adaptive use cases. ie where size is not involved */ +uint32_t FUZZ_dataProducer_range32(FUZZ_dataProducer_t *producer, uint32_t min, uint32_t max); +/* Returns lz4 preferences */ +LZ4F_preferences_t FUZZ_dataProducer_preferences(FUZZ_dataProducer_t* producer); + +/* Returns lz4 frame info */ +LZ4F_frameInfo_t FUZZ_dataProducer_frameInfo(FUZZ_dataProducer_t* producer); + /* Returns the size of the remaining bytes of data in the producer */ size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer); diff --git a/ossfuzz/round_trip_frame_fuzzer.c b/ossfuzz/round_trip_frame_fuzzer.c index 1eea90c..149542d 100644 --- a/ossfuzz/round_trip_frame_fuzzer.c +++ b/ossfuzz/round_trip_frame_fuzzer.c @@ -12,14 +12,17 @@ #include "lz4.h" #include "lz4frame.h" #include "lz4_helpers.h" +#include "fuzz_data_producer.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - uint32_t seed = FUZZ_seed(&data, &size); - LZ4F_preferences_t const prefs = FUZZ_randomPreferences(&seed); - size_t const dstCapacity = LZ4F_compressFrameBound(size, &prefs); + FUZZ_dataProducer_t* producer = FUZZ_dataProducer_create(data, size); + LZ4F_preferences_t const prefs = FUZZ_dataProducer_preferences(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const dstCapacity = LZ4F_compressFrameBound(LZ4_compressBound(size), &prefs); char* const dst = (char*)malloc(dstCapacity); - char* const rt = (char*)malloc(size); + char* const rt = (char*)malloc(FUZZ_dataProducer_remainingBytes(producer)); FUZZ_ASSERT(dst); FUZZ_ASSERT(rt); @@ -34,6 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) free(dst); free(rt); + FUZZ_dataProducer_free(producer); return 0; } diff --git a/ossfuzz/round_trip_fuzzer.c b/ossfuzz/round_trip_fuzzer.c index 3a66e80..6307058 100644 --- a/ossfuzz/round_trip_fuzzer.c +++ b/ossfuzz/round_trip_fuzzer.c @@ -10,11 +10,17 @@ #include "fuzz_helpers.h" #include "lz4.h" +#include "fuzz_data_producer.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - uint32_t seed = FUZZ_seed(&data, &size); + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); + size_t const partialCapacitySeed = FUZZ_dataProducer_retrieve32(producer); + size = FUZZ_dataProducer_remainingBytes(producer); + + size_t const partialCapacity = FUZZ_getRange_from_uint32(partialCapacitySeed, 0, size); size_t const dstCapacity = LZ4_compressBound(size); + char* const dst = (char*)malloc(dstCapacity); char* const rt = (char*)malloc(size); @@ -32,7 +38,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) /* Partial decompression must succeed. */ { - size_t const partialCapacity = FUZZ_rand32(&seed, 0, size); char* const partial = (char*)malloc(partialCapacity); FUZZ_ASSERT(partial); int const partialSize = LZ4_decompress_safe_partial( @@ -43,8 +48,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) free(partial); } + free(dst); free(rt); + FUZZ_dataProducer_free(producer); return 0; } diff --git a/ossfuzz/round_trip_hc_fuzzer.c b/ossfuzz/round_trip_hc_fuzzer.c index 8406809..7d03ee2 100644 --- a/ossfuzz/round_trip_hc_fuzzer.c +++ b/ossfuzz/round_trip_hc_fuzzer.c @@ -16,14 +16,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); + int const level = FUZZ_dataProducer_range32(producer, + LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX); + size = FUZZ_dataProducer_remainingBytes(producer); + size_t const dstCapacity = LZ4_compressBound(size); char* const dst = (char*)malloc(dstCapacity); char* const rt = (char*)malloc(size); - int const level = FUZZ_dataProducer_uint32( - producer, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX); - - /* Restrict to remaining data from producer */ - size = FUZZ_dataProducer_remainingBytes(producer); FUZZ_ASSERT(dst); FUZZ_ASSERT(rt); diff --git a/programs/platform.h b/programs/platform.h index c0b3840..7e2cb58 100644 --- a/programs/platform.h +++ b/programs/platform.h @@ -86,7 +86,7 @@ extern "C" { # else # if defined(__linux__) || defined(__linux) # ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L /* use feature test macro */ +# define _POSIX_C_SOURCE 200809L /* use feature test macro */ # endif # endif # include <unistd.h> /* declares _POSIX_VERSION */ diff --git a/programs/util.h b/programs/util.h index 1dd515c..8e361ca 100644 --- a/programs/util.h +++ b/programs/util.h @@ -37,12 +37,17 @@ extern "C" { #include <assert.h> #include <sys/types.h> /* stat, utime */ #include <sys/stat.h> /* stat */ -#if defined(_MSC_VER) +#if defined(_WIN32) # include <sys/utime.h> /* utime */ # include <io.h> /* _chmod */ #else # include <unistd.h> /* chown, stat */ +# if PLATFORM_POSIX_VERSION < 200809L # include <utime.h> /* utime */ +# else +# include <fcntl.h> /* AT_FDCWD */ +# include <sys/stat.h> /* for utimensat */ +# endif #endif #include <time.h> /* time */ #include <limits.h> /* INT_MAX */ @@ -287,14 +292,23 @@ UTIL_STATIC int UTIL_isRegFile(const char* infilename); UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf) { int res = 0; - struct utimbuf timebuf; if (!UTIL_isRegFile(filename)) return -1; - timebuf.actime = time(NULL); - timebuf.modtime = statbuf->st_mtime; - res += utime(filename, &timebuf); /* set access and modification times */ + { +#if defined(_WIN32) || (PLATFORM_POSIX_VERSION < 200809L) + struct utimbuf timebuf; + timebuf.actime = time(NULL); + timebuf.modtime = statbuf->st_mtime; + res += utime(filename, &timebuf); /* set access and modification times */ +#else + struct timespec timebuf[2] = {}; + timebuf[0].tv_nsec = UTIME_NOW; + timebuf[1].tv_sec = statbuf->st_mtime; + res += utimensat(AT_FDCWD, filename, timebuf, 0); /* set access and modification times */ +#endif + } #if !defined(_WIN32) res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ |