libcss may leak memory if css_stylesheet_data_done() is not called. See the attached source for an example.
One might argue that css_stylesheet_data_done() is a mandatory call, but I believe that a library should try to avoid memory leaks as much as possible. Hence I propose fix below which adds a single line to css_error css__parser_destroy(). I am not sure if this is the most elegant solution, but it works well for me. Feedback from the libcss developers is much appreciated. Ralf ---- css_error css__parser_destroy(css_parser *parser) { if (parser == NULL) return CSS_BADPARM; parserutils_stack_destroy(parser->open_items); unref_interned_strings_in_tokens(parser); /* <-- added: Memory leak otherwise. */ parserutils_vector_destroy(parser->tokens); parserutils_stack_destroy(parser->states); css__lexer_destroy(parser->lexer); parserutils_inputstream_destroy(parser->stream); free(parser); return CSS_OK; }
#pragma hdrstop #pragma argsused #include <stdio.h> #include <tchar.h> #include <libcss/libcss.h> css_error resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs) { /* About as useless as possible */ *abs = lwc_string_ref(rel); return CSS_OK; } void check(const css_error code) { if (code != CSS_OK && code != CSS_NEEDDATA ) { printf ("Error\n"); } } int _tmain(int argc, _TCHAR* argv[]) { css_error code; css_stylesheet *sheet; size_t size; const char data[] = "h1 { color: red } " "h4 { color: #321; } " "h4, h5 { color: #123456; }"; css_stylesheet_params params; printf("%d", __BORLANDC__); params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1; params.level = CSS_LEVEL_21; params.charset = "UTF-8"; params.url = "foo"; params.title = "foo"; params.allow_quirks = false; params.inline_style = false; params.resolve = resolve_url; params.resolve_pw = NULL; params.import = NULL; params.import_pw = NULL; params.color = NULL; params.color_pw = NULL; params.font = NULL; params.font_pw = NULL; printf ("sizeof(bool) = %d\n", sizeof(bool)); /* create a stylesheet */ code = css_stylesheet_create(¶ms, &sheet); check(code); code = css_stylesheet_size(sheet, &size); check(code); printf("created stylesheet, size %d\n", size); /* parse some CSS source */ code = css_stylesheet_append_data(sheet, (const uint8_t *) data, sizeof data); check(code); // code = css_stylesheet_data_done(sheet); // check(code); code = css_stylesheet_destroy(sheet); check(code); lwc_finalize(); return 0; }