Skip to content

Commit 65bbf02

Browse files
committed
Run SpotBugs early in CI code-style gate; suppress model-path PATH_TRAVERSAL_IN
spotbugs:check is bound to the Maven verify phase, which only the publish deploy goal reaches, so SpotBugs ran only at snapshot/release publish — a PATH_TRAVERSAL_IN finding red a release after every jar had already built. Add a SpotBugs step to the existing fast code-style job (after Spotless, before the informational jdeps step) so it runs on every PR/push and gates publish (publish-* already needs: code-style). Mirrors the existing early Spotless gate; no needs: change required. Provisionally suppress the PATH_TRAVERSAL_IN finding in OfflineModelGuard / ModelParameters (operator-supplied --model path; same threat model as the existing LlamaLoader suppression) and track an open deep-check in TODO.md for whether it — and the LlamaLoader suppression — can be genuinely resolved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0137c1LhUbNvW3kt4eF9Kqyb
1 parent 964086a commit 65bbf02

3 files changed

Lines changed: 38 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ jobs:
8484
distribution: temurin
8585
- name: Spotless check (fail fast on format violations)
8686
run: mvn -B --no-transfer-progress spotless:check
87+
- name: SpotBugs check (fail fast on static-analysis findings)
88+
run: mvn -B --no-transfer-progress -DskipTests -Denforcer.skip=true compile spotbugs:check
8789
- name: Print internal package dependency graph (jdeps, informational)
8890
continue-on-error: true
8991
run: |

TODO.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ cross-cutting initiative.
1313

1414
## Open — jllama-specific
1515

16+
### PATH_TRAVERSAL_IN suppressions — deep-check whether they can be resolved (open)
17+
18+
Two `PATH_TRAVERSAL_IN` suppressions live in `spotbugs-exclude.xml`: the long-standing
19+
`LlamaLoader` (native-lib path resolved from three operator-controlled inputs) and the new
20+
`OfflineModelGuard` / `ModelParameters` (`--model` GGUF path), added when SpotBugs moved from
21+
the publish-only `verify` phase to the fast early `code-style` CI gate (so the finding now reds
22+
every PR, not just a release). Both are currently justified as "operator-supplied path, no
23+
meaningful allowed-root." **Deep-check whether a genuine fix is feasible** — e.g. canonicalize +
24+
validate, reject `..` traversal where an expected root exists, or otherwise narrow the sink —
25+
instead of suppressing. If it is, replace the suppression with code + a regression test; if it
26+
genuinely is not, keep the suppression and record the finalized rationale here (and on the
27+
`LlamaLoader` block). See [`../workspace/policies/spotbugs-suppressions.md`](../workspace/policies/spotbugs-suppressions.md).
28+
1629
### PIT gate not hermetic — `value.ContentPart.audioFile(Path)` (open)
1730

1831
The PIT mutation gate reaches 100% **only when the audio test fixture is present**. Without it the

spotbugs-exclude.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,29 @@ SPDX-License-Identifier: MIT
147147
<Bug pattern="PATH_TRAVERSAL_IN"/>
148148
</Match>
149149

150+
<!--
151+
PROVISIONAL (under review; see java-llama.cpp TODO.md
152+
"PATH_TRAVERSAL_IN suppressions deep-check"). Same operator-supplied
153+
model-path case as the LlamaLoader suppression above.
154+
OfflineModelGuard.check() does Files.exists(Paths.get(model)) where the
155+
model path comes from ModelParameters.getModel() (the configured local
156+
model file) to verify the GGUF exists before native load; findsecbugs
157+
PATH_TRAVERSAL_IN taints that path. The model path is configured by
158+
whoever launches the process (CLI flag or builder), not untrusted
159+
end-user input, and the whole point of the setting is to let the
160+
operator point at an arbitrary GGUF on disk, so there is no meaningful
161+
allowed-root to validate against. Suppressed pending a deep check of
162+
whether a real resolution (canonicalize / restrict) is feasible for
163+
this and the LlamaLoader case.
164+
-->
165+
<Match>
166+
<Or>
167+
<Class name="net.ladenthin.llama.loader.OfflineModelGuard"/>
168+
<Class name="net.ladenthin.llama.parameters.ModelParameters"/>
169+
</Or>
170+
<Bug pattern="PATH_TRAVERSAL_IN"/>
171+
</Match>
172+
150173
<!--
151174
LlamaIterator and LlamaModel form a deliberate producer/consumer
152175
cycle: LlamaModel.generate(...) returns a LlamaIterable that

0 commit comments

Comments
 (0)