Skip to content

Circular-dependency checker misses cycles when include comments contain > #7802

Description

@CedarProof

Summary

contrib/devtools/circular-dependencies.py can miss a dependency cycle when a
valid trailing comment on an angle-bracket include contains a greater-than
character. Adding only a comment can change the tool's result from exit 1 with
a reported cycle to exit 0 with no output.

Version and scope

Repository: https://github.com/dashpay/dash
Branch snapshot: develop
Commit: c14104b172a271d69823173a7323b90ca9b32cde
Source:

RE = re.compile("^#include <(.*)>")

Reproduced using Python 3.12.14 on Windows, exercising the serial execution path.
This is a development-tool correctness report, not a wallet, consensus, or
security-critical vulnerability report. The report and proposed fix were
prepared with AI assistance and checked by direct local executions.

Minimal reproduction

In an otherwise empty temporary directory, create these two files:

a.h:

#include <b.h> // dependency for Container<T>

b.h:

#include <a.h>

Invoke the pinned script from that directory, passing both relative names:

python /path/to/circular-dependencies.py a.h b.h

Expected: exit 1, with this output:

Circular dependency: a -> b -> a

Actual: exit 0, with no stdout or stderr.

Remove the trailing comment (or replace it with a comment without '>') and the
same two-file cycle is reported correctly. A /* Container<T> */ comment causes
the same miss. Neither example relies on quoted includes or unusual whitespace.

Cause

The expression ^#include <(.*)> is greedy. For the a.h example, the captured
text is b.h> // dependency for Container<T instead of b.h. The subsequent
module lookup cannot match that value, so the a-to-b edge is omitted.

Upstream context

Upstream context: source inspection of Bitcoin Core master at 66776840beb558f7e84451c2c55457f0e06242f0 found the same greedy include expression and module-lookup behavior in contrib/devtools/circular-dependencies.py. This is therefore not presented as a Dash-specific regression. Three bounded public issue/PR searches did not identify this exact trailing-comment trigger, but one search examined only the first 30 of 85 results and discussion histories were not exhaustively reviewed; prior-report status and reward eligibility remain unconfirmed.
Source: https://github.com/bitcoin/bitcoin/blob/66776840beb558f7e84451c2c55457f0e06242f0/contrib/devtools/circular-dependencies.py#L30

Suggested fix

Stop the header-name match at the first closing angle bracket:

RE = re.compile(r"^#include <([^>]+)>")

The attached patch changes only this expression. It preserves the existing
angle-bracket and beginning-of-line requirements and does not attempt to make
the tool a full C++ preprocessor. GCC's include-syntax documentation permits
comments after a header name:
https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html

Verification

The attached verify-fix.py requires the exact source SHA-256 before executing
it. It creates eight synthetic two-header cases and runs both the unchanged
script and the one-line patched script. It checks both exit status and exact
stdout/stderr; it does not test only the regex in isolation.

Observed:

  • Unchanged source: four cases miss a cycle; four control cases behave correctly.
  • Patched source: all eight cases behave as expected.
  • Controls include ordinary cycles, ordinary comments, an acyclic graph, and
    an acyclic graph with the same comment syntax.
  • No network calls, node binaries, wallet files, or real repository data were
    used during the reproduction.

Limits

The full repository lint suite, C++ build, functional tests, and Linux fork
execution path have not been run. No claim is made that a currently checked-in
Dash source file already triggers the problem. The direct caller in
test/lint/lint-circular-dependencies.py consumes this tool's output, so missed
edges can affect its cycle detection; a full CI run was not simulated.

A bounded search did not find this exact trigger already reported, but this is
not proof that no duplicate exists. No accepted fix, confirmed bounty eligibility, or payment is claimed.

Supporting files are attached as dash-core-circular-dependency-report-v2.zip.
This issue reports the technical defect only; it does not submit a bounty claim or request payment.

dash-core-circular-dependency-report-v2.zip

Activity

  1. lamkyo commented on Oct 11, 2026

    @lamkyo

    🛠️ Antigravity Technical Solution & Verified Patch Proposal

    We have conducted a thorough root-cause analysis and verified patch implementation for this issue.

    • Interactive Technical Proposal & Evidence: job-ghb-dashpay-dash-7802
    • Verification Guarantee: 100% automated test assertions passed, zero regressions detected.
    • Bounty Payout Rail: 0x24A2151Ec787a2C5c81412A888c3a9d9eEc3beEA (EVM) / lamvukyo3001@gmail.com (PayPal)

    Submitted by Sovereign Fleet Runner: @lamkyo (github_secondary)

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions