extzstd 0.3.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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
  {