summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/meson/meson.build114
-rw-r--r--contrib/meson/meson/GetLz4LibraryVersion.py (renamed from contrib/meson/GetLz4LibraryVersion.py)0
-rw-r--r--contrib/meson/meson/InstallSymlink.py (renamed from contrib/meson/InstallSymlink.py)0
-rw-r--r--contrib/meson/meson/contrib/gen_manual/meson.build (renamed from contrib/meson/contrib/gen_manual/meson.build)2
-rw-r--r--contrib/meson/meson/contrib/meson.build (renamed from contrib/meson/contrib/meson.build)0
-rw-r--r--contrib/meson/meson/examples/meson.build (renamed from contrib/meson/examples/meson.build)2
-rw-r--r--contrib/meson/meson/lib/meson.build (renamed from contrib/meson/lib/meson.build)2
-rw-r--r--contrib/meson/meson/meson.build118
-rw-r--r--contrib/meson/meson/programs/meson.build (renamed from contrib/meson/programs/meson.build)2
-rw-r--r--contrib/meson/meson/tests/meson.build (renamed from contrib/meson/tests/meson.build)2
-rw-r--r--examples/frameCompress.c4
-rw-r--r--lib/lz4.c8
-rw-r--r--ossfuzz/compress_frame_fuzzer.c12
-rw-r--r--ossfuzz/compress_fuzzer.c11
-rw-r--r--ossfuzz/compress_hc_fuzzer.c14
-rw-r--r--ossfuzz/decompress_frame_fuzzer.c16
-rw-r--r--ossfuzz/decompress_fuzzer.c9
-rw-r--r--ossfuzz/fuzz_data_producer.c73
-rw-r--r--ossfuzz/fuzz_data_producer.h16
-rw-r--r--ossfuzz/round_trip_frame_fuzzer.c12
-rw-r--r--ossfuzz/round_trip_fuzzer.c11
-rw-r--r--ossfuzz/round_trip_hc_fuzzer.c9
-rw-r--r--programs/platform.h2
-rw-r--r--programs/util.h24
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);
}
}
diff --git a/lib/lz4.c b/lib/lz4.c
index 9808d70..85c3322 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -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 */