extzstd 0.3.3 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/contrib/zstd/CHANGELOG +39 -2
  4. data/contrib/zstd/CONTRIBUTING.md +3 -3
  5. data/contrib/zstd/Makefile +34 -20
  6. data/contrib/zstd/README.md +6 -2
  7. data/contrib/zstd/SECURITY.md +15 -0
  8. data/contrib/zstd/lib/Makefile +40 -28
  9. data/contrib/zstd/lib/README.md +14 -1
  10. data/contrib/zstd/lib/common/allocations.h +1 -1
  11. data/contrib/zstd/lib/common/bitstream.h +49 -29
  12. data/contrib/zstd/lib/common/compiler.h +114 -22
  13. data/contrib/zstd/lib/common/cpu.h +36 -0
  14. data/contrib/zstd/lib/common/debug.c +6 -0
  15. data/contrib/zstd/lib/common/debug.h +20 -11
  16. data/contrib/zstd/lib/common/error_private.h +45 -36
  17. data/contrib/zstd/lib/common/fse.h +3 -2
  18. data/contrib/zstd/lib/common/fse_decompress.c +19 -17
  19. data/contrib/zstd/lib/common/huf.h +14 -1
  20. data/contrib/zstd/lib/common/mem.h +0 -9
  21. data/contrib/zstd/lib/common/pool.c +1 -1
  22. data/contrib/zstd/lib/common/pool.h +1 -1
  23. data/contrib/zstd/lib/common/portability_macros.h +2 -0
  24. data/contrib/zstd/lib/common/threading.c +8 -2
  25. data/contrib/zstd/lib/common/xxhash.c +5 -11
  26. data/contrib/zstd/lib/common/xxhash.h +2341 -1007
  27. data/contrib/zstd/lib/common/zstd_internal.h +5 -5
  28. data/contrib/zstd/lib/compress/fse_compress.c +8 -7
  29. data/contrib/zstd/lib/compress/huf_compress.c +54 -25
  30. data/contrib/zstd/lib/compress/zstd_compress.c +282 -161
  31. data/contrib/zstd/lib/compress/zstd_compress_internal.h +29 -27
  32. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +224 -113
  33. data/contrib/zstd/lib/compress/zstd_cwksp.h +19 -13
  34. data/contrib/zstd/lib/compress/zstd_double_fast.c +17 -5
  35. data/contrib/zstd/lib/compress/zstd_double_fast.h +11 -0
  36. data/contrib/zstd/lib/compress/zstd_fast.c +14 -6
  37. data/contrib/zstd/lib/compress/zstd_lazy.c +129 -87
  38. data/contrib/zstd/lib/compress/zstd_lazy.h +103 -28
  39. data/contrib/zstd/lib/compress/zstd_ldm.c +8 -2
  40. data/contrib/zstd/lib/compress/zstd_opt.c +216 -112
  41. data/contrib/zstd/lib/compress/zstd_opt.h +31 -7
  42. data/contrib/zstd/lib/compress/zstdmt_compress.c +94 -79
  43. data/contrib/zstd/lib/decompress/huf_decompress.c +188 -126
  44. data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +38 -19
  45. data/contrib/zstd/lib/decompress/zstd_decompress.c +84 -32
  46. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +231 -208
  47. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +1 -1
  48. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +2 -0
  49. data/contrib/zstd/lib/dictBuilder/cover.c +16 -12
  50. data/contrib/zstd/lib/dictBuilder/cover.h +2 -8
  51. data/contrib/zstd/lib/dictBuilder/fastcover.c +2 -2
  52. data/contrib/zstd/lib/dictBuilder/zdict.c +12 -6
  53. data/contrib/zstd/lib/legacy/zstd_legacy.h +30 -0
  54. data/contrib/zstd/lib/legacy/zstd_v01.c +2 -0
  55. data/contrib/zstd/lib/legacy/zstd_v02.c +4 -16
  56. data/contrib/zstd/lib/legacy/zstd_v03.c +4 -16
  57. data/contrib/zstd/lib/legacy/zstd_v04.c +4 -11
  58. data/contrib/zstd/lib/legacy/zstd_v05.c +1 -0
  59. data/contrib/zstd/lib/legacy/zstd_v06.c +2 -9
  60. data/contrib/zstd/lib/legacy/zstd_v07.c +2 -10
  61. data/contrib/zstd/lib/libzstd.mk +34 -11
  62. data/contrib/zstd/lib/zstd.h +129 -60
  63. data/ext/extconf.rb +19 -1
  64. data/ext/extzstd.c +38 -14
  65. data/ext/extzstd.h +33 -6
  66. data/ext/extzstd_stream.c +74 -31
  67. metadata +4 -5
  68. data/contrib/zstd/appveyor.yml +0 -205
  69. data/ext/depend +0 -2
@@ -11,6 +11,8 @@
11
11
  #ifndef ZSTD_COMPILER_H
12
12
  #define ZSTD_COMPILER_H
13
13
 
14
+ #include <stddef.h>
15
+
14
16
  #include "portability_macros.h"
15
17
 
16
18
  /*-*******************************************************
@@ -51,12 +53,19 @@
51
53
  # define WIN_CDECL
52
54
  #endif
53
55
 
56
+ /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
57
+ #if defined(__GNUC__)
58
+ # define UNUSED_ATTR __attribute__((unused))
59
+ #else
60
+ # define UNUSED_ATTR
61
+ #endif
62
+
54
63
  /**
55
64
  * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
56
65
  * parameters. They must be inlined for the compiler to eliminate the constant
57
66
  * branches.
58
67
  */
59
- #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
68
+ #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR
60
69
  /**
61
70
  * HINT_INLINE is used to help the compiler generate better code. It is *not*
62
71
  * used for "templates", so it can be tweaked based on the compilers
@@ -71,14 +80,28 @@
71
80
  #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
72
81
  # define HINT_INLINE static INLINE_KEYWORD
73
82
  #else
74
- # define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
83
+ # define HINT_INLINE FORCE_INLINE_TEMPLATE
75
84
  #endif
76
85
 
77
- /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
86
+ /* "soft" inline :
87
+ * The compiler is free to select if it's a good idea to inline or not.
88
+ * The main objective is to silence compiler warnings
89
+ * when a defined function in included but not used.
90
+ *
91
+ * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit.
92
+ * Updating the prefix is probably preferable, but requires a fairly large codemod,
93
+ * since this name is used everywhere.
94
+ */
95
+ #ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */
78
96
  #if defined(__GNUC__)
79
- # define UNUSED_ATTR __attribute__((unused))
97
+ # define MEM_STATIC static __inline UNUSED_ATTR
98
+ #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
99
+ # define MEM_STATIC static inline
100
+ #elif defined(_MSC_VER)
101
+ # define MEM_STATIC static __inline
80
102
  #else
81
- # define UNUSED_ATTR
103
+ # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
104
+ #endif
82
105
  #endif
83
106
 
84
107
  /* force no inlining */
@@ -109,10 +132,10 @@
109
132
  /* prefetch
110
133
  * can be disabled, by declaring NO_PREFETCH build macro */
111
134
  #if defined(NO_PREFETCH)
112
- # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
113
- # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
135
+ # define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
136
+ # define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
114
137
  #else
115
- # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
138
+ # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */
116
139
  # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
117
140
  # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
118
141
  # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
@@ -120,24 +143,25 @@
120
143
  # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
121
144
  # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
122
145
  # elif defined(__aarch64__)
123
- # define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
124
- # define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
146
+ # define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0)
147
+ # define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0)
125
148
  # else
126
- # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
127
- # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
149
+ # define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
150
+ # define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
128
151
  # endif
129
152
  #endif /* NO_PREFETCH */
130
153
 
131
154
  #define CACHELINE_SIZE 64
132
155
 
133
- #define PREFETCH_AREA(p, s) { \
134
- const char* const _ptr = (const char*)(p); \
135
- size_t const _size = (size_t)(s); \
136
- size_t _pos; \
137
- for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
138
- PREFETCH_L2(_ptr + _pos); \
139
- } \
140
- }
156
+ #define PREFETCH_AREA(p, s) \
157
+ do { \
158
+ const char* const _ptr = (const char*)(p); \
159
+ size_t const _size = (size_t)(s); \
160
+ size_t _pos; \
161
+ for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
162
+ PREFETCH_L2(_ptr + _pos); \
163
+ } \
164
+ } while (0)
141
165
 
142
166
  /* vectorization
143
167
  * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
@@ -166,9 +190,9 @@
166
190
  #endif
167
191
 
168
192
  #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
169
- # define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
193
+ # define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0)
170
194
  #else
171
- # define ZSTD_UNREACHABLE { assert(0); }
195
+ # define ZSTD_UNREACHABLE do { assert(0); } while (0)
172
196
  #endif
173
197
 
174
198
  /* disable warnings */
@@ -281,6 +305,74 @@
281
305
  * Sanitizer
282
306
  *****************************************************************/
283
307
 
308
+ /**
309
+ * Zstd relies on pointer overflow in its decompressor.
310
+ * We add this attribute to functions that rely on pointer overflow.
311
+ */
312
+ #ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
313
+ # if __has_attribute(no_sanitize)
314
+ # if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
315
+ /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */
316
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow")))
317
+ # else
318
+ /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */
319
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow")))
320
+ # endif
321
+ # else
322
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
323
+ # endif
324
+ #endif
325
+
326
+ /**
327
+ * Helper function to perform a wrapped pointer difference without trigging
328
+ * UBSAN.
329
+ *
330
+ * @returns lhs - rhs with wrapping
331
+ */
332
+ MEM_STATIC
333
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
334
+ ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs)
335
+ {
336
+ return lhs - rhs;
337
+ }
338
+
339
+ /**
340
+ * Helper function to perform a wrapped pointer add without triggering UBSAN.
341
+ *
342
+ * @return ptr + add with wrapping
343
+ */
344
+ MEM_STATIC
345
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
346
+ unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
347
+ {
348
+ return ptr + add;
349
+ }
350
+
351
+ /**
352
+ * Helper function to perform a wrapped pointer subtraction without triggering
353
+ * UBSAN.
354
+ *
355
+ * @return ptr - sub with wrapping
356
+ */
357
+ MEM_STATIC
358
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
359
+ unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub)
360
+ {
361
+ return ptr - sub;
362
+ }
363
+
364
+ /**
365
+ * Helper function to add to a pointer that works around C's undefined behavior
366
+ * of adding 0 to NULL.
367
+ *
368
+ * @returns `ptr + add` except it defines `NULL + 0 == NULL`.
369
+ */
370
+ MEM_STATIC
371
+ unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add)
372
+ {
373
+ return add > 0 ? ptr + add : ptr;
374
+ }
375
+
284
376
  /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
285
377
  * abundance of caution, disable our custom poisoning on mingw. */
286
378
  #ifdef __MINGW32__
@@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
35
35
  U32 f7b = 0;
36
36
  U32 f7c = 0;
37
37
  #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
38
+ #if !defined(__clang__)
38
39
  int reg[4];
39
40
  __cpuid((int*)reg, 0);
40
41
  {
@@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
50
51
  f7c = (U32)reg[2];
51
52
  }
52
53
  }
54
+ #else
55
+ /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in
56
+ * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs
57
+ * to due to being a reserved register. So in that case, do the `cpuid`
58
+ * ourselves. Clang supports inline assembly anyway.
59
+ */
60
+ U32 n;
61
+ __asm__(
62
+ "pushq %%rbx\n\t"
63
+ "cpuid\n\t"
64
+ "popq %%rbx\n\t"
65
+ : "=a"(n)
66
+ : "a"(0)
67
+ : "rcx", "rdx");
68
+ if (n >= 1) {
69
+ U32 f1a;
70
+ __asm__(
71
+ "pushq %%rbx\n\t"
72
+ "cpuid\n\t"
73
+ "popq %%rbx\n\t"
74
+ : "=a"(f1a), "=c"(f1c), "=d"(f1d)
75
+ : "a"(1)
76
+ :);
77
+ }
78
+ if (n >= 7) {
79
+ __asm__(
80
+ "pushq %%rbx\n\t"
81
+ "cpuid\n\t"
82
+ "movq %%rbx, %%rax\n\t"
83
+ "popq %%rbx"
84
+ : "=a"(f7b), "=c"(f7c)
85
+ : "a"(7), "c"(0)
86
+ : "rdx");
87
+ }
88
+ #endif
53
89
  #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
54
90
  /* The following block like the normal cpuid branch below, but gcc
55
91
  * reserves ebx for use of its pic register so we must specially
@@ -21,4 +21,10 @@
21
21
 
22
22
  #include "debug.h"
23
23
 
24
+ #if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2)
25
+ /* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a
26
+ * translation unit is empty. So remove this from Linux kernel builds, but
27
+ * otherwise just leave it in.
28
+ */
24
29
  int g_debuglevel = DEBUGLEVEL;
30
+ #endif
@@ -85,18 +85,27 @@ extern int g_debuglevel; /* the variable is only declared,
85
85
  It's useful when enabling very verbose levels
86
86
  on selective conditions (such as position in src) */
87
87
 
88
- # define RAWLOG(l, ...) { \
89
- if (l<=g_debuglevel) { \
90
- ZSTD_DEBUG_PRINT(__VA_ARGS__); \
91
- } }
92
- # define DEBUGLOG(l, ...) { \
93
- if (l<=g_debuglevel) { \
94
- ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \
95
- ZSTD_DEBUG_PRINT(" \n"); \
96
- } }
88
+ # define RAWLOG(l, ...) \
89
+ do { \
90
+ if (l<=g_debuglevel) { \
91
+ ZSTD_DEBUG_PRINT(__VA_ARGS__); \
92
+ } \
93
+ } while (0)
94
+
95
+ #define STRINGIFY(x) #x
96
+ #define TOSTRING(x) STRINGIFY(x)
97
+ #define LINE_AS_STRING TOSTRING(__LINE__)
98
+
99
+ # define DEBUGLOG(l, ...) \
100
+ do { \
101
+ if (l<=g_debuglevel) { \
102
+ ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \
103
+ ZSTD_DEBUG_PRINT(" \n"); \
104
+ } \
105
+ } while (0)
97
106
  #else
98
- # define RAWLOG(l, ...) {} /* disabled */
99
- # define DEBUGLOG(l, ...) {} /* disabled */
107
+ # define RAWLOG(l, ...) do { } while (0) /* disabled */
108
+ # define DEBUGLOG(l, ...) do { } while (0) /* disabled */
100
109
  #endif
101
110
 
102
111
 
@@ -60,8 +60,13 @@ ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
60
60
  ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
61
61
 
62
62
  /* check and forward error code */
63
- #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
64
- #define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
63
+ #define CHECK_V_F(e, f) \
64
+ size_t const e = f; \
65
+ do { \
66
+ if (ERR_isError(e)) \
67
+ return e; \
68
+ } while (0)
69
+ #define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0)
65
70
 
66
71
 
67
72
  /*-****************************************
@@ -95,10 +100,12 @@ void _force_has_format_string(const char *format, ...) {
95
100
  * We want to force this function invocation to be syntactically correct, but
96
101
  * we don't want to force runtime evaluation of its arguments.
97
102
  */
98
- #define _FORCE_HAS_FORMAT_STRING(...) \
99
- if (0) { \
100
- _force_has_format_string(__VA_ARGS__); \
101
- }
103
+ #define _FORCE_HAS_FORMAT_STRING(...) \
104
+ do { \
105
+ if (0) { \
106
+ _force_has_format_string(__VA_ARGS__); \
107
+ } \
108
+ } while (0)
102
109
 
103
110
  #define ERR_QUOTE(str) #str
104
111
 
@@ -109,48 +116,50 @@ void _force_has_format_string(const char *format, ...) {
109
116
  * In order to do that (particularly, printing the conditional that failed),
110
117
  * this can't just wrap RETURN_ERROR().
111
118
  */
112
- #define RETURN_ERROR_IF(cond, err, ...) \
113
- if (cond) { \
114
- RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
115
- __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
116
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
117
- RAWLOG(3, ": " __VA_ARGS__); \
118
- RAWLOG(3, "\n"); \
119
- return ERROR(err); \
120
- }
119
+ #define RETURN_ERROR_IF(cond, err, ...) \
120
+ do { \
121
+ if (cond) { \
122
+ RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
123
+ __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
124
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
125
+ RAWLOG(3, ": " __VA_ARGS__); \
126
+ RAWLOG(3, "\n"); \
127
+ return ERROR(err); \
128
+ } \
129
+ } while (0)
121
130
 
122
131
  /**
123
132
  * Unconditionally return the specified error.
124
133
  *
125
134
  * In debug modes, prints additional information.
126
135
  */
127
- #define RETURN_ERROR(err, ...) \
128
- do { \
129
- RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
130
- __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
131
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
132
- RAWLOG(3, ": " __VA_ARGS__); \
133
- RAWLOG(3, "\n"); \
134
- return ERROR(err); \
135
- } while(0);
136
+ #define RETURN_ERROR(err, ...) \
137
+ do { \
138
+ RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
139
+ __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
140
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
141
+ RAWLOG(3, ": " __VA_ARGS__); \
142
+ RAWLOG(3, "\n"); \
143
+ return ERROR(err); \
144
+ } while(0)
136
145
 
137
146
  /**
138
147
  * If the provided expression evaluates to an error code, returns that error code.
139
148
  *
140
149
  * In debug modes, prints additional information.
141
150
  */
142
- #define FORWARD_IF_ERROR(err, ...) \
143
- do { \
144
- size_t const err_code = (err); \
145
- if (ERR_isError(err_code)) { \
146
- RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
147
- __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
148
- _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
149
- RAWLOG(3, ": " __VA_ARGS__); \
150
- RAWLOG(3, "\n"); \
151
- return err_code; \
152
- } \
153
- } while(0);
151
+ #define FORWARD_IF_ERROR(err, ...) \
152
+ do { \
153
+ size_t const err_code = (err); \
154
+ if (ERR_isError(err_code)) { \
155
+ RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
156
+ __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
157
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
158
+ RAWLOG(3, ": " __VA_ARGS__); \
159
+ RAWLOG(3, "\n"); \
160
+ return err_code; \
161
+ } \
162
+ } while(0)
154
163
 
155
164
  #if defined (__cplusplus)
156
165
  }
@@ -229,6 +229,7 @@ If there is an error, the function will return an error code, which can be teste
229
229
 
230
230
  #endif /* FSE_H */
231
231
 
232
+
232
233
  #if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
233
234
  #define FSE_H_FSE_STATIC_LINKING_ONLY
234
235
 
@@ -464,13 +465,13 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un
464
465
  FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
465
466
  const U16* const stateTable = (const U16*)(statePtr->stateTable);
466
467
  U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
467
- BIT_addBits(bitC, statePtr->value, nbBitsOut);
468
+ BIT_addBits(bitC, (size_t)statePtr->value, nbBitsOut);
468
469
  statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
469
470
  }
470
471
 
471
472
  MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
472
473
  {
473
- BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
474
+ BIT_addBits(bitC, (size_t)statePtr->value, statePtr->stateLog);
474
475
  BIT_flushBits(bitC);
475
476
  }
476
477
 
@@ -22,8 +22,7 @@
22
22
  #define FSE_STATIC_LINKING_ONLY
23
23
  #include "fse.h"
24
24
  #include "error_private.h"
25
- #define ZSTD_DEPS_NEED_MALLOC
26
- #include "zstd_deps.h"
25
+ #include "zstd_deps.h" /* ZSTD_memcpy */
27
26
  #include "bits.h" /* ZSTD_highbit32 */
28
27
 
29
28
 
@@ -84,7 +83,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
84
83
  symbolNext[s] = 1;
85
84
  } else {
86
85
  if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
87
- symbolNext[s] = normalizedCounter[s];
86
+ symbolNext[s] = (U16)normalizedCounter[s];
88
87
  } } }
89
88
  ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
90
89
  }
@@ -99,8 +98,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
99
98
  * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
100
99
  * our buffer to handle the over-write.
101
100
  */
102
- {
103
- U64 const add = 0x0101010101010101ull;
101
+ { U64 const add = 0x0101010101010101ull;
104
102
  size_t pos = 0;
105
103
  U64 sv = 0;
106
104
  U32 s;
@@ -111,9 +109,8 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo
111
109
  for (i = 8; i < n; i += 8) {
112
110
  MEM_write64(spread + pos + i, sv);
113
111
  }
114
- pos += n;
115
- }
116
- }
112
+ pos += (size_t)n;
113
+ } }
117
114
  /* Now we spread those positions across the table.
118
115
  * The benefit of doing it in two stages is that we avoid the
119
116
  * variable size inner loop, which caused lots of branch misses.
@@ -232,12 +229,12 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
232
229
  break;
233
230
  } }
234
231
 
235
- return op-ostart;
232
+ assert(op >= ostart);
233
+ return (size_t)(op-ostart);
236
234
  }
237
235
 
238
236
  typedef struct {
239
237
  short ncount[FSE_MAX_SYMBOL_VALUE + 1];
240
- FSE_DTable dtable[1]; /* Dynamically sized */
241
238
  } FSE_DecompressWksp;
242
239
 
243
240
 
@@ -252,13 +249,18 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
252
249
  unsigned tableLog;
253
250
  unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
254
251
  FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
252
+ size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable);
253
+ FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos;
255
254
 
256
- DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
255
+ FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
257
256
  if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
258
257
 
258
+ /* correct offset to dtable depends on this property */
259
+ FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0);
260
+
259
261
  /* normal FSE decoding mode */
260
- {
261
- size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
262
+ { size_t const NCountLength =
263
+ FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
262
264
  if (FSE_isError(NCountLength)) return NCountLength;
263
265
  if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
264
266
  assert(NCountLength <= cSrcSize);
@@ -271,16 +273,16 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
271
273
  workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
272
274
  wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
273
275
 
274
- CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
276
+ CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
275
277
 
276
278
  {
277
- const void* ptr = wksp->dtable;
279
+ const void* ptr = dtable;
278
280
  const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
279
281
  const U32 fastMode = DTableH->fastMode;
280
282
 
281
283
  /* select fast mode (static) */
282
- if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1);
283
- return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0);
284
+ if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1);
285
+ return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);
284
286
  }
285
287
  }
286
288
 
@@ -197,9 +197,22 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
197
197
 
198
198
  /** HUF_getNbBitsFromCTable() :
199
199
  * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
200
- * Note 1 : is not inlined, as HUF_CElt definition is private */
200
+ * Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0
201
+ * Note 2 : is not inlined, as HUF_CElt definition is private
202
+ */
201
203
  U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue);
202
204
 
205
+ typedef struct {
206
+ BYTE tableLog;
207
+ BYTE maxSymbolValue;
208
+ BYTE unused[sizeof(size_t) - 2];
209
+ } HUF_CTableHeader;
210
+
211
+ /** HUF_readCTableHeader() :
212
+ * @returns The header from the CTable specifying the tableLog and the maxSymbolValue.
213
+ */
214
+ HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable);
215
+
203
216
  /*
204
217
  * HUF_decompress() does the following:
205
218
  * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics
@@ -31,15 +31,6 @@ extern "C" {
31
31
  # include <stdlib.h> /* _byteswap_ulong */
32
32
  # include <intrin.h> /* _byteswap_* */
33
33
  #endif
34
- #if defined(__GNUC__)
35
- # define MEM_STATIC static __inline __attribute__((unused))
36
- #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
37
- # define MEM_STATIC static inline
38
- #elif defined(_MSC_VER)
39
- # define MEM_STATIC static __inline
40
- #else
41
- # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
42
- #endif
43
34
 
44
35
  /*-**************************************************************
45
36
  * Basic Types
@@ -223,7 +223,7 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
223
223
  { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
224
224
  if (!threadPool) return 1;
225
225
  /* replace existing thread pool */
226
- ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
226
+ ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t));
227
227
  ZSTD_customFree(ctx->threads, ctx->customMem);
228
228
  ctx->threads = threadPool;
229
229
  /* Initialize additional threads */
@@ -47,7 +47,7 @@ void POOL_joinJobs(POOL_ctx* ctx);
47
47
  /*! POOL_resize() :
48
48
  * Expands or shrinks pool's number of threads.
49
49
  * This is more efficient than releasing + creating a new context,
50
- * since it tries to preserve and re-use existing threads.
50
+ * since it tries to preserve and reuse existing threads.
51
51
  * `numThreads` must be at least 1.
52
52
  * @return : 0 when resize was successful,
53
53
  * !0 (typically 1) if there is an error.
@@ -68,6 +68,8 @@
68
68
  /* Mark the internal assembly functions as hidden */
69
69
  #ifdef __ELF__
70
70
  # define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
71
+ #elif defined(__APPLE__)
72
+ # define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func
71
73
  #else
72
74
  # define ZSTD_HIDE_ASM_FUNCTION(func)
73
75
  #endif
@@ -73,10 +73,12 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
73
73
  ZSTD_thread_params_t thread_param;
74
74
  (void)unused;
75
75
 
76
+ if (thread==NULL) return -1;
77
+ *thread = NULL;
78
+
76
79
  thread_param.start_routine = start_routine;
77
80
  thread_param.arg = arg;
78
81
  thread_param.initialized = 0;
79
- *thread = NULL;
80
82
 
81
83
  /* Setup thread initialization synchronization */
82
84
  if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
@@ -91,7 +93,7 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
91
93
 
92
94
  /* Spawn thread */
93
95
  *thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
94
- if (!thread) {
96
+ if (*thread==NULL) {
95
97
  ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
96
98
  ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
97
99
  return errno;
@@ -137,6 +139,7 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread)
137
139
 
138
140
  int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
139
141
  {
142
+ assert(mutex != NULL);
140
143
  *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
141
144
  if (!*mutex)
142
145
  return 1;
@@ -145,6 +148,7 @@ int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t con
145
148
 
146
149
  int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
147
150
  {
151
+ assert(mutex != NULL);
148
152
  if (!*mutex)
149
153
  return 0;
150
154
  {
@@ -156,6 +160,7 @@ int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
156
160
 
157
161
  int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
158
162
  {
163
+ assert(cond != NULL);
159
164
  *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
160
165
  if (!*cond)
161
166
  return 1;
@@ -164,6 +169,7 @@ int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const*
164
169
 
165
170
  int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
166
171
  {
172
+ assert(cond != NULL);
167
173
  if (!*cond)
168
174
  return 0;
169
175
  {