slopbrick 0.34.8 → 0.34.10
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 +18 -8
- package/dist/engine/worker.js +18 -8
- package/dist/index.cjs +19 -9
- package/dist/index.js +19 -9
- package/package.json +1 -1
package/dist/engine/worker.cjs
CHANGED
|
@@ -37142,7 +37142,7 @@ var javaHardcodedCredentialRule = createRule({
|
|
|
37142
37142
|
// src/rules/java/sql-string-concat.ts
|
|
37143
37143
|
var SQL_KEYWORD_REGEX = /\b(?:SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM|CREATE\s+TABLE|DROP\s+TABLE|ALTER\s+TABLE)\b/i;
|
|
37144
37144
|
var UNSAFE_REGEX = /\+/;
|
|
37145
|
-
var SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b
|
|
37145
|
+
var SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b|\?)/;
|
|
37146
37146
|
var javaSqlStringConcatRule = createRule({
|
|
37147
37147
|
id: "java/sql-string-concat",
|
|
37148
37148
|
category: "security",
|
|
@@ -37160,7 +37160,14 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37160
37160
|
const lines = source.split("\n");
|
|
37161
37161
|
for (let i = 0; i < lines.length; i++) {
|
|
37162
37162
|
const line = lines[i];
|
|
37163
|
-
|
|
37163
|
+
const keywordMatch = SQL_KEYWORD_REGEX.exec(line);
|
|
37164
|
+
if (!keywordMatch) continue;
|
|
37165
|
+
const keywordIdx = keywordMatch.index;
|
|
37166
|
+
let j = keywordIdx - 1;
|
|
37167
|
+
while (j >= 0 && /\s/.test(line[j])) j--;
|
|
37168
|
+
if (j < 0) continue;
|
|
37169
|
+
const prevChar = line[j];
|
|
37170
|
+
if (prevChar !== '"' && prevChar !== "'" && prevChar !== "=") continue;
|
|
37164
37171
|
if (!UNSAFE_REGEX.test(line)) continue;
|
|
37165
37172
|
if (SAFE_REGEX.test(line)) continue;
|
|
37166
37173
|
issues.push({
|
|
@@ -37171,7 +37178,7 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37171
37178
|
message: `SQL query built via string concat at line ${i + 1}`,
|
|
37172
37179
|
line: i + 1,
|
|
37173
37180
|
column: 1,
|
|
37174
|
-
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.
|
|
37181
|
+
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.34.9 (refined: require SQL keyword to start a string literal; tightened SAFE_REGEX).'
|
|
37175
37182
|
});
|
|
37176
37183
|
}
|
|
37177
37184
|
return issues;
|
|
@@ -40561,7 +40568,7 @@ var swiftFatalErrorThrownRule = createRule({
|
|
|
40561
40568
|
|
|
40562
40569
|
// src/rules/swift/force-unwrap.ts
|
|
40563
40570
|
var AS_FORCE_REGEX = /\bas!\s+/g;
|
|
40564
|
-
var ACCESS_FORCE_REGEX = /(
|
|
40571
|
+
var ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
40565
40572
|
var TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
40566
40573
|
var swiftForceUnwrapRule = createRule({
|
|
40567
40574
|
id: "swift/force-unwrap",
|
|
@@ -40588,7 +40595,7 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40588
40595
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
40589
40596
|
line,
|
|
40590
40597
|
column: 1,
|
|
40591
|
-
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.
|
|
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.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
40592
40599
|
});
|
|
40593
40600
|
};
|
|
40594
40601
|
let m;
|
|
@@ -40597,7 +40604,10 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40597
40604
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
40598
40605
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
40599
40606
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
40600
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
40607
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
40608
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
40609
|
+
emit(bangOffset, "!.");
|
|
40610
|
+
}
|
|
40601
40611
|
return issues;
|
|
40602
40612
|
}
|
|
40603
40613
|
});
|
|
@@ -45627,7 +45637,7 @@ var signal_strength_default = {
|
|
|
45627
45637
|
precision: 0.0691,
|
|
45628
45638
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45629
45639
|
verdict: "DORMANT",
|
|
45630
|
-
_calibrationNote:
|
|
45640
|
+
_calibrationNote: 'v0.34.9: REFINED \u2014 rule now requires the SQL keyword to be the start of a string literal (preceded by `"`, `\'`, or `=`), and tightened the SAFE_REGEX. Per-file unique v9 Java calibration (81891 neg, 10305 pos): 115 TP files, 1549 FP files, ratio=0.59 (DORMANT). 1664 total fires. The refinement is expected to push precision from 6.9% to 25%+ by removing lines where SELECT/INSERT appears in string values (e.g. `String msg = "Selected 1 row: " + count`). Also tightened SAFE_REGEX from `:??` to `:?` (the original was over-broad). The full v9 re-calibration is part of the broader v0.34.8/v0.34.9 pipeline (same pattern applied to kotlin/sql-string-concat and java/sql-string-concat). INSUFFICIENT_DATA: pos arm 10305 files, below the 10k floor. Era-confounded: pre-2022 Java used JDBC string concat more; modern Java uses PreparedStatement. defaultOff.',
|
|
45631
45641
|
aiSpecific: false,
|
|
45632
45642
|
_v9Verdict: "DORMANT",
|
|
45633
45643
|
_v9Lift: 0.59,
|
|
@@ -45707,7 +45717,7 @@ var signal_strength_default = {
|
|
|
45707
45717
|
precision: 0.1721,
|
|
45708
45718
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45709
45719
|
verdict: "DORMANT",
|
|
45710
|
-
_calibrationNote: "v0.
|
|
45720
|
+
_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).",
|
|
45711
45721
|
aiSpecific: true,
|
|
45712
45722
|
_v7Verdict: "DORMANT",
|
|
45713
45723
|
_v7Lift: 1,
|
package/dist/engine/worker.js
CHANGED
|
@@ -37113,7 +37113,7 @@ var javaHardcodedCredentialRule = createRule({
|
|
|
37113
37113
|
// src/rules/java/sql-string-concat.ts
|
|
37114
37114
|
var SQL_KEYWORD_REGEX = /\b(?:SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM|CREATE\s+TABLE|DROP\s+TABLE|ALTER\s+TABLE)\b/i;
|
|
37115
37115
|
var UNSAFE_REGEX = /\+/;
|
|
37116
|
-
var SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b
|
|
37116
|
+
var SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b|\?)/;
|
|
37117
37117
|
var javaSqlStringConcatRule = createRule({
|
|
37118
37118
|
id: "java/sql-string-concat",
|
|
37119
37119
|
category: "security",
|
|
@@ -37131,7 +37131,14 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37131
37131
|
const lines = source.split("\n");
|
|
37132
37132
|
for (let i = 0; i < lines.length; i++) {
|
|
37133
37133
|
const line = lines[i];
|
|
37134
|
-
|
|
37134
|
+
const keywordMatch = SQL_KEYWORD_REGEX.exec(line);
|
|
37135
|
+
if (!keywordMatch) continue;
|
|
37136
|
+
const keywordIdx = keywordMatch.index;
|
|
37137
|
+
let j = keywordIdx - 1;
|
|
37138
|
+
while (j >= 0 && /\s/.test(line[j])) j--;
|
|
37139
|
+
if (j < 0) continue;
|
|
37140
|
+
const prevChar = line[j];
|
|
37141
|
+
if (prevChar !== '"' && prevChar !== "'" && prevChar !== "=") continue;
|
|
37135
37142
|
if (!UNSAFE_REGEX.test(line)) continue;
|
|
37136
37143
|
if (SAFE_REGEX.test(line)) continue;
|
|
37137
37144
|
issues.push({
|
|
@@ -37142,7 +37149,7 @@ var javaSqlStringConcatRule = createRule({
|
|
|
37142
37149
|
message: `SQL query built via string concat at line ${i + 1}`,
|
|
37143
37150
|
line: i + 1,
|
|
37144
37151
|
column: 1,
|
|
37145
|
-
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.
|
|
37152
|
+
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.34.9 (refined: require SQL keyword to start a string literal; tightened SAFE_REGEX).'
|
|
37146
37153
|
});
|
|
37147
37154
|
}
|
|
37148
37155
|
return issues;
|
|
@@ -40532,7 +40539,7 @@ var swiftFatalErrorThrownRule = createRule({
|
|
|
40532
40539
|
|
|
40533
40540
|
// src/rules/swift/force-unwrap.ts
|
|
40534
40541
|
var AS_FORCE_REGEX = /\bas!\s+/g;
|
|
40535
|
-
var ACCESS_FORCE_REGEX = /(
|
|
40542
|
+
var ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
40536
40543
|
var TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
40537
40544
|
var swiftForceUnwrapRule = createRule({
|
|
40538
40545
|
id: "swift/force-unwrap",
|
|
@@ -40559,7 +40566,7 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40559
40566
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
40560
40567
|
line,
|
|
40561
40568
|
column: 1,
|
|
40562
|
-
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.
|
|
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.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
40563
40570
|
});
|
|
40564
40571
|
};
|
|
40565
40572
|
let m;
|
|
@@ -40568,7 +40575,10 @@ var swiftForceUnwrapRule = createRule({
|
|
|
40568
40575
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
40569
40576
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
40570
40577
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
40571
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
40578
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
40579
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
40580
|
+
emit(bangOffset, "!.");
|
|
40581
|
+
}
|
|
40572
40582
|
return issues;
|
|
40573
40583
|
}
|
|
40574
40584
|
});
|
|
@@ -45598,7 +45608,7 @@ var signal_strength_default = {
|
|
|
45598
45608
|
precision: 0.0691,
|
|
45599
45609
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45600
45610
|
verdict: "DORMANT",
|
|
45601
|
-
_calibrationNote:
|
|
45611
|
+
_calibrationNote: 'v0.34.9: REFINED \u2014 rule now requires the SQL keyword to be the start of a string literal (preceded by `"`, `\'`, or `=`), and tightened the SAFE_REGEX. Per-file unique v9 Java calibration (81891 neg, 10305 pos): 115 TP files, 1549 FP files, ratio=0.59 (DORMANT). 1664 total fires. The refinement is expected to push precision from 6.9% to 25%+ by removing lines where SELECT/INSERT appears in string values (e.g. `String msg = "Selected 1 row: " + count`). Also tightened SAFE_REGEX from `:??` to `:?` (the original was over-broad). The full v9 re-calibration is part of the broader v0.34.8/v0.34.9 pipeline (same pattern applied to kotlin/sql-string-concat and java/sql-string-concat). INSUFFICIENT_DATA: pos arm 10305 files, below the 10k floor. Era-confounded: pre-2022 Java used JDBC string concat more; modern Java uses PreparedStatement. defaultOff.',
|
|
45602
45612
|
aiSpecific: false,
|
|
45603
45613
|
_v9Verdict: "DORMANT",
|
|
45604
45614
|
_v9Lift: 0.59,
|
|
@@ -45678,7 +45688,7 @@ var signal_strength_default = {
|
|
|
45678
45688
|
precision: 0.1721,
|
|
45679
45689
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
45680
45690
|
verdict: "DORMANT",
|
|
45681
|
-
_calibrationNote: "v0.
|
|
45691
|
+
_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).",
|
|
45682
45692
|
aiSpecific: true,
|
|
45683
45693
|
_v7Verdict: "DORMANT",
|
|
45684
45694
|
_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.34.
|
|
39
|
+
VERSION = "0.34.10";
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -30805,7 +30805,7 @@ var init_sql_string_concat = __esm({
|
|
|
30805
30805
|
init_rule();
|
|
30806
30806
|
SQL_KEYWORD_REGEX = /\b(?:SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM|CREATE\s+TABLE|DROP\s+TABLE|ALTER\s+TABLE)\b/i;
|
|
30807
30807
|
UNSAFE_REGEX = /\+/;
|
|
30808
|
-
SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b
|
|
30808
|
+
SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b|\?)/;
|
|
30809
30809
|
javaSqlStringConcatRule = createRule({
|
|
30810
30810
|
id: "java/sql-string-concat",
|
|
30811
30811
|
category: "security",
|
|
@@ -30823,7 +30823,14 @@ var init_sql_string_concat = __esm({
|
|
|
30823
30823
|
const lines = source.split("\n");
|
|
30824
30824
|
for (let i = 0; i < lines.length; i++) {
|
|
30825
30825
|
const line = lines[i];
|
|
30826
|
-
|
|
30826
|
+
const keywordMatch = SQL_KEYWORD_REGEX.exec(line);
|
|
30827
|
+
if (!keywordMatch) continue;
|
|
30828
|
+
const keywordIdx = keywordMatch.index;
|
|
30829
|
+
let j = keywordIdx - 1;
|
|
30830
|
+
while (j >= 0 && /\s/.test(line[j])) j--;
|
|
30831
|
+
if (j < 0) continue;
|
|
30832
|
+
const prevChar = line[j];
|
|
30833
|
+
if (prevChar !== '"' && prevChar !== "'" && prevChar !== "=") continue;
|
|
30827
30834
|
if (!UNSAFE_REGEX.test(line)) continue;
|
|
30828
30835
|
if (SAFE_REGEX.test(line)) continue;
|
|
30829
30836
|
issues.push({
|
|
@@ -30834,7 +30841,7 @@ var init_sql_string_concat = __esm({
|
|
|
30834
30841
|
message: `SQL query built via string concat at line ${i + 1}`,
|
|
30835
30842
|
line: i + 1,
|
|
30836
30843
|
column: 1,
|
|
30837
|
-
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.
|
|
30844
|
+
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.34.9 (refined: require SQL keyword to start a string literal; tightened SAFE_REGEX).'
|
|
30838
30845
|
});
|
|
30839
30846
|
}
|
|
30840
30847
|
return issues;
|
|
@@ -41095,7 +41102,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41095
41102
|
"use strict";
|
|
41096
41103
|
init_rule();
|
|
41097
41104
|
AS_FORCE_REGEX = /\bas!\s+/g;
|
|
41098
|
-
ACCESS_FORCE_REGEX = /(
|
|
41105
|
+
ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
41099
41106
|
TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
41100
41107
|
swiftForceUnwrapRule = createRule({
|
|
41101
41108
|
id: "swift/force-unwrap",
|
|
@@ -41122,7 +41129,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41122
41129
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
41123
41130
|
line,
|
|
41124
41131
|
column: 1,
|
|
41125
|
-
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.
|
|
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.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
41126
41133
|
});
|
|
41127
41134
|
};
|
|
41128
41135
|
let m;
|
|
@@ -41131,7 +41138,10 @@ var init_force_unwrap2 = __esm({
|
|
|
41131
41138
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
41132
41139
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
41133
41140
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
41134
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
41141
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
41142
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
41143
|
+
emit(bangOffset, "!.");
|
|
41144
|
+
}
|
|
41135
41145
|
return issues;
|
|
41136
41146
|
}
|
|
41137
41147
|
});
|
|
@@ -51714,7 +51724,7 @@ var init_signal_strength = __esm({
|
|
|
51714
51724
|
precision: 0.0691,
|
|
51715
51725
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51716
51726
|
verdict: "DORMANT",
|
|
51717
|
-
_calibrationNote:
|
|
51727
|
+
_calibrationNote: 'v0.34.9: REFINED \u2014 rule now requires the SQL keyword to be the start of a string literal (preceded by `"`, `\'`, or `=`), and tightened the SAFE_REGEX. Per-file unique v9 Java calibration (81891 neg, 10305 pos): 115 TP files, 1549 FP files, ratio=0.59 (DORMANT). 1664 total fires. The refinement is expected to push precision from 6.9% to 25%+ by removing lines where SELECT/INSERT appears in string values (e.g. `String msg = "Selected 1 row: " + count`). Also tightened SAFE_REGEX from `:??` to `:?` (the original was over-broad). The full v9 re-calibration is part of the broader v0.34.8/v0.34.9 pipeline (same pattern applied to kotlin/sql-string-concat and java/sql-string-concat). INSUFFICIENT_DATA: pos arm 10305 files, below the 10k floor. Era-confounded: pre-2022 Java used JDBC string concat more; modern Java uses PreparedStatement. defaultOff.',
|
|
51718
51728
|
aiSpecific: false,
|
|
51719
51729
|
_v9Verdict: "DORMANT",
|
|
51720
51730
|
_v9Lift: 0.59,
|
|
@@ -51794,7 +51804,7 @@ var init_signal_strength = __esm({
|
|
|
51794
51804
|
precision: 0.1721,
|
|
51795
51805
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51796
51806
|
verdict: "DORMANT",
|
|
51797
|
-
_calibrationNote: "v0.
|
|
51807
|
+
_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).",
|
|
51798
51808
|
aiSpecific: true,
|
|
51799
51809
|
_v7Verdict: "DORMANT",
|
|
51800
51810
|
_v7Lift: 1,
|
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.34.
|
|
22
|
+
VERSION = "0.34.10";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -30786,7 +30786,7 @@ var init_sql_string_concat = __esm({
|
|
|
30786
30786
|
init_rule();
|
|
30787
30787
|
SQL_KEYWORD_REGEX = /\b(?:SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM|CREATE\s+TABLE|DROP\s+TABLE|ALTER\s+TABLE)\b/i;
|
|
30788
30788
|
UNSAFE_REGEX = /\+/;
|
|
30789
|
-
SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b
|
|
30789
|
+
SAFE_REGEX = /(?:PreparedStatement|setParameter|setString|setInt|setLong|createQuery.*:.*\b(?:set|bind)|:name\b|\?)/;
|
|
30790
30790
|
javaSqlStringConcatRule = createRule({
|
|
30791
30791
|
id: "java/sql-string-concat",
|
|
30792
30792
|
category: "security",
|
|
@@ -30804,7 +30804,14 @@ var init_sql_string_concat = __esm({
|
|
|
30804
30804
|
const lines = source.split("\n");
|
|
30805
30805
|
for (let i = 0; i < lines.length; i++) {
|
|
30806
30806
|
const line = lines[i];
|
|
30807
|
-
|
|
30807
|
+
const keywordMatch = SQL_KEYWORD_REGEX.exec(line);
|
|
30808
|
+
if (!keywordMatch) continue;
|
|
30809
|
+
const keywordIdx = keywordMatch.index;
|
|
30810
|
+
let j = keywordIdx - 1;
|
|
30811
|
+
while (j >= 0 && /\s/.test(line[j])) j--;
|
|
30812
|
+
if (j < 0) continue;
|
|
30813
|
+
const prevChar = line[j];
|
|
30814
|
+
if (prevChar !== '"' && prevChar !== "'" && prevChar !== "=") continue;
|
|
30808
30815
|
if (!UNSAFE_REGEX.test(line)) continue;
|
|
30809
30816
|
if (SAFE_REGEX.test(line)) continue;
|
|
30810
30817
|
issues.push({
|
|
@@ -30815,7 +30822,7 @@ var init_sql_string_concat = __esm({
|
|
|
30815
30822
|
message: `SQL query built via string concat at line ${i + 1}`,
|
|
30816
30823
|
line: i + 1,
|
|
30817
30824
|
column: 1,
|
|
30818
|
-
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.
|
|
30825
|
+
advice: 'Use a PreparedStatement (JDBC), setParameter (jOOQ), or an ORM (Hibernate, MyBatis with #{} binding). String concatenation into a SQL query is the canonical SQL-injection pattern \u2014 even "trusted" inputs (signed JWT, internal config) can be influenced by an attacker. Reference: java/sql-string-concat v0.34.9 (refined: require SQL keyword to start a string literal; tightened SAFE_REGEX).'
|
|
30819
30826
|
});
|
|
30820
30827
|
}
|
|
30821
30828
|
return issues;
|
|
@@ -41076,7 +41083,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41076
41083
|
"use strict";
|
|
41077
41084
|
init_rule();
|
|
41078
41085
|
AS_FORCE_REGEX = /\bas!\s+/g;
|
|
41079
|
-
ACCESS_FORCE_REGEX = /(
|
|
41086
|
+
ACCESS_FORCE_REGEX = /(?<![=!])(\w|\])\!\s*(?:\.|\(|;|,|\s*$)/gm;
|
|
41080
41087
|
TRY_FORCE_REGEX = /\btry!\s+/g;
|
|
41081
41088
|
swiftForceUnwrapRule = createRule({
|
|
41082
41089
|
id: "swift/force-unwrap",
|
|
@@ -41103,7 +41110,7 @@ var init_force_unwrap2 = __esm({
|
|
|
41103
41110
|
message: `force-unwrap (${label}) at line ${line} \u2014 crashes if the value is nil`,
|
|
41104
41111
|
line,
|
|
41105
41112
|
column: 1,
|
|
41106
|
-
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.
|
|
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.34.10 (refined: exclude `!` in `!==`/`!=` operators via negative lookbehind).'
|
|
41107
41114
|
});
|
|
41108
41115
|
};
|
|
41109
41116
|
let m;
|
|
@@ -41112,7 +41119,10 @@ var init_force_unwrap2 = __esm({
|
|
|
41112
41119
|
TRY_FORCE_REGEX.lastIndex = 0;
|
|
41113
41120
|
while ((m = TRY_FORCE_REGEX.exec(source)) !== null) emit(m.index, "try!");
|
|
41114
41121
|
ACCESS_FORCE_REGEX.lastIndex = 0;
|
|
41115
|
-
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null)
|
|
41122
|
+
while ((m = ACCESS_FORCE_REGEX.exec(source)) !== null) {
|
|
41123
|
+
const bangOffset = m.index + (m[1]?.length ?? 1);
|
|
41124
|
+
emit(bangOffset, "!.");
|
|
41125
|
+
}
|
|
41116
41126
|
return issues;
|
|
41117
41127
|
}
|
|
41118
41128
|
});
|
|
@@ -51692,7 +51702,7 @@ var init_signal_strength = __esm({
|
|
|
51692
51702
|
precision: 0.0691,
|
|
51693
51703
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51694
51704
|
verdict: "DORMANT",
|
|
51695
|
-
_calibrationNote:
|
|
51705
|
+
_calibrationNote: 'v0.34.9: REFINED \u2014 rule now requires the SQL keyword to be the start of a string literal (preceded by `"`, `\'`, or `=`), and tightened the SAFE_REGEX. Per-file unique v9 Java calibration (81891 neg, 10305 pos): 115 TP files, 1549 FP files, ratio=0.59 (DORMANT). 1664 total fires. The refinement is expected to push precision from 6.9% to 25%+ by removing lines where SELECT/INSERT appears in string values (e.g. `String msg = "Selected 1 row: " + count`). Also tightened SAFE_REGEX from `:??` to `:?` (the original was over-broad). The full v9 re-calibration is part of the broader v0.34.8/v0.34.9 pipeline (same pattern applied to kotlin/sql-string-concat and java/sql-string-concat). INSUFFICIENT_DATA: pos arm 10305 files, below the 10k floor. Era-confounded: pre-2022 Java used JDBC string concat more; modern Java uses PreparedStatement. defaultOff.',
|
|
51696
51706
|
aiSpecific: false,
|
|
51697
51707
|
_v9Verdict: "DORMANT",
|
|
51698
51708
|
_v9Lift: 0.59,
|
|
@@ -51772,7 +51782,7 @@ var init_signal_strength = __esm({
|
|
|
51772
51782
|
precision: 0.1721,
|
|
51773
51783
|
lastCalibratedAt: "2026-07-03T00:00:00Z",
|
|
51774
51784
|
verdict: "DORMANT",
|
|
51775
|
-
_calibrationNote: "v0.
|
|
51785
|
+
_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).",
|
|
51776
51786
|
aiSpecific: true,
|
|
51777
51787
|
_v7Verdict: "DORMANT",
|
|
51778
51788
|
_v7Lift: 1,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slopbrick",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.10",
|
|
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": {
|