Skip to content

[Bug]reachable assert(0) abort in parser next() when an embedded NUL truncates the token stream (CWE-617) #386

Closed

Description

@1820893135-pixel

Summary

The parser's token-stream next() assumes P->token != P->te when it advances (src/compiler/parser.c:357). A schema containing an embedded NUL byte — here between root_type and the type name — truncates the token stream at the lexer level, so when next() is asked for the token after root_type, the end-of-token sentinel is hit and assert(0) fires, aborting the whole compile instead of reporting a clean parse error.

  • Affected versions: flatcc HEAD 4c3b999e3c0a423f9fd8df3c9e58ba9d2069d71b (v0.6.4-pre)
  • Severity: Medium (reachable assertion abort / SIGABRT; crash/DoS of the schema compiler)
  • CWE: CWE-617 (Reachable Assertion)

Detail

Affected code

/* src/compiler/parser.c:357 (excerpt) */
static void next(flatcc_parser *P)
{
    ...
    assert(P->token != P->te);    /* <-- fires when embedded NUL ends the stream early */
    P->token += P->token_len;
    ...
}

Root cause: the lexer treats the embedded NUL as end-of-input, so the token queue terminates before the parser has consumed the expected number of tokens. next() does not handle the exhausted-token-stream case gracefully — it asserts instead of emitting a syntax error.

Reachability: fully attacker-controlled .fbs schema text. The NUL byte is legal inside the raw buffer but is never expected inside an identifier context.

Call chain:

next (src/compiler/parser.c:357, assert(0))
  └─ __flatcc_fb_parse (src/compiler/parser.c:1489)
       └─ flatcc_parse_buffer (src/compiler/flatcc.c:113)
            └─ LLVMFuzzerTestOneInput (harness.c:66)

POC (tested on the unmodified source)

Attached flatcc_poc3_embedded_nul.fbs (57 bytes) — a valid schema with a NUL byte (0x00) inserted between root_type and the type name:

table DoubleVec {
  a: [double];
}

root_type\x00DoubleVec;

Raw hex of the trigger region (root_type + NUL + DoubleVec;):

... 726f 6f74 5f74 7970 6500 446f 7562 6c65 5665 633b 0a
./flatcc_schema_parser_fuzzer flatcc_poc3_embedded_nul.fbs

Trigger result

Assertion failed: P->token != P->te (src/compiler/parser.c:357)
Aborted (core dumped)
EXIT=134 (SIGABRT)
  • Replay exit code: 134 (SIGABRT, assert(0))
  • Deterministic: yes — the embedded NUL reliably truncates the token stream

Suggested fix

Replace the assert(0) with a proper exhausted-stream error path that reports a syntax error and unwinds cleanly:

if (P->token == P->te) {
    flatcc_parser_error(P, "unexpected end of token stream");
    return;
}

Also consider rejecting embedded NUL bytes in the lexer with a diagnostic instead of silently terminating the input.

Activity

  1. mikkelfj commented on Aug 4, 2026

    @mikkelfj
    Contributor

    I cannot reproduce.

    With suggested schema stored in test.fbs, I get:

    bin/flatcc_d test.fbs # (debug build should report triggered assertions)

    test.fbs:5:11: error: 'x00DoubleVec': missing ';' expected by root_type at: test.fbs:5:10: ''
    test.fbs:5:11: error: 'x00DoubleVec': unexpected token in schema definition
    output failed

  2. mikkelfj commented on Aug 4, 2026

    @mikkelfj
    Contributor

    I also tested with:

    lldb bin/flatcc_d -- test.fbs

    and

    lldb bin/flatcc -- test.fbs

    And I get no exceptions when running (macOS, arm64)

  3. 1820893135-pixel commented on Aug 7, 2026

    @1820893135-pixel
    ContributorAuthor

    Sorry for the unclear reproduction steps provided in my previous POC. #386 Please review this issue. I have refined it and taken screenshots for your reference. Thank you.

  4. mikkelfj commented on Aug 7, 2026

    @mikkelfj
    Contributor

    I see no screenshots on this issue.

    I was able to reproduce your other issues, but not not this one. And I see no new information.

    Having a fuzzer fail is not enough. The provided schema did not trigger the issue.

  5. mikkelfj commented on Aug 7, 2026

    @mikkelfj
    Contributor

    I did not mean to close the issue just yet.

  6. mikkelfj commented on Aug 12, 2026

    @mikkelfj
    Contributor

    Closing absent meaningful follow up. Feel free to reopen if you have a schema that can trigger the issue with a regular bin/flatcc or bin/flatcc_d (debug) command.

  7. 1820893135-pixel commented on Sep 23, 2026

    @1820893135-pixel
    ContributorAuthor

    Reopening with a reproducer that works through bin/flatcc_d, as requested.

    The earlier POC used an attached file; when it was re-typed by hand the NUL byte
    became the two characters x00, which is why it only produced
    error: 'x00DoubleVec': missing ';'. Here is the exact schema, written as bytes
    so the NUL survives:

    printf 'table DoubleVec {\n  a: [double];\n}\n\nroot_type\x00DoubleVec;\n' > schema.fbs
    xxd schema.fbs | tail -2
    00000020: 0a7d 0a0a 726f 6f74 5f74 7970 6500 446f  .}..root_type.Do
    00000030: 7562 6c65 5665 633b 0a                   ubleVec;.
    

    The 00 in 726f 6f74 5f74 7970 6500 446f is the embedded NUL.

    $ bin/flatcc_d schema.fbs
    flatcc_d: src/compiler/parser.c:357: next: Assertion `0' failed.
    Aborted (core dumped)                   # rc=134
    

    It needs the debug build (flatcc_d) because the assert is what fires; a release
    build compiles it out. The relevant code is next():

    if (P->token == P->te) {
        --P->token;
        assert(0);                      /* <-- before the handling below */
        switch (P->token->id) {
        case LEX_TOK_EOS: case LEX_TOK_EOB: case LEX_TOK_EOF:
            P->token->id = LEX_TOK_EOF;
            return P->token;
        }
        error_tok(P, P->token, "unexpected end of input");
    }

    The NUL truncates the token stream at the lexer level, so the parser asks for a
    token that is no longer there and reaches this branch.

    Opened #397, which drops the assert(0) so the existing error_tok() path runs;
    the schema then fails with error: '': missing ';' expected by root_type and
    exit status 255.

  8. added a commit that references this issue on Sep 25, 2026
    fe8ecb2
  9. added a commit that references this issue on Sep 25, 2026
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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions