zstd-ruby 2.0.8 → 2.0.9
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/ext/zstdruby/common.h +12 -2
- data/ext/zstdruby/extconf.rb +1 -1
- data/ext/zstdruby/streaming_compress.c +7 -1
- data/ext/zstdruby/streaming_decompress.c +7 -1
- data/ext/zstdruby/zstdruby.c +8 -0
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb07a33ae127aa325dd6ccb9aba7af6456689ff2eb41aa5e9a830b63d15df6b2
|
|
4
|
+
data.tar.gz: 4925a30a7b202f632b199d0ac43f448de4e0ac841c23be2927e863e50171ef08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0b507405b5fbe9a418553d90842f1eecacc6f73ba8a82a212d520732087153683c64bced408324754816342329b9a8bead006cdd8c5e564bd184bd64e5d47212
|
|
7
|
+
data.tar.gz: d6cb8bc02eb3e1b4d3f1a32c889f245d29ad2f84d786669934d08b498b146b37fe335e7c646fbb2d8da82142396c9bb20542695b4bbef41c0565fb9348e6cefc
|
data/.gitignore
CHANGED
data/ext/zstdruby/common.h
CHANGED
|
@@ -24,7 +24,11 @@ static int convert_compression_level(ZSTD_CCtx* ctx, VALUE compression_level_val
|
|
|
24
24
|
return NUM2INT(compression_level_value);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
/* Returns the Zstd::CDict given as `dict:`, or Qnil. ZSTD_CCtx_refCDict only
|
|
28
|
+
borrows the pointer, so a caller that keeps the ZSTD_CCtx alive beyond this
|
|
29
|
+
call has to keep the returned object reachable for just as long. A String
|
|
30
|
+
dictionary needs no such handling: ZSTD_CCtx_loadDictionary copies it. */
|
|
31
|
+
static VALUE set_compress_params(ZSTD_CCtx* const ctx, VALUE kwargs)
|
|
28
32
|
{
|
|
29
33
|
ID kwargs_keys[2];
|
|
30
34
|
kwargs_keys[0] = rb_intern("level");
|
|
@@ -46,6 +50,7 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE kwargs)
|
|
|
46
50
|
ZSTD_freeCCtx(ctx);
|
|
47
51
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_refCDict failed");
|
|
48
52
|
}
|
|
53
|
+
return kwargs_values[1];
|
|
49
54
|
} else if (TYPE(kwargs_values[1]) == T_STRING) {
|
|
50
55
|
char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
|
|
51
56
|
size_t dict_size = RSTRING_LEN(kwargs_values[1]);
|
|
@@ -59,6 +64,7 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE kwargs)
|
|
|
59
64
|
rb_raise(rb_eArgError, "`dict:` must be a Zstd::CDict or a String");
|
|
60
65
|
}
|
|
61
66
|
}
|
|
67
|
+
return Qnil;
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
struct stream_compress_params {
|
|
@@ -122,7 +128,9 @@ static size_t zstd_compress(ZSTD_CCtx* const ctx, char* output_data, size_t outp
|
|
|
122
128
|
#endif
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
|
|
131
|
+
/* Returns the Zstd::DDict given as `dict:`, or Qnil. See set_compress_params:
|
|
132
|
+
ZSTD_DCtx_refDDict borrows, ZSTD_DCtx_loadDictionary copies. */
|
|
133
|
+
static VALUE set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
|
|
126
134
|
{
|
|
127
135
|
ID kwargs_keys[1];
|
|
128
136
|
kwargs_keys[0] = rb_intern("dict");
|
|
@@ -137,6 +145,7 @@ static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
|
|
|
137
145
|
ZSTD_freeDCtx(dctx);
|
|
138
146
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_DCtx_refDDict failed");
|
|
139
147
|
}
|
|
148
|
+
return kwargs_values[0];
|
|
140
149
|
} else if (TYPE(kwargs_values[0]) == T_STRING) {
|
|
141
150
|
char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
|
|
142
151
|
size_t dict_size = RSTRING_LEN(kwargs_values[0]);
|
|
@@ -150,6 +159,7 @@ static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
|
|
|
150
159
|
rb_raise(rb_eArgError, "`dict:` must be a Zstd::DDict or a String");
|
|
151
160
|
}
|
|
152
161
|
}
|
|
162
|
+
return Qnil;
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
struct stream_decompress_params {
|
data/ext/zstdruby/extconf.rb
CHANGED
|
@@ -26,7 +26,7 @@ def ext_export_filename
|
|
|
26
26
|
name
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
$CFLAGS
|
|
29
|
+
$CFLAGS += ' -I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY -DZSTD_MULTITHREAD -pthread -DDEBUGLEVEL=0 -fvisibility=hidden -DZSTDLIB_VISIBLE=\'__attribute__((visibility("hidden")))\' -DZSTDLIB_HIDDEN=\'__attribute__((visibility("hidden")))\''
|
|
30
30
|
$CPPFLAGS += " -fdeclspec" if CONFIG['CXX'] =~ /clang/
|
|
31
31
|
|
|
32
32
|
# macOS specific: Use exported_symbols_list to control symbol visibility
|
|
@@ -5,6 +5,7 @@ struct streaming_compress_t {
|
|
|
5
5
|
VALUE buf;
|
|
6
6
|
size_t buf_size;
|
|
7
7
|
VALUE pending; /* accumulate compressed bytes produced by write() */
|
|
8
|
+
VALUE dict; /* Zstd::CDict the ctx borrows a pointer into, or Qnil */
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
static void
|
|
@@ -14,9 +15,11 @@ streaming_compress_mark(void *p)
|
|
|
14
15
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
|
15
16
|
rb_gc_mark_movable(sc->buf);
|
|
16
17
|
rb_gc_mark_movable(sc->pending);
|
|
18
|
+
rb_gc_mark_movable(sc->dict);
|
|
17
19
|
#else
|
|
18
20
|
rb_gc_mark(sc->buf);
|
|
19
21
|
rb_gc_mark(sc->pending);
|
|
22
|
+
rb_gc_mark(sc->dict);
|
|
20
23
|
#endif
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -44,6 +47,7 @@ streaming_compress_compact(void *p)
|
|
|
44
47
|
struct streaming_compress_t *sc = p;
|
|
45
48
|
sc->buf = rb_gc_location(sc->buf);
|
|
46
49
|
sc->pending = rb_gc_location(sc->pending);
|
|
50
|
+
sc->dict = rb_gc_location(sc->dict);
|
|
47
51
|
}
|
|
48
52
|
#endif
|
|
49
53
|
|
|
@@ -69,6 +73,7 @@ rb_streaming_compress_allocate(VALUE klass)
|
|
|
69
73
|
RB_OBJ_WRITE(obj, &sc->buf, Qnil);
|
|
70
74
|
sc->buf_size = 0;
|
|
71
75
|
RB_OBJ_WRITE(obj, &sc->pending, Qnil);
|
|
76
|
+
RB_OBJ_WRITE(obj, &sc->dict, Qnil);
|
|
72
77
|
return obj;
|
|
73
78
|
}
|
|
74
79
|
|
|
@@ -86,9 +91,10 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
|
86
91
|
if (ctx == NULL) {
|
|
87
92
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
|
88
93
|
}
|
|
89
|
-
set_compress_params(ctx, kwargs);
|
|
94
|
+
VALUE dict = set_compress_params(ctx, kwargs);
|
|
90
95
|
|
|
91
96
|
sc->ctx = ctx;
|
|
97
|
+
RB_OBJ_WRITE(obj, &sc->dict, dict);
|
|
92
98
|
RB_OBJ_WRITE(obj, &sc->buf, rb_str_new(NULL, buffOutSize));
|
|
93
99
|
sc->buf_size = buffOutSize;
|
|
94
100
|
RB_OBJ_WRITE(obj, &sc->pending, rb_str_new(0, 0));
|
|
@@ -4,6 +4,7 @@ struct streaming_decompress_t {
|
|
|
4
4
|
ZSTD_DCtx* dctx;
|
|
5
5
|
VALUE buf;
|
|
6
6
|
size_t buf_size;
|
|
7
|
+
VALUE dict; /* Zstd::DDict the dctx borrows a pointer into, or Qnil */
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
static void
|
|
@@ -12,8 +13,10 @@ streaming_decompress_mark(void *p)
|
|
|
12
13
|
struct streaming_decompress_t *sd = p;
|
|
13
14
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
|
14
15
|
rb_gc_mark_movable(sd->buf);
|
|
16
|
+
rb_gc_mark_movable(sd->dict);
|
|
15
17
|
#else
|
|
16
18
|
rb_gc_mark(sd->buf);
|
|
19
|
+
rb_gc_mark(sd->dict);
|
|
17
20
|
#endif
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -40,6 +43,7 @@ streaming_decompress_compact(void *p)
|
|
|
40
43
|
{
|
|
41
44
|
struct streaming_decompress_t *sd = p;
|
|
42
45
|
sd->buf = rb_gc_location(sd->buf);
|
|
46
|
+
sd->dict = rb_gc_location(sd->dict);
|
|
43
47
|
}
|
|
44
48
|
#endif
|
|
45
49
|
|
|
@@ -64,6 +68,7 @@ rb_streaming_decompress_allocate(VALUE klass)
|
|
|
64
68
|
sd->dctx = NULL;
|
|
65
69
|
RB_OBJ_WRITE(obj, &sd->buf, Qnil);
|
|
66
70
|
sd->buf_size = 0;
|
|
71
|
+
RB_OBJ_WRITE(obj, &sd->dict, Qnil);
|
|
67
72
|
return obj;
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -81,9 +86,10 @@ rb_streaming_decompress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
|
81
86
|
if (dctx == NULL) {
|
|
82
87
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx error");
|
|
83
88
|
}
|
|
84
|
-
set_decompress_params(dctx, kwargs);
|
|
89
|
+
VALUE dict = set_decompress_params(dctx, kwargs);
|
|
85
90
|
|
|
86
91
|
sd->dctx = dctx;
|
|
92
|
+
RB_OBJ_WRITE(obj, &sd->dict, dict);
|
|
87
93
|
RB_OBJ_WRITE(obj, &sd->buf, rb_str_new(NULL, buffOutSize));
|
|
88
94
|
sd->buf_size = buffOutSize;
|
|
89
95
|
|
data/ext/zstdruby/zstdruby.c
CHANGED
|
@@ -51,6 +51,7 @@ static VALUE decode_one_frame(ZSTD_DCtx* dctx, const unsigned char* src, size_t
|
|
|
51
51
|
|
|
52
52
|
for (;;) {
|
|
53
53
|
ZSTD_outBuffer o = (ZSTD_outBuffer){ buf, cap, 0 };
|
|
54
|
+
size_t const in_pos_before = in.pos;
|
|
54
55
|
size_t ret = ZSTD_decompressStream(dctx, &o, &in);
|
|
55
56
|
if (ZSTD_isError(ret)) {
|
|
56
57
|
xfree(buf);
|
|
@@ -62,6 +63,13 @@ static VALUE decode_one_frame(ZSTD_DCtx* dctx, const unsigned char* src, size_t
|
|
|
62
63
|
if (ret == 0) {
|
|
63
64
|
break;
|
|
64
65
|
}
|
|
66
|
+
/* A non-zero return is a "need more input" hint, not an error, and libzstd's
|
|
67
|
+
own noForwardProgress guard is bypassed by the early return it takes on a
|
|
68
|
+
truncated frame header -- so the stall has to be detected here. */
|
|
69
|
+
if (o.pos == 0 && in.pos == in_pos_before) {
|
|
70
|
+
xfree(buf);
|
|
71
|
+
rb_raise(rb_eRuntimeError, "ZSTD_decompressStream failed: truncated or incomplete frame");
|
|
72
|
+
}
|
|
65
73
|
}
|
|
66
74
|
xfree(buf);
|
|
67
75
|
if (consumed) {
|
data/lib/zstd-ruby/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zstd-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SpringMT
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|