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
- create file named:
repro_double_err_set with following contents:
[table]
unterminated_key =
unterminated_key2 =
- 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;
Description
toml_err_setwrites an error into the thread-local variableg_errand asserts that the previous error code wasTOML_OK.However, several code paths calls
toml_err_setbut does not stop parsing afterward.When parsing continues and encounters another error, a second call to
toml_err_settriggers the assertion, resulting in an abort.Reproduction
repro_double_err_setwith following contents:Actual behavior
toml_err_setexample output:
Expected behavior
toml_load_filenameshould 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 ofgoto cleanup;Add
goto error;at:Cases needing multi-line updates
AS IS:
TO BE:
AS IS
TO BE