Skip to content

fix: sanitize threshold values in complexity SQL queries#136

Merged
carlos-alm merged 4 commits intomainfrom
fix/complexity-sql-sanitize
Feb 27, 2026
Merged

fix: sanitize threshold values in complexity SQL queries#136
carlos-alm merged 4 commits intomainfrom
fix/complexity-sql-sanitize

Conversation

@carlos-alm
Copy link
Contributor

Summary

  • Coerce complexity threshold warn values through Number() and guard with Number.isNaN() before interpolating into SQL HAVING clauses
  • Prevents malformed queries when non-numeric values are provided in .codegraphrc.json config

Test plan

  • Run node src/cli.js complexity with default thresholds — verify normal behavior
  • Set a non-numeric threshold in config (e.g. "warn": "abc") — verify no SQL error

@claude
Copy link

claude bot commented Feb 26, 2026

Claude finished @carlos-alm's task —— View job


PR Review: SQL Sanitization Fix

Todo List

  • Read and analyze the changed file (src/complexity.js)
  • Phase 1: Root cause analysis
  • Phase 2: Configuration change detection
  • Phase 3: Test integrity assessment
  • Phase 4: Code quality review
  • Provide final assessment and recommendation

Phase 1: Root Cause Analysis ✅

Problem Being Solved: The PR fixes a genuine SQL injection vulnerability in complexity threshold filtering (src/complexity.js:392-394, 396-398, 400-402). When users provide non-numeric values in .codegraphrc.json config like "warn": "abc", the old code directly interpolated these values into SQL HAVING clauses without validation:

// VULNERABLE (before):
conditions.push(`fc.cognitive >= ${thresholds.cognitive.warn}`);
// Results in: fc.cognitive >= abc  (malformed SQL)

// SECURE (after):
const val = Number(thresholds.cognitive.warn);
if (!Number.isNaN(val)) conditions.push(`fc.cognitive >= ${val}`);

Why This Approach: The fix uses Number() coercion + Number.isNaN() guard to:

  1. Convert string numbers to numeric values ("15"15)
  2. Detect and skip invalid values ("abc"NaN → skip condition)
  3. Maintain backward compatibility with existing numeric configs

Risk Assessment: This is a critical security fix addressing direct SQL injection. The approach is conservative and appropriate.

Phase 2: Configuration Change Detection ✅

No problematic configuration changes detected:

  • No linting rules disabled
  • No test thresholds relaxed
  • No build configuration modified
  • Changes are surgical and security-focused

Phase 3: Test Integrity Assessment ⚠️

Missing test coverage concern:

  • Existing tests in tests/integration/complexity.test.js don't cover the specific vulnerability scenario
  • No test verifies behavior with non-numeric threshold values (e.g., "warn": "abc")
  • The PR's test plan in description mentions manual testing but no automated tests added

Current test coverage focuses on normal complexity analysis but misses the edge case this PR fixes.

Phase 4: Code Quality Review ✅

Code quality is solid:

  • Security: Properly prevents SQL injection with input validation
  • Logic: Number() handles string-to-number conversion correctly
  • Edge cases: Number.isNaN() correctly identifies invalid values
  • Backward compatibility: Existing numeric configs continue to work
  • Performance: Minimal overhead (pre-conversion vs. runtime injection risk)

Technical correctness:

  • The fix handles all three threshold types consistently (cognitive/cyclomatic/maxNesting)
  • Graceful degradation: invalid thresholds are silently ignored rather than breaking the query
  • No side effects on other functionality

Critical Concerns

Missing test coverage: The vulnerability scenario isn't covered by automated tests. While the fix is correct, the lack of regression tests means this could break again in the future without detection.

Suggestion: Add a test case like:

test('handles non-numeric threshold values safely', () => {
  // Mock config with invalid threshold
  const invalidConfig = { cognitive: { warn: "abc" }, cyclomatic: { warn: "123xyz" } };
  // Verify no SQL error and graceful handling
});

Root Cause Analysis

Problem Being Solved: Critical SQL injection vulnerability where non-numeric threshold values in config break SQL HAVING clauses
Why This Approach: Conservative sanitization with Number() + Number.isNaN() ensures backward compatibility while preventing injection
Risk Assessment: High-impact security fix addressing real vulnerability

Critical Concerns (if any)

Test Coverage Gap: No automated test covers the specific non-numeric threshold scenario this PR fixes, creating risk of regression

Final Recommendation

  • Rating: ⭐⭐⭐☆☆ (3/5)
  • Action: APPROVE WITH CONDITIONS
  • Reasoning: Critical security fix with sound implementation, but missing regression test coverage prevents higher rating. The fix itself is excellent and should be merged, but ideally with a follow-up test addition.

The code change is technically correct and addresses a real security vulnerability. The missing test coverage is concerning but shouldn't block this important security fix.


@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

This PR fixes a security vulnerability where non-numeric threshold values in .codegraphrc.json could cause SQL injection or malformed queries. The fix uses strict type validation (typeof v === 'number' && Number.isFinite(v)) instead of loose coercion, properly rejecting strings, NaN, Infinity, null, undefined, and booleans.

Key changes:

  • Introduced isValidThreshold() helper that validates threshold values before SQL interpolation
  • Applied validation consistently across SQL HAVING clause construction, exceeds array population, and aboveWarn summary calculation
  • Added comprehensive regression tests verifying graceful handling of invalid thresholds
  • Added default threshold for maintainabilityIndex (completing the feature from PR feat: Halstead metrics and Maintainability Index #139)

The implementation correctly handles edge cases and prevents SQL injection while maintaining backward compatibility with properly formatted config files.

Confidence Score: 5/5

  • This PR is safe to merge - it's a well-tested security fix with no breaking changes
  • The strict type validation prevents SQL injection vulnerabilities, comprehensive tests verify correct behavior, and the implementation handles all edge cases properly. Both previous review concerns have been addressed through the evolution of commits
  • No files require special attention

Important Files Changed

Filename Overview
src/complexity.js Adds strict type validation for threshold values before SQL interpolation using typeof and Number.isFinite(), preventing SQL injection and handling edge cases correctly
tests/integration/complexity.test.js Adds comprehensive regression tests verifying invalid thresholds don't crash and result in correct behavior (empty exceeds, zero aboveWarn)

Last reviewed commit: 2ab45fe

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +392 to +393
const val = Number(thresholds.cognitive.warn);
if (!Number.isNaN(val)) conditions.push(`fc.cognitive >= ${val}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number() coerces edge cases to valid numbers: Number("") and Number(null) both return 0, while Number(true) returns 1. These would pass the isNaN check and be treated as valid thresholds.

Consider stricter validation to avoid unexpected behavior:

Suggested change
const val = Number(thresholds.cognitive.warn);
if (!Number.isNaN(val)) conditions.push(`fc.cognitive >= ${val}`);
const val = Number(thresholds.cognitive.warn);
if (Number.isFinite(val) && typeof thresholds.cognitive.warn === 'number') conditions.push(`fc.cognitive >= ${val}`);

@carlos-alm
Copy link
Contributor Author

Addressed the test coverage gap — added two regression tests in tests/integration/complexity.test.js:

  1. non-numeric threshold values do not crash SQL query — mocks loadConfig to return { cognitive: { warn: 'abc' }, cyclomatic: { warn: '123xyz' }, maxNesting: { warn: undefined } } with aboveThreshold: true. Verifies the query completes without SQL errors and returns a valid result.

  2. string-numeric thresholds are coerced correctly — mocks thresholds as string numbers ('15', '10', '4'). Verifies Number() coercion works: simpleAdd (0,1,0) is still excluded, handleRequest (25,15,5) is still included.

Both tests use vi.mock/mockReturnValueOnce on loadConfig so they don't affect the other tests in the file.

@greptileai

@claude
Copy link

claude bot commented Feb 27, 2026

Claude finished @carlos-alm's task —— View job


PR Review: SQL Sanitization Fix (Updated)

Todo List

  • Read and analyze the updated test file
  • Review the original complexity.js changes
  • Assess test coverage adequacy
  • Evaluate Greptile's edge case concerns
  • Provide comprehensive review and updated rating

Phase 1: Root Cause Analysis ✅

Problem Being Solved: The PR fixes a genuine SQL injection vulnerability in complexity threshold filtering (src/complexity.js:392-394, 396-398, 400-402). When users provide non-numeric values in .codegraphrc.json config like "warn": "abc", the old code directly interpolated these values into SQL HAVING clauses without validation.

Why This Approach: The fix uses Number() coercion + Number.isNaN() guard to:

  1. Convert string numbers to numeric values ("15"15)
  2. Detect and skip invalid values ("abc"NaN → skip condition)
  3. Maintain backward compatibility with existing numeric configs

Risk Assessment: This is a critical security fix addressing direct SQL injection. The approach is conservative and appropriate.

Phase 2: Configuration Change Detection ✅

No problematic configuration changes detected:

  • No linting rules disabled
  • No test thresholds relaxed
  • No build configuration modified
  • Changes are surgical and security-focused

Phase 3: Test Integrity Assessment ✅ SIGNIFICANTLY IMPROVED

Excellent test coverage additions:

The author has addressed the critical test gap with two comprehensive regression tests (tests/integration/complexity.test.js:165-196):

  1. non-numeric threshold values do not crash SQL query (lines 165-179):

    • Mocks config with genuinely invalid thresholds: 'abc', '123xyz', undefined
    • Verifies the query completes without SQL errors and returns valid results
    • Directly tests the vulnerability scenario this PR fixes
  2. string-numeric thresholds are coerced correctly (lines 181-196):

    • Tests Number() coercion with string-numeric values: '15', '10', '4'
    • Verifies correct filtering behavior with coerced values
    • Ensures backward compatibility with existing string configs

Technical quality of tests:

  • Uses vi.mocked(loadConfig).mockReturnValueOnce() for isolated testing
  • Tests the actual aboveThreshold functionality that triggers the SQL injection path
  • Verifies both error prevention AND correct behavior
  • No interference with other tests (proper mocking isolation)

Phase 4: Code Quality Review ✅

Code quality remains solid:

  • Security: Properly prevents SQL injection with input validation
  • Logic: Number() handles string-to-number conversion correctly
  • Backward compatibility: Existing numeric configs continue to work
  • Performance: Minimal overhead

Addressing Greptile's edge case concerns:
Greptile flagged that Number("") returns 0 and Number(true) returns 1, which could pass validation. However:

  • Low risk in practice: Config files rarely contain empty strings or booleans for numeric thresholds
  • Existing null check: The code already has != null checks that catch undefined/null
  • Graceful degradation: Even if edge cases slip through, they result in valid numeric SQL (not injection)
  • Not a breaking change: The current approach maintains maximum backward compatibility

The suggested stricter validation (Number.isFinite() && typeof === 'number') would be more restrictive but could break existing configs that use string numbers.

Root Cause Analysis

Problem Being Solved: Critical SQL injection vulnerability where non-numeric threshold values in config break SQL HAVING clauses
Why This Approach: Conservative sanitization with Number() + Number.isNaN() ensures backward compatibility while preventing injection
Risk Assessment: High-impact security fix addressing real vulnerability

Critical Concerns (if any)

Previously: Missing test coverage → ✅ RESOLVED with comprehensive regression tests
Greptile edge cases: Minor concern about Number() coercion behavior, but low practical risk and maintains compatibility

Final Recommendation

  • Rating: ⭐⭐⭐⭐☆ (4/5)
  • Action: APPROVE
  • Reasoning: Excellent security fix with proper test coverage. The author has directly addressed the previous critical concern by adding comprehensive regression tests that cover both the vulnerability scenario and backward compatibility. Minor edge cases exist but don't pose practical risks.

Significant improvement from previous 3/5 rating due to proper test coverage addressing the vulnerability scenario.


Comment on lines +165 to +179
test('non-numeric threshold values do not crash SQL query', () => {
vi.mocked(loadConfig).mockReturnValueOnce({
manifesto: {
rules: {
cognitive: { warn: 'abc' },
cyclomatic: { warn: '123xyz' },
maxNesting: { warn: undefined },
},
},
});
// Should not throw — invalid thresholds are silently skipped
const data = complexityData(dbPath, { aboveThreshold: true });
expect(data.functions).toBeDefined();
expect(Array.isArray(data.functions)).toBe(true);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test could verify more complete behavior. Current assertions only check that the function doesn't crash, but don't verify that exceeds arrays and summary.aboveWarn are correctly computed with non-numeric thresholds.

Consider adding:

expect(data.summary.aboveWarn).toBeGreaterThan(0); // should still count functions correctly
const handleReq = data.functions.find(f => f.name === 'handleRequest');
expect(handleReq.exceeds).toBeDefined(); // should still mark exceeding functions

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Additional Comments (2)

src/complexity.js
Threshold values used directly without sanitization. Non-numeric values (e.g., 'abc') will cause incorrect behavior: comparisons like r.cognitive >= 'abc' evaluate to false, so functions won't be marked as exceeding thresholds even when they should.

Apply the same sanitization used for SQL queries (lines 392-402) to ensure consistent behavior:

const cognitiveThreshold = thresholds.cognitive?.warn != null 
  ? Number(thresholds.cognitive.warn) 
  : null;
const cyclomaticThreshold = thresholds.cyclomatic?.warn != null 
  ? Number(thresholds.cyclomatic.warn) 
  : null;
const maxNestingThreshold = thresholds.maxNesting?.warn != null 
  ? Number(thresholds.maxNesting.warn) 
  : null;

const exceeds = [];
if (cognitiveThreshold != null && !Number.isNaN(cognitiveThreshold) && r.cognitive >= cognitiveThreshold)
  exceeds.push('cognitive');
if (cyclomaticThreshold != null && !Number.isNaN(cyclomaticThreshold) && r.cyclomatic >= cyclomaticThreshold)
  exceeds.push('cyclomatic');
if (maxNestingThreshold != null && !Number.isNaN(maxNestingThreshold) && r.max_nesting >= maxNestingThreshold)
  exceeds.push('maxNesting');

src/complexity.js
Same issue: threshold values need sanitization here too. Use sanitized values from above to maintain consistency.

carlos-alm pushed a commit that referenced this pull request Feb 27, 2026
Replace loose `!= null` checks with `typeof === 'number' && Number.isFinite()`
to prevent `Number("")`, `Number(null)`, and `Number(true)` from silently
coercing into valid SQL values. Add integration test verifying exceeds
arrays and summary.aboveWarn are correctly computed.

Addresses Greptile review feedback on #136.

Impact: 2 functions changed, 3 affected
Coerce threshold warn values through Number() and guard with isNaN
before interpolating into SQL HAVING clauses, preventing malformed
queries when non-numeric values are provided in config.

Impact: 1 functions changed, 4 affected
Replace Number() coercion + isNaN with typeof === 'number' && isFinite()
to reject values like Number(""), Number(null), Number(true) that silently
coerce to valid numbers. Add maintainabilityIndex to default thresholds.
Update regression tests to verify exceeds arrays and summary.aboveWarn.

Addresses Greptile review on #136.

Impact: 2 functions changed, 1 affected
Assert that no function has exceeds when thresholds are non-numeric
strings, complementing the summary.aboveWarn === 0 assertions.
@carlos-alm carlos-alm force-pushed the fix/complexity-sql-sanitize branch from a77461a to 2ab45fe Compare February 27, 2026 02:08
@carlos-alm
Copy link
Contributor Author

@greptileai

@claude
Copy link

claude bot commented Feb 27, 2026

Claude finished @carlos-alm's task —— View job


PR Review: SQL Sanitization Fix (Updated Analysis)

Todo List

  • Read and analyze the updated complexity.js changes
  • Review the new test additions in complexity.test.js
  • Evaluate Greptile's incomplete sanitization concerns
  • Assess test coverage adequacy
  • Provide comprehensive review following 4-phase methodology

Phase 1: Root Cause Analysis ✅

Problem Being Solved: The PR fixes a genuine SQL injection vulnerability in complexity threshold filtering (src/complexity.js:708-716). When users provide non-numeric values in .codegraphrc.json config like "warn": "abc", the old code directly interpolated these values into SQL HAVING clauses without validation.

Why This Approach: The fix uses a helper function isValidThreshold(v) that checks typeof v === 'number' && Number.isFinite(v) to:

  1. Ensure only genuine numeric values pass validation (not strings like "15")
  2. Prevent SQL injection by validating before interpolation
  3. Skip invalid thresholds gracefully (no SQL condition added)

Risk Assessment: This is a critical security fix addressing direct SQL injection. The approach is robust and conservative.

Phase 2: Configuration Change Detection ✅

No problematic configuration changes detected:

  • No linting rules disabled
  • No test thresholds relaxed
  • No build configuration modified
  • Changes are surgical and security-focused

Phase 3: Test Integrity Assessment ✅ SIGNIFICANTLY IMPROVED

Excellent test coverage additions (tests/integration/complexity.test.js:331-373):

  1. non-numeric threshold values do not crash SQL query (lines 331-352):

    • Mocks config with genuinely invalid thresholds: 'abc', '123xyz', undefined
    • Verifies query completes without SQL errors and returns valid results
    • Directly tests the vulnerability scenario this PR fixes
    • Confirms summary.aboveWarn = 0 and fn.exceeds is undefined with invalid thresholds
  2. string-numeric thresholds are rejected (strict type check) (lines 354-373):

    • Tests string-numeric values: '15', '10', '4'
    • Verifies the strict type checking rejects strings (unlike Number() coercion approach)
    • Ensures backward compatibility behavior: invalid thresholds = no filtering

Technical quality of tests:

  • Uses vi.mocked(loadConfig).mockReturnValueOnce() for isolated testing
  • Tests the actual aboveThreshold functionality that triggers the SQL path
  • Verifies both error prevention AND correct behavior with edge cases
  • No interference with other tests (proper mocking isolation)

Phase 4: Code Quality Review ✅

Code quality is excellent:

  • Security: Completely prevents SQL injection with strict validation
  • Logic: isValidThreshold() helper ensures only valid numbers pass
  • Backward compatibility: Invalid thresholds are gracefully ignored
  • Performance: Minimal overhead, validation happens once per query

Addressing Greptile's concerns about JavaScript comparison inconsistency:

After careful analysis, Greptile's concern is INVALID for this implementation. The current code in lines 764-778 correctly uses the same isValidThreshold() helper function:

// SQL query validation (lines 708-716)
if (isValidThreshold(thresholds.cognitive?.warn)) {
  conditions.push(`fc.cognitive >= ${thresholds.cognitive.warn}`);
}

// JavaScript comparison validation (lines 764-778) 
if (isValidThreshold(thresholds.cognitive?.warn) && r.cognitive >= thresholds.cognitive.warn)
  exceeds.push('cognitive');

Both paths use identical validation - there is NO inconsistency. Greptile's suggestion to add separate sanitization is unnecessary and would be redundant.

Root Cause Analysis

Problem Being Solved: Critical SQL injection vulnerability where non-numeric threshold values in config break SQL HAVING clauses
Why This Approach: Strict type validation with isValidThreshold() helper ensures only genuine numbers are used, preventing injection while maintaining graceful degradation
Risk Assessment: High-impact security fix addressing real vulnerability with robust validation

Critical Concerns (if any)

Previous concerns fully resolved: Test coverage is now comprehensive, and the sanitization approach is consistent throughout the codebase. Greptile's incomplete sanitization concern appears to be based on misunderstanding of the current implementation.

Final Recommendation

  • Rating: ⭐⭐⭐⭐⭐ (5/5)
  • Action: APPROVE
  • Reasoning: Exceptional security fix with comprehensive test coverage and consistent implementation. The author has:
    1. Fixed a critical SQL injection vulnerability
    2. Used robust, strict validation (typeof === 'number' && Number.isFinite())
    3. Added comprehensive regression tests covering both invalid and edge cases
    4. Applied validation consistently across SQL and JavaScript comparison paths
    5. Maintained backward compatibility with graceful degradation

This is a textbook example of how to properly address a security vulnerability with appropriate testing and validation.


@carlos-alm carlos-alm merged commit c5ca1f2 into main Feb 27, 2026
15 checks passed
@carlos-alm carlos-alm deleted the fix/complexity-sql-sanitize branch February 27, 2026 02:12
carlos-alm pushed a commit that referenced this pull request Feb 27, 2026
Replace loose `!= null` checks with `typeof === 'number' && Number.isFinite()`
to prevent `Number("")`, `Number(null)`, and `Number(true)` from silently
coercing into valid SQL values. Add integration test verifying exceeds
arrays and summary.aboveWarn are correctly computed.

Addresses Greptile review feedback on #136.

Impact: 2 functions changed, 3 affected
carlos-alm added a commit that referenced this pull request Feb 27, 2026
* fix: strict type validation for threshold values in complexity queries

Replace loose `!= null` checks with `typeof === 'number' && Number.isFinite()`
to prevent `Number("")`, `Number(null)`, and `Number(true)` from silently
coercing into valid SQL values. Add integration test verifying exceeds
arrays and summary.aboveWarn are correctly computed.

Addresses Greptile review feedback on #136.

Impact: 2 functions changed, 3 affected

* docs: add complexity, communities, and manifesto to all docs

Update README, CLAUDE.md, BACKLOG, titan-paradigm, recommended-practices,
and CLI/MCP examples to reflect today's merged PRs: complexity metrics
(#130/#139), Louvain community detection (#133/#134), and manifesto rule
engine (#138). Updates MCP tool count from 21 to 24 (25 in multi-repo),
marks backlog items 6/11/21/22 as done, and adds real CLI output examples.

* fix: remove redundant condition in paginate guard clauses

When limit === undefined, limit !== 0 is always true — the && check
was dead code. Simplified to just check limit === undefined.

Impact: 2 functions changed, 18 affected

* docs: update dogfood report with fix statuses

All 4 bugs now fixed (PR #117 merged, #116 closed via reverse-dep
cascade). 3 of 4 suggestions addressed. MCP tool counts updated
18→23 / 19→24. Rating upgraded 7/10 → 9/10 post-fix.

* fix: rename misleading test to match actual behavior

Test was named "handles non-numeric thresholds gracefully" but only
validated baseline exceeds/aboveWarn with valid thresholds. Actual
non-numeric threshold tests exist separately. Renamed to "produces
correct exceeds and aboveWarn with valid thresholds".

* fix: update stale MCP tool count in dogfood skill (21→24)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
carlos-alm added a commit that referenced this pull request Feb 27, 2026
* fix: strict type validation for threshold values in complexity queries

Replace loose `!= null` checks with `typeof === 'number' && Number.isFinite()`
to prevent `Number("")`, `Number(null)`, and `Number(true)` from silently
coercing into valid SQL values. Add integration test verifying exceeds
arrays and summary.aboveWarn are correctly computed.

Addresses Greptile review feedback on #136.

Impact: 2 functions changed, 3 affected

* docs: add complexity, communities, and manifesto to all docs

Update README, CLAUDE.md, BACKLOG, titan-paradigm, recommended-practices,
and CLI/MCP examples to reflect today's merged PRs: complexity metrics
(#130/#139), Louvain community detection (#133/#134), and manifesto rule
engine (#138). Updates MCP tool count from 21 to 24 (25 in multi-repo),
marks backlog items 6/11/21/22 as done, and adds real CLI output examples.

* fix: remove redundant condition in paginate guard clauses

When limit === undefined, limit !== 0 is always true — the && check
was dead code. Simplified to just check limit === undefined.

Impact: 2 functions changed, 18 affected

* docs: update dogfood report with fix statuses

All 4 bugs now fixed (PR #117 merged, #116 closed via reverse-dep
cascade). 3 of 4 suggestions addressed. MCP tool counts updated
18→23 / 19→24. Rating upgraded 7/10 → 9/10 post-fix.

* fix: rename misleading test to match actual behavior

Test was named "handles non-numeric thresholds gracefully" but only
validated baseline exceeds/aboveWarn with valid thresholds. Actual
non-numeric threshold tests exist separately. Renamed to "produces
correct exceeds and aboveWarn with valid thresholds".

* fix: update stale MCP tool count in dogfood skill (21→24)

* feat: add complexity analysis for Python, Go, Rust, Java, C#, Ruby, PHP

Parameterize the complexity algorithm to support all 10 languages instead
of just JS/TS/TSX. Add per-language COMPLEXITY_RULES, HALSTEAD_RULES, and
COMMENT_PREFIXES with three else-if detection patterns (else-wraps-if,
explicit elif, alternative field). Guard against tree-sitter keyword leaf
tokens that share node type names with their parent constructs.

Impact: 4 functions changed, 4 affected

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant