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(&params, &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;
}

Reply via email to