slopbrick 0.34.9 → 0.35.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/engine/worker.cjs +79 -4
- package/dist/engine/worker.js +79 -4
- package/dist/index.cjs +90 -5
- package/dist/index.js +90 -5
- package/package.json +1 -1
package/dist/engine/worker.cjs
CHANGED
|
@@ -37185,6 +37185,61 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37185
37185
|
}
|
|
37186
37186
|
});
|
|
37187
37187
|
|
|
37188
|
+
// src/rules/java/suspicious-implementation.ts
|
|
37189
|
+
var STRONG_VERB_REGEX = /(?:validate|validates|validated|verifies?|verify|check|checks?|checked|ensures?|ensure|ensured|verifies|verified|sanitize|sanitizes|sanitized|escape|escapes|escaped|authenticate|authenticates|authenticated|authorize|authorizes|authorized|audit|audits|audited|inspect|inspects|inspected|filter|filters?|filtered|normalize|normalizes|normalized|encrypt|encrypts|encrypted|decrypt|decrypts|decrypted|hash|hashes|hashed|sign|signs?|signed|compress|compresses|compressed|decompress|decompresses|decompressed|parse|parses|parsed|format|formats?|formatted)(?=[A-Z]|[^a-zA-Z]|$)/i;
|
|
37190
|
+
var METHOD_DECL_REGEX = /(?:public|private|protected)\s+(?:static\s+)?[\w<>,\s\[\]]+?\s+(\w+)\s*\([^)]*\)\s*\{([^{}]*)\}/g;
|
|
37191
|
+
var EMPTY_BODY_REGEX = /^\s*$/;
|
|
37192
|
+
var RETURN_CONSTANT_REGEX = /^\s*return\s+(?:null|true|false|0|1|0L|0\.0|"")\s*;\s*$/;
|
|
37193
|
+
var RETURN_INPUT_REGEX = /^\s*return\s+(\w+)\s*;\s*$/;
|
|
37194
|
+
var JUST_THROW_REGEX = /^\s*throw\s+new\s+(?:UnsupportedOperationException|UnsupportedOperationException\([^)]*\)|RuntimeException\([^)]*\)|IllegalStateException\([^)]*\))\s*;\s*$/;
|
|
37195
|
+
var javaSuspiciousImplementationRule = createRule({
|
|
37196
|
+
id: "java/suspicious-implementation",
|
|
37197
|
+
category: "security",
|
|
37198
|
+
severity: "high",
|
|
37199
|
+
aiSpecific: false,
|
|
37200
|
+
description: "function name suggests validation/encryption/auth but body is empty or trivially wrong \u2014 content mismatch",
|
|
37201
|
+
create(_context) {
|
|
37202
|
+
return {};
|
|
37203
|
+
},
|
|
37204
|
+
analyze(_context, facts) {
|
|
37205
|
+
const issues = [];
|
|
37206
|
+
const source = facts.v2?._source;
|
|
37207
|
+
if (!source) return issues;
|
|
37208
|
+
if (!/\.java$/i.test(facts.filePath)) return issues;
|
|
37209
|
+
if (/\/test\//i.test(facts.filePath) || /\/src\/test\//i.test(facts.filePath)) return issues;
|
|
37210
|
+
let m;
|
|
37211
|
+
METHOD_DECL_REGEX.lastIndex = 0;
|
|
37212
|
+
while ((m = METHOD_DECL_REGEX.exec(source)) !== null) {
|
|
37213
|
+
const methodName = m[1];
|
|
37214
|
+
const body = m[2];
|
|
37215
|
+
if (!STRONG_VERB_REGEX.test(methodName)) continue;
|
|
37216
|
+
let reason = null;
|
|
37217
|
+
if (EMPTY_BODY_REGEX.test(body)) {
|
|
37218
|
+
reason = "empty body";
|
|
37219
|
+
} else if (RETURN_CONSTANT_REGEX.test(body)) {
|
|
37220
|
+
reason = "returns a constant (null/true/false/0/1)";
|
|
37221
|
+
} else if (RETURN_INPUT_REGEX.test(body)) {
|
|
37222
|
+
reason = "returns the input unchanged (pass-through stub)";
|
|
37223
|
+
} else if (JUST_THROW_REGEX.test(body)) {
|
|
37224
|
+
reason = "throws UnsupportedOperationException \u2014 not implemented";
|
|
37225
|
+
}
|
|
37226
|
+
if (!reason) continue;
|
|
37227
|
+
const line = source.slice(0, m.index).split("\n").length;
|
|
37228
|
+
issues.push({
|
|
37229
|
+
ruleId: "java/suspicious-implementation",
|
|
37230
|
+
category: "security",
|
|
37231
|
+
severity: "high",
|
|
37232
|
+
aiSpecific: false,
|
|
37233
|
+
message: `function ${methodName} (${reason}) \u2014 content-based mismatch`,
|
|
37234
|
+
line,
|
|
37235
|
+
column: 1,
|
|
37236
|
+
advice: `The function name "${methodName}" suggests a real validation/encryption/auth/filter operation, but the body is ${reason}. This is a content mismatch \u2014 the code's claimed behavior doesn't match its actual behavior. Real production code that ships this is a silent security failure (OWASP A04:2021 \u2014 Insecure Design). The fix is to either implement the operation or rename the function to reflect what it actually does. Reference: java/suspicious-implementation v0.35.0 (CoCoNUTS-inspired content-based detection).`
|
|
37237
|
+
});
|
|
37238
|
+
}
|
|
37239
|
+
return issues;
|
|
37240
|
+
}
|
|
37241
|
+
});
|
|
37242
|
+
|
|
37188
37243
|
// src/rules/java/system-out-println.ts
|
|
37189
37244
|
var SYSTEM_OUT_REGEX = /\bSystem\.out\.println\s*\(/g;
|
|
37190
37245
|
var REAL_LOGGING_IMPORT_REGEX = /\bimport\s+(?:org\.slf4j\.|org\.apache\.logging\.log4j|org\.apache\.log4j|java\.util\.logging|com\.google\.common\.logging)/;
|
|
@@ -40568,7 +40623,7 @@ var swiftFatalErrorThrownRule = createRule({
|
|
|
40568
40623
|
|
|
40569
40624
|
// src/rules/swift/force-unwrap.ts
|
|
40570
40625
|
var AS_FORCE_REGEX = /\bas!\s+/g;
|
|
40571
|
-
var ACCESS_FORCE_REGEX = /(
|
|
40626
|
+
var ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
40572
40627
|
var TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
40573
40628
|
var swiftForceUnwrapRule = createRule({
|
|
40574
40629
|
id: "swift/force-unwrap",
|
|
@@ -40595,7 +40650,7 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40595
40650
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
40596
40651
|
line,
|
|
40597
40652
|
column: 1,
|
|
40598
|
-
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.
|
|
40653
|
+
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
40599
40654
|
});
|
|
40600
40655
|
};
|
|
40601
40656
|
let m;
|
|
@@ -40604,7 +40659,10 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40604
40659
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
40605
40660
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
40606
40661
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
40607
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
40662
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
40663
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
40664
|
+
emit(bangOffset, "!.");
|
|
40665
|
+
}
|
|
40608
40666
|
return issues;
|
|
40609
40667
|
}
|
|
40610
40668
|
});
|
|
@@ -43318,6 +43376,7 @@ var builtinRules = [
|
|
|
43318
43376
|
javaCommandInjectionRule,
|
|
43319
43377
|
javaHardcodedCredentialRule,
|
|
43320
43378
|
javaSqlStringConcatRule,
|
|
43379
|
+
javaSuspiciousImplementationRule,
|
|
43321
43380
|
javaSystemOutPrintlnRule,
|
|
43322
43381
|
javaThreadSleepInLoopRule,
|
|
43323
43382
|
kotlinCoroutineGlobalScopeRule,
|
|
@@ -45707,6 +45766,22 @@ var signal_strength_default = {
|
|
|
45707
45766
|
_v9Precision: 0,
|
|
45708
45767
|
defaultOff: true
|
|
45709
45768
|
},
|
|
45769
|
+
"java/suspicious-implementation": {
|
|
45770
|
+
recall: 0,
|
|
45771
|
+
fpRate: 0,
|
|
45772
|
+
ratio: 0,
|
|
45773
|
+
precision: 0,
|
|
45774
|
+
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45775
|
+
verdict: "OK",
|
|
45776
|
+
_calibrationNote: "v0.35.0: NEW RULE \u2014 content-based detection (CoCoNUTS-inspired). Detects function names that claim a strong operation (validate, encrypt, hash, sanitize, check, verify, authenticate, etc.) but whose body is trivially empty, returns a constant, or returns the input unchanged. The rule is a real engineering defect detector (not AI fingerprint), so it is defaultOff=false (i.e. ON by default) and verdict=OK. The CoCoNUTS paper (2025) showed that style-based AI-detectors fail under paraphrasing; this rule looks at semantic content (function body behavior) rather than surface features. v9 calibration is pending \u2014 the rule was added at the end of the v0.34.X refinement series and has not been measured against the v9 corpus yet. The expected impact: low recall (most production code doesn't have these stubs) but high precision (when it fires, it's a real bug). The full v9 calibration is the next step for v0.35.0.x patches.",
|
|
45777
|
+
aiSpecific: false,
|
|
45778
|
+
_v9Verdict: "OK",
|
|
45779
|
+
_v9Lift: 0,
|
|
45780
|
+
_v9Recall: 0,
|
|
45781
|
+
_v9FpRate: 0,
|
|
45782
|
+
_v9Precision: 0,
|
|
45783
|
+
defaultOff: false
|
|
45784
|
+
},
|
|
45710
45785
|
"swift/force-unwrap": {
|
|
45711
45786
|
recall: 0.10211,
|
|
45712
45787
|
fpRate: 0.21462,
|
|
@@ -45714,7 +45789,7 @@ var signal_strength_default = {
|
|
|
45714
45789
|
precision: 0.1721,
|
|
45715
45790
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45716
45791
|
verdict: "DORMANT",
|
|
45717
|
-
_calibrationNote: "v0.
|
|
45792
|
+
_calibrationNote: "v0.34.10: REFINED \u2014 the access-force regex now uses a negative lookbehind to exclude `!` in `!=` and `!==` comparison operators. Per-file unique v9 Swift calibration (1300 neg, 568 pos): 58 TP files, 279 FP files, ratio=0.48 (DORMANT). The previous regex incorrectly fired on `!` in `a != b` and `a !== b` patterns, which are common in control flow. The refinement is expected to push precision from 17.2% to 25%+ by removing these false positives. Era-confounded: pre-2022 Swift used `!` freely (the only way to unwrap); modern Swift uses `guard let` / `if let` / `try?`. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
|
|
45718
45793
|
aiSpecific: true,
|
|
45719
45794
|
_v7Verdict: "DORMANT",
|
|
45720
45795
|
_v7Lift: 1,
|
package/dist/engine/worker.js
CHANGED
|
@@ -37156,6 +37156,61 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37156
37156
|
}
|
|
37157
37157
|
});
|
|
37158
37158
|
|
|
37159
|
+
// src/rules/java/suspicious-implementation.ts
|
|
37160
|
+
var STRONG_VERB_REGEX = /(?:validate|validates|validated|verifies?|verify|check|checks?|checked|ensures?|ensure|ensured|verifies|verified|sanitize|sanitizes|sanitized|escape|escapes|escaped|authenticate|authenticates|authenticated|authorize|authorizes|authorized|audit|audits|audited|inspect|inspects|inspected|filter|filters?|filtered|normalize|normalizes|normalized|encrypt|encrypts|encrypted|decrypt|decrypts|decrypted|hash|hashes|hashed|sign|signs?|signed|compress|compresses|compressed|decompress|decompresses|decompressed|parse|parses|parsed|format|formats?|formatted)(?=[A-Z]|[^a-zA-Z]|$)/i;
|
|
37161
|
+
var METHOD_DECL_REGEX = /(?:public|private|protected)\s+(?:static\s+)?[\w<>,\s\[\]]+?\s+(\w+)\s*\([^)]*\)\s*\{([^{}]*)\}/g;
|
|
37162
|
+
var EMPTY_BODY_REGEX = /^\s*$/;
|
|
37163
|
+
var RETURN_CONSTANT_REGEX = /^\s*return\s+(?:null|true|false|0|1|0L|0\.0|"")\s*;\s*$/;
|
|
37164
|
+
var RETURN_INPUT_REGEX = /^\s*return\s+(\w+)\s*;\s*$/;
|
|
37165
|
+
var JUST_THROW_REGEX = /^\s*throw\s+new\s+(?:UnsupportedOperationException|UnsupportedOperationException\([^)]*\)|RuntimeException\([^)]*\)|IllegalStateException\([^)]*\))\s*;\s*$/;
|
|
37166
|
+
var javaSuspiciousImplementationRule = createRule({
|
|
37167
|
+
id: "java/suspicious-implementation",
|
|
37168
|
+
category: "security",
|
|
37169
|
+
severity: "high",
|
|
37170
|
+
aiSpecific: false,
|
|
37171
|
+
description: "function name suggests validation/encryption/auth but body is empty or trivially wrong \u2014 content mismatch",
|
|
37172
|
+
create(_context) {
|
|
37173
|
+
return {};
|
|
37174
|
+
},
|
|
37175
|
+
analyze(_context, facts) {
|
|
37176
|
+
const issues = [];
|
|
37177
|
+
const source = facts.v2?._source;
|
|
37178
|
+
if (!source) return issues;
|
|
37179
|
+
if (!/\.java$/i.test(facts.filePath)) return issues;
|
|
37180
|
+
if (/\/test\//i.test(facts.filePath) || /\/src\/test\//i.test(facts.filePath)) return issues;
|
|
37181
|
+
let m;
|
|
37182
|
+
METHOD_DECL_REGEX.lastIndex = 0;
|
|
37183
|
+
while ((m = METHOD_DECL_REGEX.exec(source)) !== null) {
|
|
37184
|
+
const methodName = m[1];
|
|
37185
|
+
const body = m[2];
|
|
37186
|
+
if (!STRONG_VERB_REGEX.test(methodName)) continue;
|
|
37187
|
+
let reason = null;
|
|
37188
|
+
if (EMPTY_BODY_REGEX.test(body)) {
|
|
37189
|
+
reason = "empty body";
|
|
37190
|
+
} else if (RETURN_CONSTANT_REGEX.test(body)) {
|
|
37191
|
+
reason = "returns a constant (null/true/false/0/1)";
|
|
37192
|
+
} else if (RETURN_INPUT_REGEX.test(body)) {
|
|
37193
|
+
reason = "returns the input unchanged (pass-through stub)";
|
|
37194
|
+
} else if (JUST_THROW_REGEX.test(body)) {
|
|
37195
|
+
reason = "throws UnsupportedOperationException \u2014 not implemented";
|
|
37196
|
+
}
|
|
37197
|
+
if (!reason) continue;
|
|
37198
|
+
const line = source.slice(0, m.index).split("\n").length;
|
|
37199
|
+
issues.push({
|
|
37200
|
+
ruleId: "java/suspicious-implementation",
|
|
37201
|
+
category: "security",
|
|
37202
|
+
severity: "high",
|
|
37203
|
+
aiSpecific: false,
|
|
37204
|
+
message: `function ${methodName} (${reason}) \u2014 content-based mismatch`,
|
|
37205
|
+
line,
|
|
37206
|
+
column: 1,
|
|
37207
|
+
advice: `The function name "${methodName}" suggests a real validation/encryption/auth/filter operation, but the body is ${reason}. This is a content mismatch \u2014 the code's claimed behavior doesn't match its actual behavior. Real production code that ships this is a silent security failure (OWASP A04:2021 \u2014 Insecure Design). The fix is to either implement the operation or rename the function to reflect what it actually does. Reference: java/suspicious-implementation v0.35.0 (CoCoNUTS-inspired content-based detection).`
|
|
37208
|
+
});
|
|
37209
|
+
}
|
|
37210
|
+
return issues;
|
|
37211
|
+
}
|
|
37212
|
+
});
|
|
37213
|
+
|
|
37159
37214
|
// src/rules/java/system-out-println.ts
|
|
37160
37215
|
var SYSTEM_OUT_REGEX = /\bSystem\.out\.println\s*\(/g;
|
|
37161
37216
|
var REAL_LOGGING_IMPORT_REGEX = /\bimport\s+(?:org\.slf4j\.|org\.apache\.logging\.log4j|org\.apache\.log4j|java\.util\.logging|com\.google\.common\.logging)/;
|
|
@@ -40539,7 +40594,7 @@ var swiftFatalErrorThrownRule = createRule({
|
|
|
40539
40594
|
|
|
40540
40595
|
// src/rules/swift/force-unwrap.ts
|
|
40541
40596
|
var AS_FORCE_REGEX = /\bas!\s+/g;
|
|
40542
|
-
var ACCESS_FORCE_REGEX = /(
|
|
40597
|
+
var ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
40543
40598
|
var TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
40544
40599
|
var swiftForceUnwrapRule = createRule({
|
|
40545
40600
|
id: "swift/force-unwrap",
|
|
@@ -40566,7 +40621,7 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40566
40621
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
40567
40622
|
line,
|
|
40568
40623
|
column: 1,
|
|
40569
|
-
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.
|
|
40624
|
+
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
40570
40625
|
});
|
|
40571
40626
|
};
|
|
40572
40627
|
let m;
|
|
@@ -40575,7 +40630,10 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40575
40630
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
40576
40631
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
40577
40632
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
40578
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
40633
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
40634
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
40635
|
+
emit(bangOffset, "!.");
|
|
40636
|
+
}
|
|
40579
40637
|
return issues;
|
|
40580
40638
|
}
|
|
40581
40639
|
});
|
|
@@ -43289,6 +43347,7 @@ var builtinRules = [
|
|
|
43289
43347
|
javaCommandInjectionRule,
|
|
43290
43348
|
javaHardcodedCredentialRule,
|
|
43291
43349
|
javaSqlStringConcatRule,
|
|
43350
|
+
javaSuspiciousImplementationRule,
|
|
43292
43351
|
javaSystemOutPrintlnRule,
|
|
43293
43352
|
javaThreadSleepInLoopRule,
|
|
43294
43353
|
kotlinCoroutineGlobalScopeRule,
|
|
@@ -45678,6 +45737,22 @@ var signal_strength_default = {
|
|
|
45678
45737
|
_v9Precision: 0,
|
|
45679
45738
|
defaultOff: true
|
|
45680
45739
|
},
|
|
45740
|
+
"java/suspicious-implementation": {
|
|
45741
|
+
recall: 0,
|
|
45742
|
+
fpRate: 0,
|
|
45743
|
+
ratio: 0,
|
|
45744
|
+
precision: 0,
|
|
45745
|
+
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45746
|
+
verdict: "OK",
|
|
45747
|
+
_calibrationNote: "v0.35.0: NEW RULE \u2014 content-based detection (CoCoNUTS-inspired). Detects function names that claim a strong operation (validate, encrypt, hash, sanitize, check, verify, authenticate, etc.) but whose body is trivially empty, returns a constant, or returns the input unchanged. The rule is a real engineering defect detector (not AI fingerprint), so it is defaultOff=false (i.e. ON by default) and verdict=OK. The CoCoNUTS paper (2025) showed that style-based AI-detectors fail under paraphrasing; this rule looks at semantic content (function body behavior) rather than surface features. v9 calibration is pending \u2014 the rule was added at the end of the v0.34.X refinement series and has not been measured against the v9 corpus yet. The expected impact: low recall (most production code doesn't have these stubs) but high precision (when it fires, it's a real bug). The full v9 calibration is the next step for v0.35.0.x patches.",
|
|
45748
|
+
aiSpecific: false,
|
|
45749
|
+
_v9Verdict: "OK",
|
|
45750
|
+
_v9Lift: 0,
|
|
45751
|
+
_v9Recall: 0,
|
|
45752
|
+
_v9FpRate: 0,
|
|
45753
|
+
_v9Precision: 0,
|
|
45754
|
+
defaultOff: false
|
|
45755
|
+
},
|
|
45681
45756
|
"swift/force-unwrap": {
|
|
45682
45757
|
recall: 0.10211,
|
|
45683
45758
|
fpRate: 0.21462,
|
|
@@ -45685,7 +45760,7 @@ var signal_strength_default = {
|
|
|
45685
45760
|
precision: 0.1721,
|
|
45686
45761
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45687
45762
|
verdict: "DORMANT",
|
|
45688
|
-
_calibrationNote: "v0.
|
|
45763
|
+
_calibrationNote: "v0.34.10: REFINED \u2014 the access-force regex now uses a negative lookbehind to exclude `!` in `!=` and `!==` comparison operators. Per-file unique v9 Swift calibration (1300 neg, 568 pos): 58 TP files, 279 FP files, ratio=0.48 (DORMANT). The previous regex incorrectly fired on `!` in `a != b` and `a !== b` patterns, which are common in control flow. The refinement is expected to push precision from 17.2% to 25%+ by removing these false positives. Era-confounded: pre-2022 Swift used `!` freely (the only way to unwrap); modern Swift uses `guard let` / `if let` / `try?`. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
|
|
45689
45764
|
aiSpecific: true,
|
|
45690
45765
|
_v7Verdict: "DORMANT",
|
|
45691
45766
|
_v7Lift: 1,
|
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,7 @@ var VERSION;
|
|
|
36
36
|
var init_header = __esm({
|
|
37
37
|
"src/types/_header.ts"() {
|
|
38
38
|
"use strict";
|
|
39
|
-
VERSION = "0.
|
|
39
|
+
VERSION = "0.35.0";
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -30850,6 +30850,68 @@ var init_sql_string_concat = __esm({
|
|
|
30850
30850
|
}
|
|
30851
30851
|
});
|
|
30852
30852
|
|
|
30853
|
+
// src/rules/java/suspicious-implementation.ts
|
|
30854
|
+
var STRONG_VERB_REGEX, METHOD_DECL_REGEX, EMPTY_BODY_REGEX, RETURN_CONSTANT_REGEX, RETURN_INPUT_REGEX, JUST_THROW_REGEX, javaSuspiciousImplementationRule;
|
|
30855
|
+
var init_suspicious_implementation = __esm({
|
|
30856
|
+
"src/rules/java/suspicious-implementation.ts"() {
|
|
30857
|
+
"use strict";
|
|
30858
|
+
init_rule();
|
|
30859
|
+
STRONG_VERB_REGEX = /(?:validate|validates|validated|verifies?|verify|check|checks?|checked|ensures?|ensure|ensured|verifies|verified|sanitize|sanitizes|sanitized|escape|escapes|escaped|authenticate|authenticates|authenticated|authorize|authorizes|authorized|audit|audits|audited|inspect|inspects|inspected|filter|filters?|filtered|normalize|normalizes|normalized|encrypt|encrypts|encrypted|decrypt|decrypts|decrypted|hash|hashes|hashed|sign|signs?|signed|compress|compresses|compressed|decompress|decompresses|decompressed|parse|parses|parsed|format|formats?|formatted)(?=[A-Z]|[^a-zA-Z]|$)/i;
|
|
30860
|
+
METHOD_DECL_REGEX = /(?:public|private|protected)\s+(?:static\s+)?[\w<>,\s\[\]]+?\s+(\w+)\s*\([^)]*\)\s*\{([^{}]*)\}/g;
|
|
30861
|
+
EMPTY_BODY_REGEX = /^\s*$/;
|
|
30862
|
+
RETURN_CONSTANT_REGEX = /^\s*return\s+(?:null|true|false|0|1|0L|0\.0|"")\s*;\s*$/;
|
|
30863
|
+
RETURN_INPUT_REGEX = /^\s*return\s+(\w+)\s*;\s*$/;
|
|
30864
|
+
JUST_THROW_REGEX = /^\s*throw\s+new\s+(?:UnsupportedOperationException|UnsupportedOperationException\([^)]*\)|RuntimeException\([^)]*\)|IllegalStateException\([^)]*\))\s*;\s*$/;
|
|
30865
|
+
javaSuspiciousImplementationRule = createRule({
|
|
30866
|
+
id: "java/suspicious-implementation",
|
|
30867
|
+
category: "security",
|
|
30868
|
+
severity: "high",
|
|
30869
|
+
aiSpecific: false,
|
|
30870
|
+
description: "function name suggests validation/encryption/auth but body is empty or trivially wrong \u2014 content mismatch",
|
|
30871
|
+
create(_context) {
|
|
30872
|
+
return {};
|
|
30873
|
+
},
|
|
30874
|
+
analyze(_context, facts) {
|
|
30875
|
+
const issues = [];
|
|
30876
|
+
const source = facts.v2?._source;
|
|
30877
|
+
if (!source) return issues;
|
|
30878
|
+
if (!/\.java$/i.test(facts.filePath)) return issues;
|
|
30879
|
+
if (/\/test\//i.test(facts.filePath) || /\/src\/test\//i.test(facts.filePath)) return issues;
|
|
30880
|
+
let m;
|
|
30881
|
+
METHOD_DECL_REGEX.lastIndex = 0;
|
|
30882
|
+
while ((m = METHOD_DECL_REGEX.exec(source)) !== null) {
|
|
30883
|
+
const methodName = m[1];
|
|
30884
|
+
const body = m[2];
|
|
30885
|
+
if (!STRONG_VERB_REGEX.test(methodName)) continue;
|
|
30886
|
+
let reason = null;
|
|
30887
|
+
if (EMPTY_BODY_REGEX.test(body)) {
|
|
30888
|
+
reason = "empty body";
|
|
30889
|
+
} else if (RETURN_CONSTANT_REGEX.test(body)) {
|
|
30890
|
+
reason = "returns a constant (null/true/false/0/1)";
|
|
30891
|
+
} else if (RETURN_INPUT_REGEX.test(body)) {
|
|
30892
|
+
reason = "returns the input unchanged (pass-through stub)";
|
|
30893
|
+
} else if (JUST_THROW_REGEX.test(body)) {
|
|
30894
|
+
reason = "throws UnsupportedOperationException \u2014 not implemented";
|
|
30895
|
+
}
|
|
30896
|
+
if (!reason) continue;
|
|
30897
|
+
const line = source.slice(0, m.index).split("\n").length;
|
|
30898
|
+
issues.push({
|
|
30899
|
+
ruleId: "java/suspicious-implementation",
|
|
30900
|
+
category: "security",
|
|
30901
|
+
severity: "high",
|
|
30902
|
+
aiSpecific: false,
|
|
30903
|
+
message: `function ${methodName} (${reason}) \u2014 content-based mismatch`,
|
|
30904
|
+
line,
|
|
30905
|
+
column: 1,
|
|
30906
|
+
advice: `The function name "${methodName}" suggests a real validation/encryption/auth/filter operation, but the body is ${reason}. This is a content mismatch \u2014 the code's claimed behavior doesn't match its actual behavior. Real production code that ships this is a silent security failure (OWASP A04:2021 \u2014 Insecure Design). The fix is to either implement the operation or rename the function to reflect what it actually does. Reference: java/suspicious-implementation v0.35.0 (CoCoNUTS-inspired content-based detection).`
|
|
30907
|
+
});
|
|
30908
|
+
}
|
|
30909
|
+
return issues;
|
|
30910
|
+
}
|
|
30911
|
+
});
|
|
30912
|
+
}
|
|
30913
|
+
});
|
|
30914
|
+
|
|
30853
30915
|
// src/rules/java/system-out-println.ts
|
|
30854
30916
|
var SYSTEM_OUT_REGEX, REAL_LOGGING_IMPORT_REGEX, javaSystemOutPrintlnRule;
|
|
30855
30917
|
var init_system_out_println = __esm({
|
|
@@ -41102,7 +41164,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41102
41164
|
"use strict";
|
|
41103
41165
|
init_rule();
|
|
41104
41166
|
AS_FORCE_REGEX = /\bas!\s+/g;
|
|
41105
|
-
ACCESS_FORCE_REGEX = /(
|
|
41167
|
+
ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
41106
41168
|
TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
41107
41169
|
swiftForceUnwrapRule = createRule({
|
|
41108
41170
|
id: "swift/force-unwrap",
|
|
@@ -41129,7 +41191,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41129
41191
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
41130
41192
|
line,
|
|
41131
41193
|
column: 1,
|
|
41132
|
-
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.
|
|
41194
|
+
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
41133
41195
|
});
|
|
41134
41196
|
};
|
|
41135
41197
|
let m;
|
|
@@ -41138,7 +41200,10 @@ var init_force_unwrap2 = __esm({
|
|
|
41138
41200
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
41139
41201
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
41140
41202
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
41141
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
41203
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
41204
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
41205
|
+
emit(bangOffset, "!.");
|
|
41206
|
+
}
|
|
41142
41207
|
return issues;
|
|
41143
41208
|
}
|
|
41144
41209
|
});
|
|
@@ -46961,6 +47026,7 @@ var init_builtins = __esm({
|
|
|
46961
47026
|
init_command_injection();
|
|
46962
47027
|
init_hardcoded_credential();
|
|
46963
47028
|
init_sql_string_concat();
|
|
47029
|
+
init_suspicious_implementation();
|
|
46964
47030
|
init_system_out_println();
|
|
46965
47031
|
init_thread_sleep_in_loop();
|
|
46966
47032
|
init_coroutine_global_scope();
|
|
@@ -47100,6 +47166,7 @@ var init_builtins = __esm({
|
|
|
47100
47166
|
javaCommandInjectionRule,
|
|
47101
47167
|
javaHardcodedCredentialRule,
|
|
47102
47168
|
javaSqlStringConcatRule,
|
|
47169
|
+
javaSuspiciousImplementationRule,
|
|
47103
47170
|
javaSystemOutPrintlnRule,
|
|
47104
47171
|
javaThreadSleepInLoopRule,
|
|
47105
47172
|
kotlinCoroutineGlobalScopeRule,
|
|
@@ -51794,6 +51861,22 @@ var init_signal_strength = __esm({
|
|
|
51794
51861
|
_v9Precision: 0,
|
|
51795
51862
|
defaultOff: true
|
|
51796
51863
|
},
|
|
51864
|
+
"java/suspicious-implementation": {
|
|
51865
|
+
recall: 0,
|
|
51866
|
+
fpRate: 0,
|
|
51867
|
+
ratio: 0,
|
|
51868
|
+
precision: 0,
|
|
51869
|
+
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51870
|
+
verdict: "OK",
|
|
51871
|
+
_calibrationNote: "v0.35.0: NEW RULE \u2014 content-based detection (CoCoNUTS-inspired). Detects function names that claim a strong operation (validate, encrypt, hash, sanitize, check, verify, authenticate, etc.) but whose body is trivially empty, returns a constant, or returns the input unchanged. The rule is a real engineering defect detector (not AI fingerprint), so it is defaultOff=false (i.e. ON by default) and verdict=OK. The CoCoNUTS paper (2025) showed that style-based AI-detectors fail under paraphrasing; this rule looks at semantic content (function body behavior) rather than surface features. v9 calibration is pending \u2014 the rule was added at the end of the v0.34.X refinement series and has not been measured against the v9 corpus yet. The expected impact: low recall (most production code doesn't have these stubs) but high precision (when it fires, it's a real bug). The full v9 calibration is the next step for v0.35.0.x patches.",
|
|
51872
|
+
aiSpecific: false,
|
|
51873
|
+
_v9Verdict: "OK",
|
|
51874
|
+
_v9Lift: 0,
|
|
51875
|
+
_v9Recall: 0,
|
|
51876
|
+
_v9FpRate: 0,
|
|
51877
|
+
_v9Precision: 0,
|
|
51878
|
+
defaultOff: false
|
|
51879
|
+
},
|
|
51797
51880
|
"swift/force-unwrap": {
|
|
51798
51881
|
recall: 0.10211,
|
|
51799
51882
|
fpRate: 0.21462,
|
|
@@ -51801,7 +51884,7 @@ var init_signal_strength = __esm({
|
|
|
51801
51884
|
precision: 0.1721,
|
|
51802
51885
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51803
51886
|
verdict: "DORMANT",
|
|
51804
|
-
_calibrationNote: "v0.
|
|
51887
|
+
_calibrationNote: "v0.34.10: REFINED \u2014 the access-force regex now uses a negative lookbehind to exclude `!` in `!=` and `!==` comparison operators. Per-file unique v9 Swift calibration (1300 neg, 568 pos): 58 TP files, 279 FP files, ratio=0.48 (DORMANT). The previous regex incorrectly fired on `!` in `a != b` and `a !== b` patterns, which are common in control flow. The refinement is expected to push precision from 17.2% to 25%+ by removing these false positives. Era-confounded: pre-2022 Swift used `!` freely (the only way to unwrap); modern Swift uses `guard let` / `if let` / `try?`. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
|
|
51805
51888
|
aiSpecific: true,
|
|
51806
51889
|
_v7Verdict: "DORMANT",
|
|
51807
51890
|
_v7Lift: 1,
|
|
@@ -60060,6 +60143,8 @@ var RULE_HINTS = {
|
|
|
60060
60143
|
"java/thread-sleep-in-loop": "Use ScheduledExecutorService for periodic work, or BlockingQueue.take() for event-driven work. Thread.sleep in a loop is the polling anti-pattern \u2014 ties up Tomcat/Jetty/Netty threads. (v0.30.0 \u2014 DORMANT, era-confounded ratio 0.97.)",
|
|
60061
60144
|
"java/system-out-println": "The file imports a real logger (SLF4J/Log4j2/java.util.logging) but uses System.out.println. Use the declared log object instead. (v0.31.0 \u2014 OK; ratio 1.73, refined from v0.30.)",
|
|
60062
60145
|
"java/command-injection": "Use ProcessBuilder with a List<String> of args (no shell parsing) and validate each arg. Runtime.exec() with concat is the canonical command-injection pattern. OWASP A03:2021. (v0.30.0 \u2014 DORMANT.)",
|
|
60146
|
+
// v0.35.0 — content-based detection (CoCoNUTS-inspired)
|
|
60147
|
+
"java/suspicious-implementation": "Function name claims validate/encrypt/hash/sanitize but body is empty, returns null/true, or returns the input. This is a content mismatch \u2014 the function's claimed behavior doesn't match its actual behavior. OWASP A04:2021.",
|
|
60063
60148
|
// v0.24.0 — Swift rules (DORMANT until v9 Swift corpus calibration)
|
|
60064
60149
|
"swift/force-unwrap": "Replace with the safe form: `as?` + guard/if let, `try?`, or `guard let x = optional else { return }`. `!` crashes unconditionally in release. (v0.24.0 \u2014 DORMANT.)",
|
|
60065
60150
|
"swift/print-debug": "Replace with `Logger(subsystem:..., category:...).info(...)` (os.log). `print` writes to stdout with no level and no redaction. (v0.24.0 \u2014 DORMANT.)",
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var VERSION;
|
|
|
19
19
|
var init_header = __esm({
|
|
20
20
|
"src/types/_header.ts"() {
|
|
21
21
|
"use strict";
|
|
22
|
-
VERSION = "0.
|
|
22
|
+
VERSION = "0.35.0";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -30831,6 +30831,68 @@ var init_sql_string_concat = __esm({
|
|
|
30831
30831
|
}
|
|
30832
30832
|
});
|
|
30833
30833
|
|
|
30834
|
+
// src/rules/java/suspicious-implementation.ts
|
|
30835
|
+
var STRONG_VERB_REGEX, METHOD_DECL_REGEX, EMPTY_BODY_REGEX, RETURN_CONSTANT_REGEX, RETURN_INPUT_REGEX, JUST_THROW_REGEX, javaSuspiciousImplementationRule;
|
|
30836
|
+
var init_suspicious_implementation = __esm({
|
|
30837
|
+
"src/rules/java/suspicious-implementation.ts"() {
|
|
30838
|
+
"use strict";
|
|
30839
|
+
init_rule();
|
|
30840
|
+
STRONG_VERB_REGEX = /(?:validate|validates|validated|verifies?|verify|check|checks?|checked|ensures?|ensure|ensured|verifies|verified|sanitize|sanitizes|sanitized|escape|escapes|escaped|authenticate|authenticates|authenticated|authorize|authorizes|authorized|audit|audits|audited|inspect|inspects|inspected|filter|filters?|filtered|normalize|normalizes|normalized|encrypt|encrypts|encrypted|decrypt|decrypts|decrypted|hash|hashes|hashed|sign|signs?|signed|compress|compresses|compressed|decompress|decompresses|decompressed|parse|parses|parsed|format|formats?|formatted)(?=[A-Z]|[^a-zA-Z]|$)/i;
|
|
30841
|
+
METHOD_DECL_REGEX = /(?:public|private|protected)\s+(?:static\s+)?[\w<>,\s\[\]]+?\s+(\w+)\s*\([^)]*\)\s*\{([^{}]*)\}/g;
|
|
30842
|
+
EMPTY_BODY_REGEX = /^\s*$/;
|
|
30843
|
+
RETURN_CONSTANT_REGEX = /^\s*return\s+(?:null|true|false|0|1|0L|0\.0|"")\s*;\s*$/;
|
|
30844
|
+
RETURN_INPUT_REGEX = /^\s*return\s+(\w+)\s*;\s*$/;
|
|
30845
|
+
JUST_THROW_REGEX = /^\s*throw\s+new\s+(?:UnsupportedOperationException|UnsupportedOperationException\([^)]*\)|RuntimeException\([^)]*\)|IllegalStateException\([^)]*\))\s*;\s*$/;
|
|
30846
|
+
javaSuspiciousImplementationRule = createRule({
|
|
30847
|
+
id: "java/suspicious-implementation",
|
|
30848
|
+
category: "security",
|
|
30849
|
+
severity: "high",
|
|
30850
|
+
aiSpecific: false,
|
|
30851
|
+
description: "function name suggests validation/encryption/auth but body is empty or trivially wrong \u2014 content mismatch",
|
|
30852
|
+
create(_context) {
|
|
30853
|
+
return {};
|
|
30854
|
+
},
|
|
30855
|
+
analyze(_context, facts) {
|
|
30856
|
+
const issues = [];
|
|
30857
|
+
const source = facts.v2?._source;
|
|
30858
|
+
if (!source) return issues;
|
|
30859
|
+
if (!/\.java$/i.test(facts.filePath)) return issues;
|
|
30860
|
+
if (/\/test\//i.test(facts.filePath) || /\/src\/test\//i.test(facts.filePath)) return issues;
|
|
30861
|
+
let m;
|
|
30862
|
+
METHOD_DECL_REGEX.lastIndex = 0;
|
|
30863
|
+
while ((m = METHOD_DECL_REGEX.exec(source)) !== null) {
|
|
30864
|
+
const methodName = m[1];
|
|
30865
|
+
const body = m[2];
|
|
30866
|
+
if (!STRONG_VERB_REGEX.test(methodName)) continue;
|
|
30867
|
+
let reason = null;
|
|
30868
|
+
if (EMPTY_BODY_REGEX.test(body)) {
|
|
30869
|
+
reason = "empty body";
|
|
30870
|
+
} else if (RETURN_CONSTANT_REGEX.test(body)) {
|
|
30871
|
+
reason = "returns a constant (null/true/false/0/1)";
|
|
30872
|
+
} else if (RETURN_INPUT_REGEX.test(body)) {
|
|
30873
|
+
reason = "returns the input unchanged (pass-through stub)";
|
|
30874
|
+
} else if (JUST_THROW_REGEX.test(body)) {
|
|
30875
|
+
reason = "throws UnsupportedOperationException \u2014 not implemented";
|
|
30876
|
+
}
|
|
30877
|
+
if (!reason) continue;
|
|
30878
|
+
const line = source.slice(0, m.index).split("\n").length;
|
|
30879
|
+
issues.push({
|
|
30880
|
+
ruleId: "java/suspicious-implementation",
|
|
30881
|
+
category: "security",
|
|
30882
|
+
severity: "high",
|
|
30883
|
+
aiSpecific: false,
|
|
30884
|
+
message: `function ${methodName} (${reason}) \u2014 content-based mismatch`,
|
|
30885
|
+
line,
|
|
30886
|
+
column: 1,
|
|
30887
|
+
advice: `The function name "${methodName}" suggests a real validation/encryption/auth/filter operation, but the body is ${reason}. This is a content mismatch \u2014 the code's claimed behavior doesn't match its actual behavior. Real production code that ships this is a silent security failure (OWASP A04:2021 \u2014 Insecure Design). The fix is to either implement the operation or rename the function to reflect what it actually does. Reference: java/suspicious-implementation v0.35.0 (CoCoNUTS-inspired content-based detection).`
|
|
30888
|
+
});
|
|
30889
|
+
}
|
|
30890
|
+
return issues;
|
|
30891
|
+
}
|
|
30892
|
+
});
|
|
30893
|
+
}
|
|
30894
|
+
});
|
|
30895
|
+
|
|
30834
30896
|
// src/rules/java/system-out-println.ts
|
|
30835
30897
|
var SYSTEM_OUT_REGEX, REAL_LOGGING_IMPORT_REGEX, javaSystemOutPrintlnRule;
|
|
30836
30898
|
var init_system_out_println = __esm({
|
|
@@ -41083,7 +41145,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41083
41145
|
"use strict";
|
|
41084
41146
|
init_rule();
|
|
41085
41147
|
AS_FORCE_REGEX = /\bas!\s+/g;
|
|
41086
|
-
ACCESS_FORCE_REGEX = /(
|
|
41148
|
+
ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
41087
41149
|
TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
41088
41150
|
swiftForceUnwrapRule = createRule({
|
|
41089
41151
|
id: "swift/force-unwrap",
|
|
@@ -41110,7 +41172,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41110
41172
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
41111
41173
|
line,
|
|
41112
41174
|
column: 1,
|
|
41113
|
-
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.
|
|
41175
|
+
advice: 'Replace with the safe form: `as?` + guard/if let, `try?` + nil-check, or `guard let x = optional else { return }` instead of `x!`. A force-unwrap converts "the value might be nil" into "the program crashes if the value is nil" \u2014 in production that is a customer-facing crash log. AI agents reach for `!` because their training-data snippets "just make it compile" without modelling the nil case. Apple SwiftLint flags every shape (force_cast / force_try / force_unwrapping). Reference: swift/force-unwrap v0.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
41114
41176
|
});
|
|
41115
41177
|
};
|
|
41116
41178
|
let m;
|
|
@@ -41119,7 +41181,10 @@ var init_force_unwrap2 = __esm({
|
|
|
41119
41181
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
41120
41182
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
41121
41183
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
41122
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
41184
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
41185
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
41186
|
+
emit(bangOffset, "!.");
|
|
41187
|
+
}
|
|
41123
41188
|
return issues;
|
|
41124
41189
|
}
|
|
41125
41190
|
});
|
|
@@ -46942,6 +47007,7 @@ var init_builtins = __esm({
|
|
|
46942
47007
|
init_command_injection();
|
|
46943
47008
|
init_hardcoded_credential();
|
|
46944
47009
|
init_sql_string_concat();
|
|
47010
|
+
init_suspicious_implementation();
|
|
46945
47011
|
init_system_out_println();
|
|
46946
47012
|
init_thread_sleep_in_loop();
|
|
46947
47013
|
init_coroutine_global_scope();
|
|
@@ -47081,6 +47147,7 @@ var init_builtins = __esm({
|
|
|
47081
47147
|
javaCommandInjectionRule,
|
|
47082
47148
|
javaHardcodedCredentialRule,
|
|
47083
47149
|
javaSqlStringConcatRule,
|
|
47150
|
+
javaSuspiciousImplementationRule,
|
|
47084
47151
|
javaSystemOutPrintlnRule,
|
|
47085
47152
|
javaThreadSleepInLoopRule,
|
|
47086
47153
|
kotlinCoroutineGlobalScopeRule,
|
|
@@ -51772,6 +51839,22 @@ var init_signal_strength = __esm({
|
|
|
51772
51839
|
_v9Precision: 0,
|
|
51773
51840
|
defaultOff: true
|
|
51774
51841
|
},
|
|
51842
|
+
"java/suspicious-implementation": {
|
|
51843
|
+
recall: 0,
|
|
51844
|
+
fpRate: 0,
|
|
51845
|
+
ratio: 0,
|
|
51846
|
+
precision: 0,
|
|
51847
|
+
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51848
|
+
verdict: "OK",
|
|
51849
|
+
_calibrationNote: "v0.35.0: NEW RULE \u2014 content-based detection (CoCoNUTS-inspired). Detects function names that claim a strong operation (validate, encrypt, hash, sanitize, check, verify, authenticate, etc.) but whose body is trivially empty, returns a constant, or returns the input unchanged. The rule is a real engineering defect detector (not AI fingerprint), so it is defaultOff=false (i.e. ON by default) and verdict=OK. The CoCoNUTS paper (2025) showed that style-based AI-detectors fail under paraphrasing; this rule looks at semantic content (function body behavior) rather than surface features. v9 calibration is pending \u2014 the rule was added at the end of the v0.34.X refinement series and has not been measured against the v9 corpus yet. The expected impact: low recall (most production code doesn't have these stubs) but high precision (when it fires, it's a real bug). The full v9 calibration is the next step for v0.35.0.x patches.",
|
|
51850
|
+
aiSpecific: false,
|
|
51851
|
+
_v9Verdict: "OK",
|
|
51852
|
+
_v9Lift: 0,
|
|
51853
|
+
_v9Recall: 0,
|
|
51854
|
+
_v9FpRate: 0,
|
|
51855
|
+
_v9Precision: 0,
|
|
51856
|
+
defaultOff: false
|
|
51857
|
+
},
|
|
51775
51858
|
"swift/force-unwrap": {
|
|
51776
51859
|
recall: 0.10211,
|
|
51777
51860
|
fpRate: 0.21462,
|
|
@@ -51779,7 +51862,7 @@ var init_signal_strength = __esm({
|
|
|
51779
51862
|
precision: 0.1721,
|
|
51780
51863
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51781
51864
|
verdict: "DORMANT",
|
|
51782
|
-
_calibrationNote: "v0.
|
|
51865
|
+
_calibrationNote: "v0.34.10: REFINED \u2014 the access-force regex now uses a negative lookbehind to exclude `!` in `!=` and `!==` comparison operators. Per-file unique v9 Swift calibration (1300 neg, 568 pos): 58 TP files, 279 FP files, ratio=0.48 (DORMANT). The previous regex incorrectly fired on `!` in `a != b` and `a !== b` patterns, which are common in control flow. The refinement is expected to push precision from 17.2% to 25%+ by removing these false positives. Era-confounded: pre-2022 Swift used `!` freely (the only way to unwrap); modern Swift uses `guard let` / `if let` / `try?`. Same direction as kotlin/force-unwrap (0.35) and kotlin/runblocking-misuse (0.50). INSUFFICIENT_DATA: pos arm 568 files (below 10k floor).",
|
|
51783
51866
|
aiSpecific: true,
|
|
51784
51867
|
_v7Verdict: "DORMANT",
|
|
51785
51868
|
_v7Lift: 1,
|
|
@@ -59959,6 +60042,8 @@ var RULE_HINTS = {
|
|
|
59959
60042
|
"java/thread-sleep-in-loop": "Use ScheduledExecutorService for periodic work, or BlockingQueue.take() for event-driven work. Thread.sleep in a loop is the polling anti-pattern \u2014 ties up Tomcat/Jetty/Netty threads. (v0.30.0 \u2014 DORMANT, era-confounded ratio 0.97.)",
|
|
59960
60043
|
"java/system-out-println": "The file imports a real logger (SLF4J/Log4j2/java.util.logging) but uses System.out.println. Use the declared log object instead. (v0.31.0 \u2014 OK; ratio 1.73, refined from v0.30.)",
|
|
59961
60044
|
"java/command-injection": "Use ProcessBuilder with a List<String> of args (no shell parsing) and validate each arg. Runtime.exec() with concat is the canonical command-injection pattern. OWASP A03:2021. (v0.30.0 \u2014 DORMANT.)",
|
|
60045
|
+
// v0.35.0 — content-based detection (CoCoNUTS-inspired)
|
|
60046
|
+
"java/suspicious-implementation": "Function name claims validate/encrypt/hash/sanitize but body is empty, returns null/true, or returns the input. This is a content mismatch \u2014 the function's claimed behavior doesn't match its actual behavior. OWASP A04:2021.",
|
|
59962
60047
|
// v0.24.0 — Swift rules (DORMANT until v9 Swift corpus calibration)
|
|
59963
60048
|
"swift/force-unwrap": "Replace with the safe form: `as?` + guard/if let, `try?`, or `guard let x = optional else { return }`. `!` crashes unconditionally in release. (v0.24.0 \u2014 DORMANT.)",
|
|
59964
60049
|
"swift/print-debug": "Replace with `Logger(subsystem:..., category:...).info(...)` (os.log). `print` writes to stdout with no level and no redaction. (v0.24.0 \u2014 DORMANT.)",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slopbrick",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Discovered, modeled, and governed repository structure. SlopBrick scans source code, classifies it against 95+ rules in 15 categories, computes 4 scores (aiSlopScore: lower=cleaner, engineeringHygiene, security, repositoryHealth composite), and persists the structure for AI agents and CI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|