Skip to content

Commit 31a16ad

Browse files
committed
Fix memory leak in compression level with non-Integer
This PR fixes a memory leak when an invalid level option is passed to Zstd.compress. If non-Integer object was given as compression level, NUM2INT cause a TypeError exception and memory leak. This changes will release the context if necessary and raise an exception if non-Integer object was given as compression level.
1 parent 8ae07a1 commit 31a16ad

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

ext/zstdruby/common.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@
1010

1111
extern VALUE rb_cCDict, rb_cDDict;
1212

13-
static int convert_compression_level(VALUE compression_level_value)
13+
static int convert_compression_level(ZSTD_CCtx* ctx, VALUE compression_level_value)
1414
{
1515
if (NIL_P(compression_level_value)) {
1616
return ZSTD_CLEVEL_DEFAULT;
1717
}
18+
if (!RB_INTEGER_TYPE_P(compression_level_value)) {
19+
if (ctx) {
20+
ZSTD_freeCCtx(ctx);
21+
}
22+
rb_raise(rb_eTypeError, "compression level must be an Integer");
23+
}
1824
return NUM2INT(compression_level_value);
1925
}
2026

@@ -28,7 +34,7 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE kwargs)
2834

2935
int compression_level = ZSTD_CLEVEL_DEFAULT;
3036
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
31-
compression_level = convert_compression_level(kwargs_values[0]);
37+
compression_level = convert_compression_level(ctx, kwargs_values[0]);
3238
}
3339
ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
3440

ext/zstdruby/zstdruby.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static VALUE rb_cdict_initialize(int argc, VALUE *argv, VALUE self)
169169
VALUE dict;
170170
VALUE compression_level_value;
171171
rb_scan_args(argc, argv, "11", &dict, &compression_level_value);
172-
int compression_level = convert_compression_level(compression_level_value);
172+
int compression_level = convert_compression_level(NULL, compression_level_value);
173173

174174
StringValue(dict);
175175
char* dict_buffer = RSTRING_PTR(dict);

0 commit comments

Comments
 (0)