@sun-asterisk/sunlint 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/config/rule-analysis-strategies.js +5 -0
- package/config/rules/enhanced-rules-registry.json +65 -10
- package/core/analysis-orchestrator.js +9 -5
- package/core/performance-optimizer.js +8 -2
- package/package.json +1 -1
- package/rules/common/C067_no_hardcoded_config/symbol-based-analyzer.js +78 -44
- package/rules/common/C070_no_real_time_tests/analyzer.js +320 -0
- package/rules/common/C070_no_real_time_tests/config.json +78 -0
- package/rules/common/C070_no_real_time_tests/regex-analyzer.js +424 -0
- package/rules/common/C073_validate_required_config_on_startup/README.md +110 -0
- package/rules/common/C073_validate_required_config_on_startup/analyzer.js +770 -0
- package/rules/common/C073_validate_required_config_on_startup/config.json +46 -0
- package/rules/common/C073_validate_required_config_on_startup/symbol-based-analyzer.js +370 -0
- package/rules/security/S057_utc_logging/README.md +152 -0
- package/rules/security/S057_utc_logging/analyzer.js +457 -0
- package/rules/security/S057_utc_logging/config.json +105 -0
- package/rules/security/S058_no_ssrf/README.md +180 -0
- package/rules/security/S058_no_ssrf/analyzer.js +403 -0
- package/rules/security/S058_no_ssrf/config.json +125 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,73 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## � **v1.3.7 - File Count Reporting & Performance Fixes (September 11, 2025)**
|
|
6
|
+
|
|
7
|
+
**Release Date**: September 11, 2025
|
|
8
|
+
**Type**: Bug Fix & Enhancement
|
|
9
|
+
**Branch**: `fix.sunlint.report`
|
|
10
|
+
|
|
11
|
+
### 🐛 **Critical Bug Fixes**
|
|
12
|
+
- **FIXED**: File count reporting accuracy in summary
|
|
13
|
+
- **Issue**: Summary showed incorrect file counts when performance filtering applied
|
|
14
|
+
- **Before**: `Files loaded: 1322` but summary `Files: 1000` (misleading)
|
|
15
|
+
- **After**: Summary accurately reflects files actually analyzed
|
|
16
|
+
- **FIXED**: File count multiplication in batch processing
|
|
17
|
+
- **Issue**: Multiple batches incorrectly accumulated file counts
|
|
18
|
+
- **Before**: 1322 files → reported as 3000 files in batched analysis
|
|
19
|
+
- **After**: Consistent file count regardless of batch strategy
|
|
20
|
+
|
|
21
|
+
### ⚡ **Performance Enhancements**
|
|
22
|
+
- **ENHANCED**: `--max-files=-1` unlimited file processing
|
|
23
|
+
- **Issue**: `-1` flag was ignored, still limited to 1000 files
|
|
24
|
+
- **Solution**: Proper unlimited file processing support
|
|
25
|
+
- **Usage**: `sunlint --max-files=-1` now analyzes all files without limits
|
|
26
|
+
|
|
27
|
+
### 🎯 **Rule Improvements**
|
|
28
|
+
- **ENHANCED**: S057 UTC Logging rule precision (100% accuracy)
|
|
29
|
+
- Fixed false positive detection for `pino.stdTimeFunctions.isoTime`
|
|
30
|
+
- Added timezone indicator support: `'Z'`, `"Z"`, `+00:00`, `.l'Z'`
|
|
31
|
+
- Enhanced config variable tracing for complex logging setups
|
|
32
|
+
- Cleaned up test fixtures and moved to proper location
|
|
33
|
+
|
|
34
|
+
### 📊 **Validation Results**
|
|
35
|
+
- **File Processing**: `--max-files=-1` → 1322 files analyzed ✅
|
|
36
|
+
- **Limited Analysis**: `--max-files=500` → 500 files analyzed ✅
|
|
37
|
+
- **Batch Analysis**: Multi-rule analysis maintains accurate counts ✅
|
|
38
|
+
- **S057 Precision**: 0 false positives on real projects ✅
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## �🔧 **v1.3.6 - C067 False Positive Reduction (September 8, 2025)**
|
|
43
|
+
|
|
44
|
+
**Release Date**: September 8, 2025
|
|
45
|
+
**Type**: Bug Fix & Improvement
|
|
46
|
+
|
|
47
|
+
### 🐛 **Bug Fixes**
|
|
48
|
+
- **FIXED**: C067 "no hardcoded config" rule - Massive false positive reduction
|
|
49
|
+
- **replace-fe**: From 296 → 2 violations (-99.3%)
|
|
50
|
+
- **replace-be**: From 171 → 3 violations (-98.2%)
|
|
51
|
+
- **jmb-app-be**: From 121 → 5 violations (-95.9%)
|
|
52
|
+
- **mdx-cycle-hack**: From 8 → 6 violations (-25%)
|
|
53
|
+
|
|
54
|
+
### 🔧 **Technical Improvements**
|
|
55
|
+
- **ENHANCED**: C067 analyzer logic improvements
|
|
56
|
+
- Skip dummy/test files and entity files completely
|
|
57
|
+
- Exclude field mapping objects and ORM configurations
|
|
58
|
+
- Skip database constraint names (primaryKeyConstraintName, etc.)
|
|
59
|
+
- Focus only on truly environment-dependent configurations
|
|
60
|
+
- Exclude business logic constants and UI field mappings
|
|
61
|
+
- **IMPROVED**: Rule precision - Only flag real environment config issues
|
|
62
|
+
- API endpoints, AWS service URLs, application keys
|
|
63
|
+
- Credential values and connection strings
|
|
64
|
+
- Environment-dependent timeouts and ports
|
|
65
|
+
|
|
66
|
+
### 📊 **Performance**
|
|
67
|
+
- **OPTIMIZED**: Reduced analysis noise by 95%+ on large projects
|
|
68
|
+
- **ENHANCED**: Better developer experience with fewer false alarms
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
5
72
|
## 🔧 **v1.3.5 - Preset System Refactor (September 8, 2025)**
|
|
6
73
|
|
|
7
74
|
**Release Date**: September 8, 2025
|
|
@@ -61,6 +61,11 @@ module.exports = {
|
|
|
61
61
|
methods: ['regex'],
|
|
62
62
|
accuracy: { regex: 90 }
|
|
63
63
|
},
|
|
64
|
+
'C070': {
|
|
65
|
+
reason: 'Real-time dependencies detection via timer/sleep patterns',
|
|
66
|
+
methods: ['regex'],
|
|
67
|
+
accuracy: { regex: 95 }
|
|
68
|
+
},
|
|
64
69
|
'S001': {
|
|
65
70
|
reason: 'Security patterns are often string-based',
|
|
66
71
|
methods: ['regex', 'ast'],
|
|
@@ -1107,28 +1107,36 @@
|
|
|
1107
1107
|
"tags": ["security", "rest", "content-type"]
|
|
1108
1108
|
},
|
|
1109
1109
|
"S057": {
|
|
1110
|
-
"name": "UTC
|
|
1111
|
-
"description": "
|
|
1110
|
+
"name": "Log with UTC Timestamps",
|
|
1111
|
+
"description": "Ensure all logs use synchronized UTC time with ISO 8601/RFC3339 format to avoid timezone discrepancies across systems",
|
|
1112
1112
|
"category": "security",
|
|
1113
1113
|
"severity": "warning",
|
|
1114
1114
|
"languages": ["typescript", "javascript"],
|
|
1115
|
-
"analyzer": "
|
|
1116
|
-
"
|
|
1115
|
+
"analyzer": "./rules/security/S057_utc_logging/analyzer.js",
|
|
1116
|
+
"config": "./rules/security/S057_utc_logging/config.json",
|
|
1117
1117
|
"version": "1.0.0",
|
|
1118
1118
|
"status": "stable",
|
|
1119
|
-
"tags": ["security", "logging", "timezone"]
|
|
1119
|
+
"tags": ["security", "logging", "timezone", "utc"],
|
|
1120
|
+
"engineMappings": {
|
|
1121
|
+
"eslint": ["custom/typescript_s057"],
|
|
1122
|
+
"heuristic": ["./rules/security/S057_utc_logging/analyzer.js"]
|
|
1123
|
+
}
|
|
1120
1124
|
},
|
|
1121
1125
|
"S058": {
|
|
1122
|
-
"name": "No SSRF",
|
|
1123
|
-
"description": "
|
|
1126
|
+
"name": "No SSRF (Server-Side Request Forgery)",
|
|
1127
|
+
"description": "Prevent SSRF attacks by validating URLs from user input before making HTTP requests",
|
|
1124
1128
|
"category": "security",
|
|
1125
1129
|
"severity": "error",
|
|
1126
1130
|
"languages": ["typescript", "javascript"],
|
|
1127
|
-
"analyzer": "
|
|
1128
|
-
"
|
|
1131
|
+
"analyzer": "./rules/security/S058_no_ssrf/analyzer.js",
|
|
1132
|
+
"config": "./rules/security/S058_no_ssrf/config.json",
|
|
1129
1133
|
"version": "1.0.0",
|
|
1130
1134
|
"status": "stable",
|
|
1131
|
-
"tags": ["security", "ssrf", "url-validation"]
|
|
1135
|
+
"tags": ["security", "ssrf", "url-validation", "http-requests"],
|
|
1136
|
+
"engineMappings": {
|
|
1137
|
+
"heuristic": ["./rules/security/S058_no_ssrf/analyzer.js"],
|
|
1138
|
+
"eslint": ["custom/typescript_s058"]
|
|
1139
|
+
}
|
|
1132
1140
|
},
|
|
1133
1141
|
"C002": {
|
|
1134
1142
|
"id": "C002",
|
|
@@ -1357,6 +1365,29 @@
|
|
|
1357
1365
|
"heuristic": ["rules/common/C067_no_hardcoded_config/analyzer.js"]
|
|
1358
1366
|
}
|
|
1359
1367
|
},
|
|
1368
|
+
"C070": {
|
|
1369
|
+
"name": "No Real Time Tests",
|
|
1370
|
+
"description": "Tests should not depend on real time delays or sleeps. Use fake timers, clock injection, or condition-based waits to improve test reliability and speed.",
|
|
1371
|
+
"category": "testing",
|
|
1372
|
+
"severity": "error",
|
|
1373
|
+
"languages": ["typescript", "javascript"],
|
|
1374
|
+
"analyzer": "../rules/common/C070_no_real_time_tests/regex-analyzer.js",
|
|
1375
|
+
"config": "../rules/common/C070_no_real_time_tests/config.json",
|
|
1376
|
+
"version": "1.0.0",
|
|
1377
|
+
"status": "stable",
|
|
1378
|
+
"tags": ["testing", "flaky-tests", "timing", "fake-timers", "reliability"],
|
|
1379
|
+
"strategy": {
|
|
1380
|
+
"preferred": "ast",
|
|
1381
|
+
"fallbacks": ["regex"],
|
|
1382
|
+
"accuracy": {
|
|
1383
|
+
"ast": 95,
|
|
1384
|
+
"regex": 88
|
|
1385
|
+
}
|
|
1386
|
+
},
|
|
1387
|
+
"engineMappings": {
|
|
1388
|
+
"heuristic": ["../rules/common/C070_no_real_time_tests/regex-analyzer.js"]
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1360
1391
|
"C072": {
|
|
1361
1392
|
"id": "C072",
|
|
1362
1393
|
"name": "Single Test Behavior",
|
|
@@ -1377,6 +1408,29 @@
|
|
|
1377
1408
|
"accuracy": {}
|
|
1378
1409
|
}
|
|
1379
1410
|
},
|
|
1411
|
+
"C073": {
|
|
1412
|
+
"id": "C073",
|
|
1413
|
+
"name": "Validate Required Configuration on Startup",
|
|
1414
|
+
"description": "C073 - Validate mandatory configuration at startup and fail fast on invalid/missing values",
|
|
1415
|
+
"category": "configuration",
|
|
1416
|
+
"severity": "error",
|
|
1417
|
+
"languages": ["typescript", "javascript", "java", "go"],
|
|
1418
|
+
"version": "1.0.0",
|
|
1419
|
+
"status": "stable",
|
|
1420
|
+
"tags": ["configuration", "validation", "startup", "fail-fast"],
|
|
1421
|
+
"engineMappings": {
|
|
1422
|
+
"heuristic": ["rules/common/C073_validate_required_config_on_startup/analyzer.js"],
|
|
1423
|
+
"semantic": ["rules/common/C073_validate_required_config_on_startup/symbol-based-analyzer.js"]
|
|
1424
|
+
},
|
|
1425
|
+
"strategy": {
|
|
1426
|
+
"preferred": "semantic",
|
|
1427
|
+
"fallbacks": ["heuristic"],
|
|
1428
|
+
"accuracy": {
|
|
1429
|
+
"semantic": 0.9,
|
|
1430
|
+
"heuristic": 0.7
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1380
1434
|
"C075": {
|
|
1381
1435
|
"id": "C075",
|
|
1382
1436
|
"name": "Rule C075",
|
|
@@ -1784,6 +1838,7 @@
|
|
|
1784
1838
|
"C048",
|
|
1785
1839
|
"C052",
|
|
1786
1840
|
"C072",
|
|
1841
|
+
"C073",
|
|
1787
1842
|
"C075",
|
|
1788
1843
|
"T002",
|
|
1789
1844
|
"T003",
|
|
@@ -264,7 +264,7 @@ class AnalysisOrchestrator {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
// Merge results and add performance metrics
|
|
267
|
-
const mergedResults = this.mergeEngineResults(results, options);
|
|
267
|
+
const mergedResults = this.mergeEngineResults(results, options, optimizedFiles.length);
|
|
268
268
|
mergedResults.performance = performanceMetrics;
|
|
269
269
|
|
|
270
270
|
return mergedResults;
|
|
@@ -523,7 +523,7 @@ class AnalysisOrchestrator {
|
|
|
523
523
|
* @param {Object} options - Analysis options
|
|
524
524
|
* @returns {Object} Merged results
|
|
525
525
|
*/
|
|
526
|
-
mergeEngineResults(engineResults, options) {
|
|
526
|
+
mergeEngineResults(engineResults, options, actualFilesCount = 0) {
|
|
527
527
|
const mergedResults = {
|
|
528
528
|
results: [],
|
|
529
529
|
summary: {
|
|
@@ -568,15 +568,19 @@ class AnalysisOrchestrator {
|
|
|
568
568
|
// Accumulate engine statistics across batches
|
|
569
569
|
mergedResults.summary.engines[engineName].rules.push(...(engineResult.rules || []));
|
|
570
570
|
mergedResults.summary.engines[engineName].violations += violationCount;
|
|
571
|
-
|
|
571
|
+
// Don't accumulate filesAnalyzed for each batch - use actual unique file count
|
|
572
|
+
if (!mergedResults.summary.engines[engineName].filesSet) {
|
|
573
|
+
mergedResults.summary.engines[engineName].files = actualFilesCount;
|
|
574
|
+
mergedResults.summary.engines[engineName].filesSet = true;
|
|
575
|
+
}
|
|
572
576
|
mergedResults.summary.engines[engineName].batches += 1;
|
|
573
577
|
|
|
574
578
|
mergedResults.summary.totalViolations += violationCount;
|
|
575
|
-
mergedResults.summary.totalFiles += engineResult.filesAnalyzed || 0;
|
|
576
579
|
}
|
|
577
580
|
|
|
578
|
-
// Update unique engine count
|
|
581
|
+
// Update unique engine count and correct total files count
|
|
579
582
|
mergedResults.summary.totalEngines = uniqueEngines.size;
|
|
583
|
+
mergedResults.summary.totalFiles = actualFilesCount;
|
|
580
584
|
|
|
581
585
|
return mergedResults;
|
|
582
586
|
}
|
|
@@ -26,6 +26,12 @@ class PerformanceOptimizer {
|
|
|
26
26
|
...DEFAULT_PERFORMANCE,
|
|
27
27
|
...config
|
|
28
28
|
};
|
|
29
|
+
|
|
30
|
+
// Override maxTotalFiles if provided in config
|
|
31
|
+
if (config.maxFiles !== undefined) {
|
|
32
|
+
this.fileSizeLimits.maxTotalFiles = config.maxFiles;
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
this.initialized = true;
|
|
30
36
|
}
|
|
31
37
|
|
|
@@ -106,8 +112,8 @@ class PerformanceOptimizer {
|
|
|
106
112
|
break;
|
|
107
113
|
}
|
|
108
114
|
|
|
109
|
-
// Check file count limit
|
|
110
|
-
if (filtered.length >= this.fileSizeLimits.maxTotalFiles) {
|
|
115
|
+
// Check file count limit (skip if unlimited -1)
|
|
116
|
+
if (this.fileSizeLimits.maxTotalFiles > 0 && filtered.length >= this.fileSizeLimits.maxTotalFiles) {
|
|
111
117
|
if (this.config.verbose) {
|
|
112
118
|
console.log(`⚠️ Reached file count limit: ${this.fileSizeLimits.maxTotalFiles} files`);
|
|
113
119
|
}
|
package/package.json
CHANGED
|
@@ -246,7 +246,7 @@ class C067SymbolBasedAnalyzer {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
isConfigOrTestFile(filePath) {
|
|
249
|
-
// Skip config files themselves and test files
|
|
249
|
+
// Skip config files themselves and test files, including dummy/test data files
|
|
250
250
|
const fileName = filePath.toLowerCase();
|
|
251
251
|
const configPatterns = [
|
|
252
252
|
/config\.(ts|js|json)$/,
|
|
@@ -264,9 +264,12 @@ class C067SymbolBasedAnalyzer {
|
|
|
264
264
|
/\/test\//,
|
|
265
265
|
/\/tests\//,
|
|
266
266
|
/\.stories\.(ts|tsx|js|jsx)$/,
|
|
267
|
-
/\.mock\.(ts|tsx|js|jsx)
|
|
268
|
-
//
|
|
269
|
-
//
|
|
267
|
+
/\.mock\.(ts|tsx|js|jsx)$/,
|
|
268
|
+
/\/dummy\//, // Skip dummy data files
|
|
269
|
+
/dummy\.(ts|js)$/, // Skip dummy files
|
|
270
|
+
/test-fixtures\//, // Skip test fixture files
|
|
271
|
+
/\.fixture\.(ts|js)$/, // Skip fixture files
|
|
272
|
+
/entity\.(ts|js)$/ // Skip entity/ORM files (contain DB constraints)
|
|
270
273
|
];
|
|
271
274
|
|
|
272
275
|
return configPatterns.some(pattern => pattern.test(fileName)) ||
|
|
@@ -451,66 +454,97 @@ class C067SymbolBasedAnalyzer {
|
|
|
451
454
|
const propertyName = nameNode.getText();
|
|
452
455
|
const position = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
453
456
|
|
|
454
|
-
// Skip field mapping objects
|
|
457
|
+
// Skip ALL field mapping objects and ORM/database entity configurations
|
|
455
458
|
const ancestorObj = node.getParent();
|
|
456
459
|
if (ancestorObj && Node.isObjectLiteralExpression(ancestorObj)) {
|
|
457
460
|
const objParent = ancestorObj.getParent();
|
|
458
461
|
if (objParent && Node.isVariableDeclaration(objParent)) {
|
|
459
462
|
const varName = objParent.getName();
|
|
460
|
-
|
|
461
|
-
|
|
463
|
+
// Skip field mappings, database schemas, etc.
|
|
464
|
+
if (/mapping|map|field|column|decode|schema|entity|constraint|table/i.test(varName)) {
|
|
465
|
+
return null;
|
|
462
466
|
}
|
|
463
467
|
}
|
|
468
|
+
|
|
469
|
+
// Check if this looks like a table column definition or field mapping
|
|
470
|
+
const objText = ancestorObj.getText();
|
|
471
|
+
if (/primaryKeyConstraintName|foreignKeyConstraintName|key.*may contain/i.test(objText)) {
|
|
472
|
+
return null; // Skip database constraint definitions
|
|
473
|
+
}
|
|
464
474
|
}
|
|
465
475
|
|
|
466
|
-
// Skip
|
|
476
|
+
// Skip properties that are clearly field mappings or business data
|
|
467
477
|
const businessLogicProperties = [
|
|
468
|
-
|
|
469
|
-
'
|
|
470
|
-
|
|
471
|
-
'
|
|
478
|
+
// Field mappings
|
|
479
|
+
'key', 'field', 'dataKey', 'valueKey', 'labelKey', 'sortKey',
|
|
480
|
+
// Business logic
|
|
481
|
+
'endpoint', 'path', 'route', 'method',
|
|
482
|
+
'limit', 'pageSize', 'batchSize', 'maxResults',
|
|
483
|
+
'retry', 'retries', 'maxRetries', 'attempts',
|
|
484
|
+
'count', 'max', 'min', 'size', 'length',
|
|
485
|
+
// UI properties
|
|
486
|
+
'className', 'style', 'disabled', 'readonly',
|
|
487
|
+
// Database/ORM
|
|
488
|
+
'primaryKeyConstraintName', 'foreignKeyConstraintName', 'constraintName',
|
|
489
|
+
'tableName', 'columnName', 'schemaName'
|
|
472
490
|
];
|
|
473
491
|
|
|
474
492
|
const lowerPropertyName = propertyName.toLowerCase();
|
|
475
493
|
if (businessLogicProperties.some(prop => lowerPropertyName.includes(prop))) {
|
|
476
|
-
|
|
477
|
-
let value = null;
|
|
478
|
-
if (valueNode.getKind() === SyntaxKind.StringLiteral) {
|
|
479
|
-
value = valueNode.getLiteralValue();
|
|
480
|
-
// Only flag URLs or clearly environment-dependent strings
|
|
481
|
-
if (!this.configPatterns.urls.regex.test(value) || !this.isEnvironmentDependentUrl(value)) {
|
|
482
|
-
return null;
|
|
483
|
-
}
|
|
484
|
-
} else if (valueNode.getKind() === SyntaxKind.NumericLiteral) {
|
|
485
|
-
value = valueNode.getLiteralValue();
|
|
486
|
-
const parentContext = this.getParentContext(node);
|
|
487
|
-
// Only flag if it's clearly environment-dependent (like ports, large timeouts)
|
|
488
|
-
if (!this.configPatterns.environmentNumbers.isEnvironmentDependent(value, parentContext)) {
|
|
489
|
-
return null;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
494
|
+
return null; // Skip these completely
|
|
492
495
|
}
|
|
493
496
|
|
|
494
|
-
//
|
|
495
|
-
|
|
496
|
-
|
|
497
|
+
// Only check for CLEARLY environment-dependent properties
|
|
498
|
+
const trulyEnvironmentDependentProps = [
|
|
499
|
+
'baseurl', 'baseURL', 'host', 'hostname', 'server', 'endpoint',
|
|
500
|
+
'apikey', 'api_key', 'secret_key', 'client_secret',
|
|
501
|
+
'database', 'connectionstring', 'dbhost', 'dbport',
|
|
502
|
+
'port', 'timeout', // Only when they have suspicious values
|
|
503
|
+
'bucket', 'region', // Cloud-specific
|
|
504
|
+
'clientid', 'tenantid' // OAuth-specific
|
|
505
|
+
];
|
|
506
|
+
|
|
507
|
+
if (!trulyEnvironmentDependentProps.some(prop => lowerPropertyName.includes(prop))) {
|
|
508
|
+
return null; // Not clearly environment-dependent
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
let value = null;
|
|
512
|
+
let configType = null;
|
|
513
|
+
|
|
514
|
+
if (valueNode.getKind() === SyntaxKind.StringLiteral) {
|
|
515
|
+
value = valueNode.getLiteralValue();
|
|
497
516
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
517
|
+
// Only flag URLs or clearly sensitive values
|
|
518
|
+
if (this.configPatterns.urls.regex.test(value) && this.isEnvironmentDependentUrl(value)) {
|
|
519
|
+
configType = 'url';
|
|
520
|
+
} else if (this.isRealCredential(value, propertyName)) {
|
|
521
|
+
configType = 'credential';
|
|
522
|
+
} else {
|
|
523
|
+
return null; // Skip other string values
|
|
502
524
|
}
|
|
525
|
+
} else if (valueNode.getKind() === SyntaxKind.NumericLiteral) {
|
|
526
|
+
value = valueNode.getLiteralValue();
|
|
527
|
+
const parentContext = this.getParentContext(node);
|
|
503
528
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
column: position.column,
|
|
510
|
-
node: node,
|
|
511
|
-
propertyName: propertyName
|
|
512
|
-
};
|
|
529
|
+
// Only flag numbers that are clearly environment-dependent
|
|
530
|
+
if (this.configPatterns.environmentNumbers.isEnvironmentDependent(value, parentContext)) {
|
|
531
|
+
configType = 'environment_config';
|
|
532
|
+
} else {
|
|
533
|
+
return null;
|
|
513
534
|
}
|
|
535
|
+
} else {
|
|
536
|
+
return null; // Skip other value types
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (configType) {
|
|
540
|
+
return {
|
|
541
|
+
type: configType,
|
|
542
|
+
value: value,
|
|
543
|
+
line: position.line,
|
|
544
|
+
column: position.column,
|
|
545
|
+
node: node,
|
|
546
|
+
propertyName: propertyName
|
|
547
|
+
};
|
|
514
548
|
}
|
|
515
549
|
|
|
516
550
|
return null;
|