Skip to content

Commit 1661755

Browse files
authored
Merge pull request #2213 from mgreter/bugfix/ctx-options-leak
Fix some minor memory leaks with context options
2 parents 7065502 + 716255b commit 1661755

File tree

5 files changed

+68
-21
lines changed

5 files changed

+68
-21
lines changed

docs/api-context.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ int sass_compiler_execute (struct Sass_Compiler* compiler);
174174
// Release all memory allocated with the compiler
175175
// This does _not_ include any contexts or options
176176
void sass_delete_compiler (struct Sass_Compiler* compiler);
177+
void sass_delete_options(struct Sass_Options* options);
177178

178179
// Release all memory allocated and also ourself
179180
void sass_delete_file_context (struct Sass_File_Context* ctx);

include/sass/context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);
5050
// Release all memory allocated with the compiler
5151
// This does _not_ include any contexts or options
5252
ADDAPI void ADDCALL sass_delete_compiler(struct Sass_Compiler* compiler);
53+
ADDAPI void ADDCALL sass_delete_options(struct Sass_Options* options);
5354

5455
// Release all memory allocated and also ourself
5556
ADDAPI void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx);

src/expand.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ namespace Sass {
141141
}
142142

143143
selector_stack.push_back(sel);
144-
Env* env = 0;
144+
Env env(environment());
145145
if (block_stack.back()->is_root()) {
146-
env = new Env(environment());
147-
env_stack.push_back(env);
146+
env_stack.push_back(&env);
148147
}
149148
sel->set_media_block(media_block_stack.back());
150149
Block* blk = r->block()->perform(this)->block();
@@ -155,8 +154,8 @@ namespace Sass {
155154
selector_stack.pop_back();
156155
if (block_stack.back()->is_root()) {
157156
env_stack.pop_back();
158-
delete env;
159157
}
158+
160159
rr->is_root(r->is_root());
161160
rr->tabs(r->tabs());
162161

src/json.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,13 @@ char *json_encode_string(const char *str)
399399
SB sb;
400400
sb_init(&sb);
401401

402-
emit_string(&sb, str);
402+
try {
403+
emit_string(&sb, str);
404+
}
405+
catch (std::exception &e) {
406+
sb_free(&sb);
407+
throw;
408+
}
403409

404410
return sb_finish(&sb);
405411
}
@@ -409,10 +415,16 @@ char *json_stringify(const JsonNode *node, const char *space)
409415
SB sb;
410416
sb_init(&sb);
411417

412-
if (space != NULL)
413-
emit_value_indented(&sb, node, space, 0);
414-
else
415-
emit_value(&sb, node);
418+
try {
419+
if (space != NULL)
420+
emit_value_indented(&sb, node, space, 0);
421+
else
422+
emit_value(&sb, node);
423+
}
424+
catch (std::exception &e) {
425+
sb_free(&sb);
426+
throw;
427+
}
416428

417429
return sb_finish(&sb);
418430
}

src/sass_context.cpp

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,16 @@ namespace Sass {
3131
extern "C" {
3232
using namespace Sass;
3333

34-
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) { *to = *from; }
34+
static void sass_clear_options (struct Sass_Options* options);
35+
static void sass_reset_options (struct Sass_Options* options);
36+
static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {
37+
// free assigned memory
38+
sass_clear_options(to);
39+
// move memory
40+
*to = *from;
41+
// Reset pointers on source
42+
sass_reset_options(from);
43+
}
3544

3645
#define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \
3746
type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \
@@ -475,6 +484,24 @@ extern "C" {
475484
return 0;
476485
}
477486

487+
// helper function, not exported, only accessible locally
488+
static void sass_reset_options (struct Sass_Options* options)
489+
{
490+
// free pointer before
491+
// or copy/move them
492+
options->input_path = 0;
493+
options->output_path = 0;
494+
options->plugin_path = 0;
495+
options->include_path = 0;
496+
options->source_map_file = 0;
497+
options->source_map_root = 0;
498+
options->c_functions = 0;
499+
options->c_importers = 0;
500+
options->c_headers = 0;
501+
options->plugin_paths = 0;
502+
options->include_paths = 0;
503+
}
504+
478505
// helper function, not exported, only accessible locally
479506
static void sass_clear_options (struct Sass_Options* options)
480507
{
@@ -527,12 +554,25 @@ extern "C" {
527554
cur = next;
528555
}
529556
}
557+
// Free options strings
558+
free(options->input_path);
559+
free(options->output_path);
560+
free(options->plugin_path);
561+
free(options->include_path);
562+
free(options->source_map_file);
563+
free(options->source_map_root);
530564
// Free custom functions
531565
free(options->c_functions);
532566
// Free custom importers
533567
free(options->c_importers);
534568
free(options->c_headers);
535569
// Reset our pointers
570+
options->input_path = 0;
571+
options->output_path = 0;
572+
options->plugin_path = 0;
573+
options->include_path = 0;
574+
options->source_map_file = 0;
575+
options->source_map_root = 0;
536576
options->c_functions = 0;
537577
options->c_importers = 0;
538578
options->c_headers = 0;
@@ -552,12 +592,6 @@ extern "C" {
552592
if (ctx->error_text) free(ctx->error_text);
553593
if (ctx->error_json) free(ctx->error_json);
554594
if (ctx->error_file) free(ctx->error_file);
555-
if (ctx->input_path) free(ctx->input_path);
556-
if (ctx->output_path) free(ctx->output_path);
557-
if (ctx->plugin_path) free(ctx->plugin_path);
558-
if (ctx->include_path) free(ctx->include_path);
559-
if (ctx->source_map_file) free(ctx->source_map_file);
560-
if (ctx->source_map_root) free(ctx->source_map_root);
561595
free_string_array(ctx->included_files);
562596
// play safe and reset properties
563597
ctx->output_string = 0;
@@ -566,11 +600,6 @@ extern "C" {
566600
ctx->error_text = 0;
567601
ctx->error_json = 0;
568602
ctx->error_file = 0;
569-
ctx->input_path = 0;
570-
ctx->output_path = 0;
571-
ctx->include_path = 0;
572-
ctx->source_map_file = 0;
573-
ctx->source_map_root = 0;
574603
ctx->included_files = 0;
575604
// now clear the options
576605
sass_clear_options(ctx);
@@ -587,6 +616,11 @@ extern "C" {
587616
free(compiler);
588617
}
589618

619+
void ADDCALL sass_delete_options (struct Sass_Options* options)
620+
{
621+
sass_clear_options(options); free(options);
622+
}
623+
590624
// Deallocate all associated memory with file context
591625
void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx)
592626
{

0 commit comments

Comments
 (0)