Skip to content

Malformed input "[&" triggers UB in parser (and assertion in assert-enabled builds) #294

@VAHPEM

Description

@VAHPEM

Environment

toml++ version and/or commit hash:
Commit: 209ba6675bde846e878111e03bb84852a537f7e3

Compiler:
Clang++ 18.1.3

C++ standard mode:
C++17

Target arch:
AArch64 (ARM64 Linux)

Library configuration overrides:
None

Relevant compilation flags:
-O1 -g -DNDEBUG -std=c++17 -fsanitize=address,undefined -fno-omit-frame-pointer

Describe the bug

Parsing malformed TOML input can trigger undefined behavior instead of producing a clean parse_error.

While fuzzing the toml::parse() API with libFuzzer, AddressSanitizer, and UBSan, a minimal input of only two bytes causes runtime undefined behavior inside the parser implementation.

Minimal crashing input:

[&

Hex representation:

5b26

Running the parser with sanitizers produces runtime errors similar to:

target/include/toml++/impl/parser.inl:555:22: runtime error: member call on address which does not point to an object of type 'toml::impl::utf8_reader_interface'

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior target/include/toml++/impl/parser.inl:555:22

target/include/toml++/impl/parser.inl:520:19: runtime error: member call on address which does not point to an object of type 'toml::impl::utf8_reader_interface'

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior target/include/toml++/impl/parser.inl:520:19

In assertion-enabled builds, the same input also triggers:

Assertion 'is_bare_key_character(*cp) || is_string_delimiter(*cp)' failed.

Expected behavior: malformed TOML input should be rejected cleanly with a parse_error rather than triggering undefined behavior.

Steps to reproduce (or a small repro code sample)

The following standalone program reproduces the issue without libFuzzer

Save the following program as repro.cpp:

#include <string_view>
#include <toml++/toml.hpp>

int main()
{
    try
    {
        auto tbl = toml::parse(std::string_view{"[&", 2});
        (void)tbl;
    }
    catch (...)
    {
    }
}

Build command:

clang++ -O1 -g -DNDEBUG -std=c++17 -fsanitize=address,undefined -fno-omit-frame-pointer repro.cpp src/toml.cpp -I include -o repro

Run:

ASAN_OPTIONS=detect_leaks=0 ./repro

Additional information

This issue was discovered during fuzz testing of the toml::parse(std::string_view) API using libFuzzer.

The input minimized automatically during crash minimization and consistently reproduces the sanitizer findings without requiring libFuzzer.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions