Skip to content

Commit 674a48a

Browse files
fix: strict type validation for threshold values in complexity queries
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
1 parent f8cba1f commit 674a48a

1 file changed

Lines changed: 24 additions & 18 deletions

File tree

src/complexity.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ export function complexityData(customDbPath, opts = {}) {
673673
cognitive: { warn: 15, fail: null },
674674
cyclomatic: { warn: 10, fail: null },
675675
maxNesting: { warn: 4, fail: null },
676+
maintainabilityIndex: { warn: 20, fail: null },
676677
};
677678

678679
// Build query
@@ -699,22 +700,21 @@ export function complexityData(customDbPath, opts = {}) {
699700
params.push(kindFilter);
700701
}
701702

703+
const isValidThreshold = (v) => typeof v === 'number' && Number.isFinite(v);
704+
702705
let having = '';
703706
if (aboveThreshold) {
704707
const conditions = [];
705-
if (thresholds.cognitive?.warn != null) {
706-
const val = Number(thresholds.cognitive.warn);
707-
if (!Number.isNaN(val)) conditions.push(`fc.cognitive >= ${val}`);
708+
if (isValidThreshold(thresholds.cognitive?.warn)) {
709+
conditions.push(`fc.cognitive >= ${thresholds.cognitive.warn}`);
708710
}
709-
if (thresholds.cyclomatic?.warn != null) {
710-
const val = Number(thresholds.cyclomatic.warn);
711-
if (!Number.isNaN(val)) conditions.push(`fc.cyclomatic >= ${val}`);
711+
if (isValidThreshold(thresholds.cyclomatic?.warn)) {
712+
conditions.push(`fc.cyclomatic >= ${thresholds.cyclomatic.warn}`);
712713
}
713-
if (thresholds.maxNesting?.warn != null) {
714-
const val = Number(thresholds.maxNesting.warn);
715-
if (!Number.isNaN(val)) conditions.push(`fc.max_nesting >= ${val}`);
714+
if (isValidThreshold(thresholds.maxNesting?.warn)) {
715+
conditions.push(`fc.max_nesting >= ${thresholds.maxNesting.warn}`);
716716
}
717-
if (thresholds.maintainabilityIndex?.warn != null) {
717+
if (isValidThreshold(thresholds.maintainabilityIndex?.warn)) {
718718
conditions.push(
719719
`fc.maintainability_index > 0 AND fc.maintainability_index <= ${thresholds.maintainabilityIndex.warn}`,
720720
);
@@ -761,14 +761,17 @@ export function complexityData(customDbPath, opts = {}) {
761761

762762
const functions = filtered.map((r) => {
763763
const exceeds = [];
764-
if (thresholds.cognitive?.warn != null && r.cognitive >= thresholds.cognitive.warn)
764+
if (isValidThreshold(thresholds.cognitive?.warn) && r.cognitive >= thresholds.cognitive.warn)
765765
exceeds.push('cognitive');
766-
if (thresholds.cyclomatic?.warn != null && r.cyclomatic >= thresholds.cyclomatic.warn)
766+
if (isValidThreshold(thresholds.cyclomatic?.warn) && r.cyclomatic >= thresholds.cyclomatic.warn)
767767
exceeds.push('cyclomatic');
768-
if (thresholds.maxNesting?.warn != null && r.max_nesting >= thresholds.maxNesting.warn)
768+
if (
769+
isValidThreshold(thresholds.maxNesting?.warn) &&
770+
r.max_nesting >= thresholds.maxNesting.warn
771+
)
769772
exceeds.push('maxNesting');
770773
if (
771-
thresholds.maintainabilityIndex?.warn != null &&
774+
isValidThreshold(thresholds.maintainabilityIndex?.warn) &&
772775
r.maintainability_index > 0 &&
773776
r.maintainability_index <= thresholds.maintainabilityIndex.warn
774777
)
@@ -820,10 +823,13 @@ export function complexityData(customDbPath, opts = {}) {
820823
minMI: +Math.min(...miValues).toFixed(1),
821824
aboveWarn: allRows.filter(
822825
(r) =>
823-
(thresholds.cognitive?.warn != null && r.cognitive >= thresholds.cognitive.warn) ||
824-
(thresholds.cyclomatic?.warn != null && r.cyclomatic >= thresholds.cyclomatic.warn) ||
825-
(thresholds.maxNesting?.warn != null && r.max_nesting >= thresholds.maxNesting.warn) ||
826-
(thresholds.maintainabilityIndex?.warn != null &&
826+
(isValidThreshold(thresholds.cognitive?.warn) &&
827+
r.cognitive >= thresholds.cognitive.warn) ||
828+
(isValidThreshold(thresholds.cyclomatic?.warn) &&
829+
r.cyclomatic >= thresholds.cyclomatic.warn) ||
830+
(isValidThreshold(thresholds.maxNesting?.warn) &&
831+
r.max_nesting >= thresholds.maxNesting.warn) ||
832+
(isValidThreshold(thresholds.maintainabilityIndex?.warn) &&
827833
r.maintainability_index > 0 &&
828834
r.maintainability_index <= thresholds.maintainabilityIndex.warn),
829835
).length,

0 commit comments

Comments
 (0)