Skip to content

C/C++: a CRLF file with a backslash-continued string literal swallows the rest of the file, and every later function is missing from the graph #1546

Description

@noohi

Version

codebase-memory-mcp 0.10.1

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

When a C/C++ source file uses CRLF line endings and contains a string literal continued
with a backslash at end of line, the extractor loses the end of that literal. The
enclosing function is emitted as a single node spanning to end of file, and every
function defined after it is missing from the graph entirely.

The same file with LF line endings extracts correctly. Line endings are the only
difference between the two inputs below.

Expected: the same set of functions, with the same spans, regardless of line endings.
CRLF is the default checkout on Windows, so this affects a normally configured Windows
working tree.

Both conditions are required. CRLF alone is fine, and backslash continuation on LF is
fine. Backslash continuation is uncommon in modern C++, since adjacent string literal
concatenation is the usual idiom, which is probably why this has survived several
releases.

Reproduction

1. Code. Two directories, byte-identical apart from line endings. Because the bug is
byte-sensitive, here is a generator rather than a paste, so the exact bytes survive
copying (176 bytes LF, 196 bytes CRLF):

src = r'''void Head()
{
    int h = 0;
}

void Middle()
{
    const wchar_t* s = L"line 0\r\n\
line 1\r\n";
}

void TrailerOne()
{
    int a = 1;
}

void TrailerTwo()
{
    int b = 2;
}
'''
import os
for name, text in (('lf', src), ('crlf', src.replace('\n', '\r\n'))):
    os.makedirs(name, exist_ok=True)
    open(os.path.join(name, 'repro.cpp'), 'wb').write(text.encode())

2. Commands. Index each directory and list the functions:

codebase-memory-mcp cli index_repository '{"repo_path":"<dir>"}'
codebase-memory-mcp cli query_graph '{"project":"<name>","query":"MATCH (n:Function) RETURN n.name, n.start_line, n.end_line"}'

3. Result vs expected.

Line endings Head Middle TrailerOne TrailerTwo
LF (expected) 1-4 6-10 12-15 17-20
CRLF (actual) 1-4 6-20 missing missing

Middle absorbs the remaining 10 lines of the file, and the two functions defined after
it are absent from the graph. The whole-graph counts differ accordingly: LF indexes to 8
nodes / 7 edges, CRLF to 6 nodes / 5 edges. CBM_LSP_DISABLED=1 does not change the
outcome, so this looks like the base extractor rather than the Hybrid LSP layer.

One caveat when reproducing: index into a fresh cache directory. An incremental re-index
of an already-indexed project returns parse_partial_count: 0 even though the graph is
still missing the functions, which makes the flag look like it cleared when it has not.

Logs

On 0.10.1, `index_repository` on the CRLF directory reports `parse_partial_count: 1`,
and the per-project logfile carries:


parse_partial	8-12,12-12,20-20	repro.cpp


Releases before 0.10.0 reported this file clean, so the loss was fully silent. Since
0.10.0 the flag is raised, but the file is still not extracted.

Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

No response

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglanguage-requestRequest for new language supportparsing/qualityGraph extraction bugs, false positives, missing edgeswindowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions