@opencodereview/core 2.0.1 → 2.1.0
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/dist/ai/v4/index.d.ts +3 -1
- package/dist/ai/v4/index.d.ts.map +1 -1
- package/dist/ai/v4/index.js +2 -0
- package/dist/ai/v4/index.js.map +1 -1
- package/dist/ai/v4/llm/index.d.ts +1 -0
- package/dist/ai/v4/llm/index.d.ts.map +1 -1
- package/dist/ai/v4/llm/index.js +1 -0
- package/dist/ai/v4/llm/index.js.map +1 -1
- package/dist/ai/v4/llm/provider-factory.d.ts +59 -0
- package/dist/ai/v4/llm/provider-factory.d.ts.map +1 -0
- package/dist/ai/v4/llm/provider-factory.js +87 -0
- package/dist/ai/v4/llm/provider-factory.js.map +1 -0
- package/dist/ai/v4/pipeline.d.ts.map +1 -1
- package/dist/ai/v4/pipeline.js +2 -8
- package/dist/ai/v4/pipeline.js.map +1 -1
- package/dist/ai/v4/types.d.ts +42 -7
- package/dist/ai/v4/types.d.ts.map +1 -1
- package/dist/ai/v4/types.js +40 -1
- package/dist/ai/v4/types.js.map +1 -1
- package/dist/ai-healer/auto-fix-engine.d.ts +98 -0
- package/dist/ai-healer/auto-fix-engine.d.ts.map +1 -0
- package/dist/ai-healer/auto-fix-engine.js +371 -0
- package/dist/ai-healer/auto-fix-engine.js.map +1 -0
- package/dist/ai-healer/heal-reporter.d.ts +22 -0
- package/dist/ai-healer/heal-reporter.d.ts.map +1 -0
- package/dist/ai-healer/heal-reporter.js +137 -0
- package/dist/ai-healer/heal-reporter.js.map +1 -0
- package/dist/ai-healer/ide-rules-generator.d.ts +46 -0
- package/dist/ai-healer/ide-rules-generator.d.ts.map +1 -0
- package/dist/ai-healer/ide-rules-generator.js +214 -0
- package/dist/ai-healer/ide-rules-generator.js.map +1 -0
- package/dist/config/v4-config.d.ts +3 -1
- package/dist/config/v4-config.d.ts.map +1 -1
- package/dist/config/v4-config.js.map +1 -1
- package/dist/detectors/registry/go-packages.d.ts +16 -0
- package/dist/detectors/registry/go-packages.d.ts.map +1 -0
- package/dist/detectors/registry/go-packages.js +181 -0
- package/dist/detectors/registry/go-packages.js.map +1 -0
- package/dist/detectors/registry/java-packages.d.ts +16 -0
- package/dist/detectors/registry/java-packages.d.ts.map +1 -0
- package/dist/detectors/registry/java-packages.js +144 -0
- package/dist/detectors/registry/java-packages.js.map +1 -0
- package/dist/detectors/registry/kotlin-packages.d.ts +15 -0
- package/dist/detectors/registry/kotlin-packages.d.ts.map +1 -0
- package/dist/detectors/registry/kotlin-packages.js +125 -0
- package/dist/detectors/registry/kotlin-packages.js.map +1 -0
- package/dist/detectors/registry/python-packages.d.ts +16 -0
- package/dist/detectors/registry/python-packages.d.ts.map +1 -0
- package/dist/detectors/registry/python-packages.js +113 -0
- package/dist/detectors/registry/python-packages.js.map +1 -0
- package/dist/detectors/v4/index.d.ts +5 -0
- package/dist/detectors/v4/index.d.ts.map +1 -1
- package/dist/detectors/v4/index.js +10 -0
- package/dist/detectors/v4/index.js.map +1 -1
- package/dist/detectors/v4/language-specific.d.ts +47 -0
- package/dist/detectors/v4/language-specific.d.ts.map +1 -0
- package/dist/detectors/v4/language-specific.js +560 -0
- package/dist/detectors/v4/language-specific.js.map +1 -0
- package/dist/detectors/v4/security-pattern.d.ts.map +1 -1
- package/dist/detectors/v4/security-pattern.js +91 -0
- package/dist/detectors/v4/security-pattern.js.map +1 -1
- package/dist/detectors/v4/stale-api.d.ts.map +1 -1
- package/dist/detectors/v4/stale-api.js +21 -0
- package/dist/detectors/v4/stale-api.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/scanner/v4-scanner.d.ts +3 -1
- package/dist/scanner/v4-scanner.d.ts.map +1 -1
- package/dist/scanner/v4-scanner.js +1 -0
- package/dist/scanner/v4-scanner.js.map +1 -1
- package/package.json +22 -10
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language-Specific AI Detectors — V4 detectors for Go/Java/Kotlin/Python.
|
|
3
|
+
*
|
|
4
|
+
* These detectors catch AI-specific patterns that are unique to each language:
|
|
5
|
+
* - GoDetector: Unhandled errors, deprecated ioutil, unnecessary goroutines
|
|
6
|
+
* - JavaDetector: Deprecated Date/Calendar API, System.out.println leaks
|
|
7
|
+
* - KotlinDetector: Non-null assertion abuse (!!), coroutine misuse
|
|
8
|
+
* - PythonDetector: bare except, eval(), deprecated urlparse, mutable defaults
|
|
9
|
+
*
|
|
10
|
+
* @since 0.5.0
|
|
11
|
+
*/
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
13
|
+
// Go-specific AI Detector
|
|
14
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
15
|
+
const GO_PATTERNS = [
|
|
16
|
+
{
|
|
17
|
+
id: 'go-unhandled-error',
|
|
18
|
+
pattern: /\b\w+\s*\([^)]*\)\s*$(?!\s*_\s*=)/m,
|
|
19
|
+
severity: 'warning',
|
|
20
|
+
confidence: 0.6,
|
|
21
|
+
message: 'Function call that may return an error is not assigned or checked. AI often ignores Go error returns.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'go-deprecated-ioutil',
|
|
25
|
+
pattern: /['"]io\/ioutil['"]/,
|
|
26
|
+
severity: 'warning',
|
|
27
|
+
confidence: 0.95,
|
|
28
|
+
message: 'io/ioutil is deprecated since Go 1.16. Use os and io packages instead.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'go-ioutil-readfile',
|
|
32
|
+
pattern: /\bioutil\.ReadFile\b/,
|
|
33
|
+
severity: 'warning',
|
|
34
|
+
confidence: 0.95,
|
|
35
|
+
message: 'ioutil.ReadFile is deprecated. Use os.ReadFile instead.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'go-ioutil-writefile',
|
|
39
|
+
pattern: /\bioutil\.WriteFile\b/,
|
|
40
|
+
severity: 'warning',
|
|
41
|
+
confidence: 0.95,
|
|
42
|
+
message: 'ioutil.WriteFile is deprecated. Use os.WriteFile instead.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'go-ioutil-readall',
|
|
46
|
+
pattern: /\bioutil\.ReadAll\b/,
|
|
47
|
+
severity: 'warning',
|
|
48
|
+
confidence: 0.95,
|
|
49
|
+
message: 'ioutil.ReadAll is deprecated. Use io.ReadAll instead.',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'go-panic-in-library',
|
|
53
|
+
pattern: /\bpanic\s*\(/,
|
|
54
|
+
severity: 'warning',
|
|
55
|
+
confidence: 0.7,
|
|
56
|
+
message: 'panic() used in non-main code. AI often uses panic instead of proper error handling in library code.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'go-empty-defer',
|
|
60
|
+
pattern: /\bdefer\s+\w+\s*\(\s*\)/,
|
|
61
|
+
severity: 'info',
|
|
62
|
+
confidence: 0.5,
|
|
63
|
+
message: 'defer call with no arguments or empty function. May indicate AI-generated boilerplate.',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
export class GoLanguageDetector {
|
|
67
|
+
id = 'go-language-specific';
|
|
68
|
+
name = 'Go Language-Specific Detector';
|
|
69
|
+
category = 'implementation';
|
|
70
|
+
supportedLanguages = ['go'];
|
|
71
|
+
async detect(units, context) {
|
|
72
|
+
const results = [];
|
|
73
|
+
for (const unit of units) {
|
|
74
|
+
if (unit.language !== 'go')
|
|
75
|
+
continue;
|
|
76
|
+
if (!unit.source || unit.source.trim().length === 0)
|
|
77
|
+
continue;
|
|
78
|
+
// Check if this is a main package — relax panic rules for main
|
|
79
|
+
const isMainPackage = /package\s+main\b/.test(unit.source);
|
|
80
|
+
const lines = unit.source.split('\n');
|
|
81
|
+
for (let i = 0; i < lines.length; i++) {
|
|
82
|
+
const line = lines[i];
|
|
83
|
+
const trimmed = line.trim();
|
|
84
|
+
// Skip comments
|
|
85
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*'))
|
|
86
|
+
continue;
|
|
87
|
+
// Skip these patterns for clean code - only apply line-by-line patterns
|
|
88
|
+
for (const pat of GO_PATTERNS) {
|
|
89
|
+
if (pat.id === 'go-panic-in-library' && isMainPackage)
|
|
90
|
+
continue;
|
|
91
|
+
if (pat.id === 'go-unhandled-error')
|
|
92
|
+
continue; // Skip broad heuristic — handled by specific analysis
|
|
93
|
+
pat.pattern.lastIndex = 0;
|
|
94
|
+
if (pat.pattern.test(line)) {
|
|
95
|
+
results.push({
|
|
96
|
+
detectorId: this.id,
|
|
97
|
+
severity: pat.severity,
|
|
98
|
+
category: this.category,
|
|
99
|
+
messageKey: `go-language-specific.${pat.id}`,
|
|
100
|
+
message: pat.message,
|
|
101
|
+
file: unit.file,
|
|
102
|
+
line: unit.location.startLine + i + 1,
|
|
103
|
+
confidence: pat.confidence,
|
|
104
|
+
metadata: {
|
|
105
|
+
patternId: pat.id,
|
|
106
|
+
language: 'go',
|
|
107
|
+
matchedLine: trimmed.substring(0, 100),
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Unhandled error analysis: find assignments that ignore errors
|
|
114
|
+
this.detectUnhandledErrors(unit, lines, results);
|
|
115
|
+
}
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
detectUnhandledErrors(unit, lines, results) {
|
|
119
|
+
// Look for error-returning functions called without capturing the error
|
|
120
|
+
const errorReturningFuncs = /\b(?:os\.Open|os\.Create|os\.ReadFile|os\.WriteFile|os\.MkdirAll|os\.Remove|net\.Dial|net\.Listen|http\.Get|http\.Post|json\.Marshal|json\.Unmarshal|exec\.Command|ioutil\.\w+)\s*\(/;
|
|
121
|
+
for (let i = 0; i < lines.length; i++) {
|
|
122
|
+
const line = lines[i].trim();
|
|
123
|
+
if (line.startsWith('//') || line.startsWith('/*') || line.startsWith('*'))
|
|
124
|
+
continue;
|
|
125
|
+
errorReturningFuncs.lastIndex = 0;
|
|
126
|
+
if (!errorReturningFuncs.test(line))
|
|
127
|
+
continue;
|
|
128
|
+
// Check if the line properly assigns the error return
|
|
129
|
+
// Lines with "err" in them are considered handled
|
|
130
|
+
if (/\berr\b/.test(line))
|
|
131
|
+
continue;
|
|
132
|
+
// Lines that assign to _ (ignoring error) are fine
|
|
133
|
+
if (/:=\s*_\s*,/.test(line))
|
|
134
|
+
continue;
|
|
135
|
+
// Lines that are in a return statement using the result directly are ok
|
|
136
|
+
if (/return\s+.*(?:os\.|net\.|http\.|json\.|exec\.|ioutil\.)/.test(line))
|
|
137
|
+
continue;
|
|
138
|
+
// Lines in if conditions are ok (e.g., if err := ...)
|
|
139
|
+
if (/^\s*if\s/.test(line))
|
|
140
|
+
continue;
|
|
141
|
+
results.push({
|
|
142
|
+
detectorId: this.id,
|
|
143
|
+
severity: 'warning',
|
|
144
|
+
category: this.category,
|
|
145
|
+
messageKey: 'go-language-specific.unhandled-error-return',
|
|
146
|
+
message: 'Function that returns an error is called without proper error handling. AI-generated Go code commonly ignores error returns.',
|
|
147
|
+
file: unit.file,
|
|
148
|
+
line: unit.location.startLine + i + 1,
|
|
149
|
+
confidence: 0.7,
|
|
150
|
+
metadata: {
|
|
151
|
+
patternId: 'unhandled-error-return',
|
|
152
|
+
language: 'go',
|
|
153
|
+
matchedLine: line.substring(0, 100),
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
160
|
+
// Java-specific AI Detector
|
|
161
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
162
|
+
const JAVA_PATTERNS = [
|
|
163
|
+
{
|
|
164
|
+
id: 'java-system-out-println',
|
|
165
|
+
pattern: /\bSystem\.out\.println\s*\(/,
|
|
166
|
+
severity: 'warning',
|
|
167
|
+
confidence: 0.85,
|
|
168
|
+
message: 'System.out.println() used instead of a proper logging framework. AI frequently leaves debug prints in production code.',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: 'java-system-err-println',
|
|
172
|
+
pattern: /\bSystem\.err\.println\s*\(/,
|
|
173
|
+
severity: 'warning',
|
|
174
|
+
confidence: 0.85,
|
|
175
|
+
message: 'System.err.println() used instead of a proper logging framework.',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 'java-equals-without-null',
|
|
179
|
+
pattern: /\w+\.equals\s*\(\s*\w+\s*\)/,
|
|
180
|
+
severity: 'info',
|
|
181
|
+
confidence: 0.5,
|
|
182
|
+
message: 'String.equals() called on a variable that may be null. AI often writes this without null checks.',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'java-empty-catch',
|
|
186
|
+
pattern: /catch\s*\([^)]+\)\s*\{\s*\}/,
|
|
187
|
+
severity: 'warning',
|
|
188
|
+
confidence: 0.9,
|
|
189
|
+
message: 'Empty catch block — swallowing exceptions silently. AI commonly generates this pattern.',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: 'java-raw-type',
|
|
193
|
+
pattern: /(?:ArrayList|HashMap|LinkedList|HashSet|TreeMap|TreeSet|Vector|Hashtable|Stack)\s*<\s*>/,
|
|
194
|
+
severity: 'info',
|
|
195
|
+
confidence: 0.8,
|
|
196
|
+
message: 'Raw generic type used (diamond without type). Consider specifying the generic type parameter.',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'java-deprecated-date',
|
|
200
|
+
pattern: /\bnew\s+Date\s*\(\s*\)/,
|
|
201
|
+
severity: 'warning',
|
|
202
|
+
confidence: 0.8,
|
|
203
|
+
message: 'java.util.Date is outdated. Use java.time.LocalDateTime or java.time.Instant (Java 8+).',
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: 'java-deprecated-calendar',
|
|
207
|
+
pattern: /\bCalendar\.getInstance\s*\(\s*\)/,
|
|
208
|
+
severity: 'warning',
|
|
209
|
+
confidence: 0.8,
|
|
210
|
+
message: 'Calendar.getInstance() is outdated. Use java.time API (ZonedDateTime, LocalDate) instead.',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: 'java-string-concatenation-loop',
|
|
214
|
+
pattern: /for\s*\([^)]*\)\s*\{[^}]*\+=\s*['"]/,
|
|
215
|
+
severity: 'warning',
|
|
216
|
+
confidence: 0.65,
|
|
217
|
+
message: 'String concatenation inside a loop. Use StringBuilder instead. AI commonly makes this mistake.',
|
|
218
|
+
},
|
|
219
|
+
];
|
|
220
|
+
export class JavaLanguageDetector {
|
|
221
|
+
id = 'java-language-specific';
|
|
222
|
+
name = 'Java Language-Specific Detector';
|
|
223
|
+
category = 'implementation';
|
|
224
|
+
supportedLanguages = ['java'];
|
|
225
|
+
async detect(units, context) {
|
|
226
|
+
const results = [];
|
|
227
|
+
for (const unit of units) {
|
|
228
|
+
if (unit.language !== 'java')
|
|
229
|
+
continue;
|
|
230
|
+
if (!unit.source || unit.source.trim().length === 0)
|
|
231
|
+
continue;
|
|
232
|
+
const lines = unit.source.split('\n');
|
|
233
|
+
for (let i = 0; i < lines.length; i++) {
|
|
234
|
+
const line = lines[i];
|
|
235
|
+
const trimmed = line.trim();
|
|
236
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*') || trimmed.startsWith('*'))
|
|
237
|
+
continue;
|
|
238
|
+
for (const pat of JAVA_PATTERNS) {
|
|
239
|
+
pat.pattern.lastIndex = 0;
|
|
240
|
+
if (pat.pattern.test(line)) {
|
|
241
|
+
results.push({
|
|
242
|
+
detectorId: this.id,
|
|
243
|
+
severity: pat.severity,
|
|
244
|
+
category: this.category,
|
|
245
|
+
messageKey: `java-language-specific.${pat.id}`,
|
|
246
|
+
message: pat.message,
|
|
247
|
+
file: unit.file,
|
|
248
|
+
line: unit.location.startLine + i + 1,
|
|
249
|
+
confidence: pat.confidence,
|
|
250
|
+
metadata: {
|
|
251
|
+
patternId: pat.id,
|
|
252
|
+
language: 'java',
|
|
253
|
+
matchedLine: trimmed.substring(0, 100),
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Check source for multiline patterns (empty catch blocks span lines)
|
|
260
|
+
this.detectEmptyCatchBlocks(unit, results);
|
|
261
|
+
}
|
|
262
|
+
return results;
|
|
263
|
+
}
|
|
264
|
+
detectEmptyCatchBlocks(unit, results) {
|
|
265
|
+
// Match empty catch blocks: catch (...) { } possibly with whitespace
|
|
266
|
+
const emptyCatchPattern = /catch\s*\([^)]+\)\s*\{\s*\}/;
|
|
267
|
+
emptyCatchPattern.lastIndex = 0;
|
|
268
|
+
const match = emptyCatchPattern.exec(unit.source);
|
|
269
|
+
if (match) {
|
|
270
|
+
const lineNum = unit.source.substring(0, match.index).split('\n').length;
|
|
271
|
+
results.push({
|
|
272
|
+
detectorId: this.id,
|
|
273
|
+
severity: 'warning',
|
|
274
|
+
category: this.category,
|
|
275
|
+
messageKey: 'java-language-specific.java-empty-catch',
|
|
276
|
+
message: 'Empty catch block — swallowing exceptions silently. AI commonly generates this pattern.',
|
|
277
|
+
file: unit.file,
|
|
278
|
+
line: lineNum,
|
|
279
|
+
confidence: 0.9,
|
|
280
|
+
metadata: {
|
|
281
|
+
patternId: 'java-empty-catch',
|
|
282
|
+
language: 'java',
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
289
|
+
// Kotlin-specific AI Detector
|
|
290
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
291
|
+
const KOTLIN_PATTERNS = [
|
|
292
|
+
{
|
|
293
|
+
id: 'kotlin-bang-bang-chain',
|
|
294
|
+
pattern: /!!\s*\.\s*\w/,
|
|
295
|
+
severity: 'warning',
|
|
296
|
+
confidence: 0.8,
|
|
297
|
+
message: 'Chained non-null assertion (!!) detected. This defeats Kotlin\'s null safety. Use safe calls (?.) or explicit null checks.',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
id: 'kotlin-bang-bang-multiple',
|
|
301
|
+
pattern: /!!.*!!/,
|
|
302
|
+
severity: 'warning',
|
|
303
|
+
confidence: 0.85,
|
|
304
|
+
message: 'Multiple non-null assertions (!!) in one expression. AI often chains !! operators instead of handling nulls properly.',
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
id: 'kotlin-bare-println',
|
|
308
|
+
pattern: /\bprintln\s*\(/,
|
|
309
|
+
severity: 'info',
|
|
310
|
+
confidence: 0.7,
|
|
311
|
+
message: 'println() used instead of a logging framework. AI commonly leaves debug prints in production Kotlin code.',
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
id: 'kotlin-unnecessary-apply',
|
|
315
|
+
pattern: /\.\s*apply\s*\{\s*(?:\w+\s*=\s*\w+)\s*\}/,
|
|
316
|
+
severity: 'info',
|
|
317
|
+
confidence: 0.6,
|
|
318
|
+
message: 'apply {} with a single simple assignment. Direct assignment would be clearer.',
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
id: 'kotlin-empty-catch',
|
|
322
|
+
pattern: /catch\s*\([^)]+\)\s*\{\s*\}/,
|
|
323
|
+
severity: 'warning',
|
|
324
|
+
confidence: 0.9,
|
|
325
|
+
message: 'Empty catch block — silently swallowing exceptions. AI commonly generates this pattern.',
|
|
326
|
+
},
|
|
327
|
+
];
|
|
328
|
+
export class KotlinLanguageDetector {
|
|
329
|
+
id = 'kotlin-language-specific';
|
|
330
|
+
name = 'Kotlin Language-Specific Detector';
|
|
331
|
+
category = 'implementation';
|
|
332
|
+
supportedLanguages = ['kotlin'];
|
|
333
|
+
async detect(units, context) {
|
|
334
|
+
const results = [];
|
|
335
|
+
for (const unit of units) {
|
|
336
|
+
if (unit.language !== 'kotlin')
|
|
337
|
+
continue;
|
|
338
|
+
if (!unit.source || unit.source.trim().length === 0)
|
|
339
|
+
continue;
|
|
340
|
+
const lines = unit.source.split('\n');
|
|
341
|
+
for (let i = 0; i < lines.length; i++) {
|
|
342
|
+
const line = lines[i];
|
|
343
|
+
const trimmed = line.trim();
|
|
344
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*'))
|
|
345
|
+
continue;
|
|
346
|
+
for (const pat of KOTLIN_PATTERNS) {
|
|
347
|
+
pat.pattern.lastIndex = 0;
|
|
348
|
+
if (pat.pattern.test(line)) {
|
|
349
|
+
results.push({
|
|
350
|
+
detectorId: this.id,
|
|
351
|
+
severity: pat.severity,
|
|
352
|
+
category: this.category,
|
|
353
|
+
messageKey: `kotlin-language-specific.${pat.id}`,
|
|
354
|
+
message: pat.message,
|
|
355
|
+
file: unit.file,
|
|
356
|
+
line: unit.location.startLine + i + 1,
|
|
357
|
+
confidence: pat.confidence,
|
|
358
|
+
metadata: {
|
|
359
|
+
patternId: pat.id,
|
|
360
|
+
language: 'kotlin',
|
|
361
|
+
matchedLine: trimmed.substring(0, 100),
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// Detect !!. chains across lines (multiline)
|
|
368
|
+
this.detectBangBangChains(unit, lines, results);
|
|
369
|
+
// Check source for multiline patterns (empty catch blocks span lines)
|
|
370
|
+
this.detectEmptyCatchBlocks(unit, results);
|
|
371
|
+
}
|
|
372
|
+
return results;
|
|
373
|
+
}
|
|
374
|
+
detectEmptyCatchBlocks(unit, results) {
|
|
375
|
+
const emptyCatchPattern = /catch\s*\([^)]+\)\s*\{\s*\}/;
|
|
376
|
+
emptyCatchPattern.lastIndex = 0;
|
|
377
|
+
const match = emptyCatchPattern.exec(unit.source);
|
|
378
|
+
if (match) {
|
|
379
|
+
const lineNum = unit.source.substring(0, match.index).split('\n').length;
|
|
380
|
+
results.push({
|
|
381
|
+
detectorId: this.id,
|
|
382
|
+
severity: 'warning',
|
|
383
|
+
category: this.category,
|
|
384
|
+
messageKey: 'kotlin-language-specific.kotlin-empty-catch',
|
|
385
|
+
message: 'Empty catch block — silently swallowing exceptions. AI commonly generates this pattern.',
|
|
386
|
+
file: unit.file,
|
|
387
|
+
line: lineNum,
|
|
388
|
+
confidence: 0.9,
|
|
389
|
+
metadata: {
|
|
390
|
+
patternId: 'kotlin-empty-catch',
|
|
391
|
+
language: 'kotlin',
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
detectBangBangChains(unit, lines, results) {
|
|
397
|
+
// Count !! occurrences in each function/method unit
|
|
398
|
+
const bangBangCount = unit.source.match(/!!/g)?.length ?? 0;
|
|
399
|
+
if (bangBangCount >= 3) {
|
|
400
|
+
// Find the first occurrence
|
|
401
|
+
for (let i = 0; i < lines.length; i++) {
|
|
402
|
+
if (lines[i].includes('!!')) {
|
|
403
|
+
results.push({
|
|
404
|
+
detectorId: this.id,
|
|
405
|
+
severity: 'warning',
|
|
406
|
+
category: this.category,
|
|
407
|
+
messageKey: 'kotlin-language-specific.excessive-bang-bang',
|
|
408
|
+
message: `Found ${bangBangCount} non-null assertions (!!) in this unit. AI often overuses !! instead of proper null handling.`,
|
|
409
|
+
file: unit.file,
|
|
410
|
+
line: unit.location.startLine + i + 1,
|
|
411
|
+
confidence: 0.8,
|
|
412
|
+
metadata: {
|
|
413
|
+
patternId: 'excessive-bang-bang',
|
|
414
|
+
language: 'kotlin',
|
|
415
|
+
count: bangBangCount,
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
break; // Only report once per unit
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
425
|
+
// Python-specific AI Detector
|
|
426
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
427
|
+
const PYTHON_PATTERNS = [
|
|
428
|
+
{
|
|
429
|
+
id: 'python-bare-except',
|
|
430
|
+
pattern: /\bexcept\s*:/,
|
|
431
|
+
severity: 'warning',
|
|
432
|
+
confidence: 0.9,
|
|
433
|
+
message: 'Bare except: catches all exceptions including SystemExit and KeyboardInterrupt. Use except Exception: instead.',
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: 'python-eval-usage',
|
|
437
|
+
pattern: /\beval\s*\(/,
|
|
438
|
+
severity: 'error',
|
|
439
|
+
confidence: 0.9,
|
|
440
|
+
message: 'eval() usage detected — enables arbitrary code execution. Use ast.literal_eval() for safe evaluation.',
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
id: 'python-exec-usage',
|
|
444
|
+
pattern: /\bexec\s*\(/,
|
|
445
|
+
severity: 'error',
|
|
446
|
+
confidence: 0.85,
|
|
447
|
+
message: 'exec() usage detected — enables arbitrary code execution. Consider safer alternatives.',
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
id: 'python-deprecated-urlparse',
|
|
451
|
+
pattern: /\bfrom\s+urllib\.parse\s+import\s+urlparse\b/,
|
|
452
|
+
severity: 'info',
|
|
453
|
+
confidence: 0.5,
|
|
454
|
+
message: 'urlparse import detected. Note: urlparse is still valid in Python 3; however, AI sometimes confuses urlparse with urlsplit.',
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
id: 'python-mutable-default-arg',
|
|
458
|
+
pattern: /def\s+\w+\s*\([^)]*(?:=\s*\[\]|\s*=\s*\{\})\s*\)/,
|
|
459
|
+
severity: 'warning',
|
|
460
|
+
confidence: 0.85,
|
|
461
|
+
message: 'Mutable default argument (list/dict) detected. This is a common Python gotcha — use None as default and initialize inside the function.',
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
id: 'python-global-variable',
|
|
465
|
+
pattern: /\bglobal\s+\w+/,
|
|
466
|
+
severity: 'info',
|
|
467
|
+
confidence: 0.5,
|
|
468
|
+
message: 'global keyword used. Excessive use of global state is an anti-pattern common in AI-generated code.',
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
id: 'python-pass-in-except',
|
|
472
|
+
pattern: /\bexcept\s+.*?:\s*\n\s*pass/,
|
|
473
|
+
severity: 'warning',
|
|
474
|
+
confidence: 0.85,
|
|
475
|
+
message: 'except block with only pass — silently swallowing exceptions. AI commonly generates this pattern.',
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
id: 'python-os-system',
|
|
479
|
+
pattern: /\bos\.system\s*\(/,
|
|
480
|
+
severity: 'warning',
|
|
481
|
+
confidence: 0.75,
|
|
482
|
+
message: 'os.system() used instead of subprocess. Use subprocess.run() for better control and security.',
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
id: 'python-pickle-load',
|
|
486
|
+
pattern: /\bpickle\.load(?:s)?\s*\(/,
|
|
487
|
+
severity: 'error',
|
|
488
|
+
confidence: 0.8,
|
|
489
|
+
message: 'pickle.load() can execute arbitrary code. Use json or safer serialization for untrusted data.',
|
|
490
|
+
},
|
|
491
|
+
];
|
|
492
|
+
export class PythonLanguageDetector {
|
|
493
|
+
id = 'python-language-specific';
|
|
494
|
+
name = 'Python Language-Specific Detector';
|
|
495
|
+
category = 'implementation';
|
|
496
|
+
supportedLanguages = ['python'];
|
|
497
|
+
async detect(units, context) {
|
|
498
|
+
const results = [];
|
|
499
|
+
for (const unit of units) {
|
|
500
|
+
if (unit.language !== 'python')
|
|
501
|
+
continue;
|
|
502
|
+
if (!unit.source || unit.source.trim().length === 0)
|
|
503
|
+
continue;
|
|
504
|
+
const lines = unit.source.split('\n');
|
|
505
|
+
for (let i = 0; i < lines.length; i++) {
|
|
506
|
+
const line = lines[i];
|
|
507
|
+
const trimmed = line.trim();
|
|
508
|
+
if (trimmed.startsWith('#') || trimmed.startsWith('"""') || trimmed.startsWith("'''"))
|
|
509
|
+
continue;
|
|
510
|
+
for (const pat of PYTHON_PATTERNS) {
|
|
511
|
+
pat.pattern.lastIndex = 0;
|
|
512
|
+
if (pat.pattern.test(line)) {
|
|
513
|
+
results.push({
|
|
514
|
+
detectorId: this.id,
|
|
515
|
+
severity: pat.severity,
|
|
516
|
+
category: this.category,
|
|
517
|
+
messageKey: `python-language-specific.${pat.id}`,
|
|
518
|
+
message: pat.message,
|
|
519
|
+
file: unit.file,
|
|
520
|
+
line: unit.location.startLine + i + 1,
|
|
521
|
+
confidence: pat.confidence,
|
|
522
|
+
metadata: {
|
|
523
|
+
patternId: pat.id,
|
|
524
|
+
language: 'python',
|
|
525
|
+
matchedLine: trimmed.substring(0, 100),
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
// Multiline mutable default arg detection
|
|
532
|
+
this.detectMultilinePatterns(unit, results);
|
|
533
|
+
}
|
|
534
|
+
return results;
|
|
535
|
+
}
|
|
536
|
+
detectMultilinePatterns(unit, results) {
|
|
537
|
+
const source = unit.source;
|
|
538
|
+
// Detect except ... pass pattern across lines
|
|
539
|
+
const exceptPassMatches = source.matchAll(/except\s+(\w+)\s*:\s*\n\s*pass/g);
|
|
540
|
+
for (const match of exceptPassMatches) {
|
|
541
|
+
const lineNum = source.substring(0, match.index).split('\n').length;
|
|
542
|
+
results.push({
|
|
543
|
+
detectorId: this.id,
|
|
544
|
+
severity: 'warning',
|
|
545
|
+
category: this.category,
|
|
546
|
+
messageKey: 'python-language-specific.except-with-pass',
|
|
547
|
+
message: `except ${match[1]} with only pass — silently swallowing exceptions. Log the exception or handle it properly.`,
|
|
548
|
+
file: unit.file,
|
|
549
|
+
line: lineNum,
|
|
550
|
+
confidence: 0.85,
|
|
551
|
+
metadata: {
|
|
552
|
+
patternId: 'except-with-pass',
|
|
553
|
+
language: 'python',
|
|
554
|
+
exceptionType: match[1],
|
|
555
|
+
},
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
//# sourceMappingURL=language-specific.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-specific.js","sourceRoot":"","sources":["../../../src/detectors/v4/language-specific.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-pattern.d.ts","sourceRoot":"","sources":["../../../src/detectors/v4/security-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIhG,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;
|
|
1
|
+
{"version":3,"file":"security-pattern.d.ts","sourceRoot":"","sources":["../../../src/detectors/v4/security-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIhG,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;AA2QD,qBAAa,uBAAwB,YAAW,UAAU;IACxD,QAAQ,CAAC,EAAE,sBAAsB;IACjC,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAoB;IACvD,QAAQ,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,CAAM;IAEhD,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CA4DrF"}
|