Skip to content

Parser not terminating after toml_err_set, which may lead to assertion failure #13

Description

@jidnjs

Description

toml_err_set writes an error into the thread-local variable g_err and asserts that the previous error code was TOML_OK.

However, several code paths calls toml_err_set but does not stop parsing afterward.
When parsing continues and encounters another error, a second call to toml_err_set triggers the assertion, resulting in an abort.

static TOML_THREAD_LOCAL TomlErr g_err = {TOML_OK, (char*)"", TOML_TRUE};
...
TOML_INLINE void toml_err_set(TomlErrCode code, TOML_CONST char *format, ...)
{
    assert(g_err.code == TOML_OK);
    ...
    g_err.code = code;
    ...
}

Reproduction

  1. create file named: repro_double_err_set with following contents:
[table]
unterminated_key = 
unterminated_key2 = 
  1. run the parser
toml_load_filename("./repro_double_err_set");

Actual behavior

  • The program aborts due to the assertion inside toml_err_set

example output:

src/toml.c:137: void toml_err_set(TomlErrCode, const char *, ...): Assertion `g_err.code == TOML_OK' failed.
Aborted (core dumped)

Expected behavior

  • toml_load_filename should stop parsing after the first error and return NULL without crashing.

Fix suggestion

Certain codes need to return NULL or error code immediately after call to toml_err_set.

Add return NULL; at:

Use goto error; instead of goto cleanup;

Add goto error; at:

Cases needing multi-line updates

AS IS:

            toml_err_set(TOML_ERR_SYNTAX, "%s:%d:%d: invalid float");
            goto cleanup; // here

TO BE:

            toml_err_set(TOML_ERR_SYNTAX, "%s:%d:%d: invalid float");
            toml_string_free(str);
            return NULL;

AS IS

    toml_parse_key_value(self, real_table);

    goto cleanup;

TO BE

    if (toml_parse_key_value(self, real_table) == TOML_OK)
        goto cleanup;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions