Memleaks on shaping related failures
If the below patch isn't a flawed way to test this, the existing fail-cases in ass_render_event suffer from memory leaks.
Depending on the failure point I get a few kB or ~½MB of leaked memory per test file.
They can be applied individually and tested with eg ASAN:
diff --git a/libass/ass_render.c b/libass/ass_render.c
index b91bdd7..be76834 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -2657,7 +2657,8 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
resolve_base_direction(render_priv->state.font_encoding));
ass_shaper_find_runs(render_priv->shaper, render_priv, text_info->glyphs,
text_info->length);
- if (!ass_shaper_shape(render_priv->shaper, text_info)) {
+ //if (!ass_shaper_shape(render_priv->shaper, text_info)) {
+ if (true) {
ass_msg(render_priv->library, MSGL_ERR, "Failed to shape text");
free_render_context(render_priv);
return false;
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 4665e7a..7982f03 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -671,9 +671,10 @@ static bool shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
}
int offset = i;
- hb_font_t *font = get_hb_font(shaper, glyphs + offset);
- if (!font)
+ //hb_font_t *font = get_hb_font(shaper, glyphs + offset);
+ //if (!font)
return false;
+ hb_font_t *font = NULL; //to make compiler happy
int run_id = glyphs[offset].shape_run_id;
int level = shaper->emblevels[offset];
For reference, below are the memleaks as listed by ASAN using ART's crash-test files. The above diff is applied on top of 1140b6b885c89d37eef13dc1f31f144e9a76a4d7 and comments are toggled as needed. I'm not sure how pointers held in cache can leak, as to my understanding all cache items are supposed to get cleaned up at the end.
If forcing a "fail" during shape_harfbuzz (and not replacing the ass_shaper_shape call in ass_render_event) around ½MB leaks:
[CRASH-TEST]: ./generic
From: 0.00s
To: 120.00s
fps: 12.00
=================================================================
==6552==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 558208 byte(s) in 2492 object(s) allocated from:
#0 0x7f2319d92518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
#1 0x7f2319a2eb2f in hb_buffer_create (/lib/x86_64-linux-gnu/libharfbuzz.so.0+0x20b2f)
Direct leak of 576 byte(s) in 2 object(s) allocated from:
#0 0x7f2319d92330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x55ba2282ab10 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 2016 byte(s) in 7 object(s) allocated from:
#0 0x7f2319d92330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x55ba2282ab10 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 216 byte(s) in 1 object(s) allocated from:
#0 0x7f2319d92518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
#1 0x7f2319abbc87 in hb_unicode_funcs_create (/lib/x86_64-linux-gnu/libharfbuzz.so.0+0xadc87)
Indirect leak of 89 byte(s) in 9 object(s) allocated from:
#0 0x7f2319d92330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x55ba228258bb in ass_copy_string libass/libass/ass_utils.h:64
#2 0x55ba228258bb in font_key_move libass/libass/ass_cache.c:48
#3 0x55ba228258bb in font_key_move libass/libass/ass_cache.c:41
SUMMARY: AddressSanitizer: 561105 byte(s) leaked in 2511 allocation(s).
FAILED!
[CRASH-TEST]: ./aegisub-format-tests
From: 0.00s
To: 65.00s
fps: 24.00
=================================================================
==6568==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 432544 byte(s) in 1931 object(s) allocated from:
#0 0x7f4ca8525518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
#1 0x7f4ca81c1b2f in hb_buffer_create (/lib/x86_64-linux-gnu/libharfbuzz.so.0+0x20b2f)
Indirect leak of 1152 byte(s) in 4 object(s) allocated from:
#0 0x7f4ca8525330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x561ef939fb10 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 216 byte(s) in 1 object(s) allocated from:
#0 0x7f4ca8525518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
#1 0x7f4ca824ec87 in hb_unicode_funcs_create (/lib/x86_64-linux-gnu/libharfbuzz.so.0+0xadc87)
Indirect leak of 34 byte(s) in 4 object(s) allocated from:
#0 0x7f4ca8525330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x561ef939a8bb in ass_copy_string libass/libass/ass_utils.h:64
#2 0x561ef939a8bb in font_key_move libass/libass/ass_cache.c:48
#3 0x561ef939a8bb in font_key_move libass/libass/ass_cache.c:41
SUMMARY: AddressSanitizer: 433946 byte(s) leaked in 1940 allocation(s).
FAILED!
If forcing a "fail" in ass_render_event by replacing the ass_shaper_shape-call, a few kB leak:
[CRASH-TEST]: ./generic
From: 0.00s
To: 120.00s
fps: 12.00
=================================================================
==6287==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 576 byte(s) in 2 object(s) allocated from:
#0 0x7f6977507330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x5645bb55d0e0 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 2016 byte(s) in 7 object(s) allocated from:
#0 0x7f6977507330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x5645bb55d0e0 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 89 byte(s) in 9 object(s) allocated from:
#0 0x7f6977507330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x5645bb557e8b in ass_copy_string libass/libass/ass_utils.h:64
#2 0x5645bb557e8b in font_key_move libass/libass/ass_cache.c:48
#3 0x5645bb557e8b in font_key_move libass/libass/ass_cache.c:41
SUMMARY: AddressSanitizer: 2681 byte(s) leaked in 18 allocation(s).
FAILED!
[CRASH-TEST]: ./aegisub-format-tests
From: 0.00s
To: 65.00s
fps: 24.00
=================================================================
==6303==ERROR: LeakSanitizer: detected memory leaks
Indirect leak of 1152 byte(s) in 4 object(s) allocated from:
#0 0x7fbc76143330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x5567e91b20e0 in ass_cache_get libass/libass/ass_cache.c:370
Indirect leak of 34 byte(s) in 4 object(s) allocated from:
#0 0x7fbc76143330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x5567e91ace8b in ass_copy_string libass/libass/ass_utils.h:64
#2 0x5567e91ace8b in font_key_move libass/libass/ass_cache.c:48
#3 0x5567e91ace8b in font_key_move libass/libass/ass_cache.c:41
SUMMARY: AddressSanitizer: 1186 byte(s) leaked in 8 allocation(s).
FAILED!