From ab77778a6524393dd728d994ea0918a9dfb64ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20M=C3=A2rza?= Date: Sun, 17 May 2026 13:07:37 +0300 Subject: [PATCH] Clear remaining ignored SpotBugs findings --- .github/workflows/spotbugs.yaml | 7 +- BUGS.md | 76 +++++++++++-------- PLAN.md | 63 +++++++++------ .../dialog/pref/general/ShortcutsTable.java | 18 ++--- .../ui/main/table/FileTableCellRenderer.java | 10 +-- .../ui/main/tree/FoldersTreePanel.java | 12 +-- .../ui/main/tree/FoldersTreeRenderer.java | 16 ++-- .../commander/ui/theme/ThemeCache.java | 20 +++-- .../main/java/com/sun/file/XFileAccessor.java | 3 +- .../java/com/sun/gssapi/ChannelBinding.java | 18 ++--- .../java/com/sun/gssapi/GSSCredential.java | 13 ++++ .../main/java/com/sun/gssapi/GSSManager.java | 8 +- .../src/main/java/com/sun/gssapi/GSSName.java | 23 +++++- .../src/main/java/com/sun/gssapi/Oid.java | 4 + .../com/sun/gssapi/samples/GSSClient.java | 3 +- .../com/sun/gssapi/samples/GSSServer.java | 3 +- .../src/main/java/com/sun/nfs/Buffer.java | 4 +- .../src/main/java/com/sun/nfs/Nfs2.java | 6 +- .../src/main/java/com/sun/nfs/Nfs3.java | 7 +- .../src/main/java/com/sun/nfs/NfsURL.java | 3 +- .../com/sun/nfs/XFileExtensionAccessor.java | 10 ++- .../src/main/java/com/sun/rpc/CredUnix.java | 6 +- .../src/main/java/com/sun/rpc/Xdr.java | 6 +- .../com/sun/rpc/samples/RPCGSSClient.java | 2 +- .../src/main/java/com/sun/xfile/XFile.java | 18 ++++- .../main/java/com/sun/xfile/XFileReader.java | 5 +- .../main/java/com/sun/xfile/XFileWriter.java | 7 +- .../com/sun/xfilechooser/XFileChooser.java | 11 +-- .../com/sun/xhandler/NfsURLConnection.java | 3 +- build.gradle.kts | 10 +-- config/spotbugs/exclude.xml | 31 -------- .../main/java/sun/net/www/MessageHeader.java | 8 +- .../src/main/java/sun/net/www/MimeEntry.java | 7 +- .../src/main/java/sun/net/www/MimeTable.java | 11 ++- .../main/java/sun/net/www/URLConnection.java | 10 ++- 35 files changed, 265 insertions(+), 197 deletions(-) delete mode 100644 config/spotbugs/exclude.xml diff --git a/.github/workflows/spotbugs.yaml b/.github/workflows/spotbugs.yaml index c970720936..fac18c9c01 100644 --- a/.github/workflows/spotbugs.yaml +++ b/.github/workflows/spotbugs.yaml @@ -1,10 +1,9 @@ name: SpotBugs # SpotBugs + FindSecBugs static analysis. Runs on every PR and push -# to main. Fails the build on any HIGH-confidence finding not listed -# in config/spotbugs/exclude.xml (the Phase-9 baseline). SARIF output -# is uploaded to GitHub Code Scanning so findings are visible in the -# Security tab. +# to main. Fails the build on every HIGH-confidence finding. SARIF +# output is uploaded to GitHub Code Scanning so findings are visible +# in the Security tab. on: pull_request: diff --git a/BUGS.md b/BUGS.md index 458be4c095..77ea12a5bb 100644 --- a/BUGS.md +++ b/BUGS.md @@ -742,6 +742,38 @@ constructing the notification popup singleton on the EDT, making quick-list spinners instance-owned, clearing SFTP random-access streams before close, and returning immediately when trash waiting is interrupted. +### 1.60 ~~MED — SpotBugs still has ignored findings after the baseline drawdown~~ **FIXED** +**`barebones-core/.../ThemeCache.java`**, +**`barebones-protocol-nfs/src/main/java/com/sun/`**, +**`sun-net-www/src/main/java/sun/net/www/`** + +Phase 20 intentionally left one own-code `MS_MUTABLE_ARRAY` suppression for +`ThemeCache.foregroundColors` / `backgroundColors` and wholesale package +suppressions for the vendored Sun NFS/RPC URL-handler code. That means +SpotBugs can still report green while hiding known findings. + +Phase 33 is removing the filter instead of carrying another exception: the +theme arrays are being made private with typed hot-path accessors, and the +vendored package findings are being surfaced so they can be fixed or proven +obsolete by the actual SpotBugs run. + +The first unfiltered run fails only in `sun-net-www` and +`barebones-protocol-nfs`: 5 URL-handler findings +(`ES_COMPARING_PARAMETER_STRING_WITH_EQ`, `PATH_TRAVERSAL_IN`, +`ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD`, `NM_SAME_SIMPLE_NAME_AS_SUPERCLASS`) +and 29 NFS/RPC/GSS/XFile findings covering default charset use, +missing `hashCode()`, lazy static initialization, ignored close/flush +failures, an impossible chooser cast, and one same-simple-name warning. + +Phase 33 fixes the last own-code mutable-array exposure by making the +`ThemeCache` color arrays private and routing renderer reads through typed +accessors. It also fixes the surfaced vendored findings directly: deterministic +charsets, matching `hashCode()` implementations, synchronized/default static +initialization, explicit exception propagation or thread interrupt handling, +the chooser property-type bug, and compatibility wrapper classes for the two +same-simple-name reports. The SpotBugs exclude filter has been deleted; the +unfiltered `spotbugsMain spotbugsTest` run is green. + --- ## 2. UX gaps @@ -1067,12 +1099,11 @@ discovery does the wiring; others use `api` / `implementation`. The convention isn't documented; the pattern flips around Phase boundaries. Worth a written convention. -### 5.12 SpotBugs baseline is technical debt with no decay schedule -`config/spotbugs/exclude.xml` had 95 entries at Phase 9; we burned -one in Phase 12 (`XORCipher`) and added zero new entries since. -A target like "drop 5 entries per release" would force the file to -shrink. 62 of the entries are real bugs in our own code waiting -for someone to fix them. +### 5.12 ~~SpotBugs baseline is technical debt with no decay schedule~~ **DONE** +Phase 33 deleted the SpotBugs exclude filter after fixing the last own-code +mutable-array exposure and the vendored Sun NFS/RPC URL-handler findings that +the package filters had hidden. SpotBugs now fails on every high-confidence +finding. --- @@ -1123,33 +1154,12 @@ The mount-helper module was removed in PR #24. Single source of truth for the 30+ scattered timeout/poll constants noted in 5.10. Optional override via system property. -### 6.10 SpotBugs baseline drawdown phase -A dedicated short PR that picks one bug pattern (e.g. all 8 -remaining `HE_EQUALS_USE_HASHCODE` entries) and fixes them -properly + removes the corresponding lines from `exclude.xml`. -Repeat until the file is empty. +### 6.10 ~~SpotBugs baseline drawdown phase~~ **DONE** +Phase 33 completed the drawdown: there is no SpotBugs exclude filter left. --- -## 7. SpotBugs baseline summary (carried over from Phase 9) - -`config/spotbugs/exclude.xml` currently suppresses **~94** findings -across our own code + vendored upstream: - -| Bucket | Count | Notes | -|--------|------:|-------| -| `DM_DEFAULT_ENCODING` | 41 | Charset-default reliance — most are in widget / dialog / archive code paths. | -| `ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD` | 15 | Form-state caches; the Phase-10b/-11 panels avoid this via the `LastValues` holder pattern. | -| `HE_EQUALS_USE_HASHCODE` | 8 | Real bugs (see 1.9). | -| `DMI_RANDOM_USED_ONLY_ONCE` | 5 | Each `new Random()` for a single nextInt; trivial to fix. | -| `MS_SHOULD_BE_FINAL` | 4 | Mutable static fields. | -| `DE_MIGHT_IGNORE` | 3 | Catch-and-ignore exception types. | -| `NM_SAME_SIMPLE_NAME_AS_SUPERCLASS` | 3 | Name shadowing across packages. | -| `MS_MUTABLE_ARRAY` | 2 | Static `byte[]` exposed. | -| `ES_COMPARING_PARAMETER_STRING_WITH_EQ` | 2 | `==` instead of `.equals()`. | -| `CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE` | 2 | Broken `clone()`. | -| various others | 8 | One each. | -| Vendored (`com.sun.*`, `sun.net.www.*`) | 33 | Wholesale package suppressions; not ours to fix. | - -The baseline file's stated lifecycle is "delete a line, fix the -underlying bug, repeat." See refactor proposal 6.10. +## 7. SpotBugs baseline summary + +There is no SpotBugs baseline left. Phase 33 removed the project-level exclude +filter and fixed the remaining findings it exposed. diff --git a/PLAN.md b/PLAN.md index ccf903ac2d..2ed74c0747 100644 --- a/PLAN.md +++ b/PLAN.md @@ -39,7 +39,7 @@ Source: forked from https://github.com/mucommander/mucommander to https://github | **17** | done | **Concurrency + correctness sweep** — `Hashtable` → `ConcurrentHashMap` (`ActionProperties`); `synchronized` on `CredentialsManager` read-modify-write; `WeakHashMap` listener pseudo-set → `CopyOnWriteArraySet` (`BookmarkManager`); all 33 `barebones-core` empty catches surfaced (try-with-resources for stream close, `AssertionError` for `Cloneable` swallows, restore-interrupt for `InterruptedException`, error dialogs for user-visible failures, WARN logs for cleanup-after-error); `EditBookmarksDialog` no-selection NPE replaced with `IllegalStateException`; principle established: no silent fallbacks in logic | this PR | | **18** | done | **Observability + logging** — S3 module gains logger fields + WARN on every AWS error, INFO on connection open/close, DEBUG on each list page, INFO on activator register/shutdown; `ThemeManager` save-failure carries theme type/name/file path; AppleScript decoder logs REPLACE-branch substitutions at DEBUG and caps `outputBuffer` at 1 MiB with a visible truncation marker; SFTP auth failures logged at WARN. `System.err` in CLI bootstrap (`Application.printError`, `Main` headless detection) and `EncodingDetector.main` documented as kept-by-design. | this PR | | **19** | done | **UX polish** — `S3ErrorHandler` typed 401/403/404; error-dialog throwable plumbed through Phase-17 + every `FileJob` error site (~25 catches across 10 job classes); `DynamicList.RemoveAction` prompts before deletion; `FileDropTargetListener` rejects drops on non-writable target folders; `ProgressNotifier` SPI wires producer-side hints into the MainFrame status bar; `S3Object.StatusBarProgressListener` publishes byte-accurate S3 upload progress ("47.3 MiB / 100.0 MiB (47%)") throttled to 250 ms; `CredentialsWriter` posts a status-bar explainer before the first keychain prompt. Default-button focus, huge-file open, folder-browse cursor, prefs Cancel-revert, and batch-rename preview audit-confirmed as already-fixed / as-designed. | this PR | -| **20** | done | **SpotBugs baseline drawdown to ~zero** — fixed every own-code suppression in `config/spotbugs/exclude.xml` (DM_DEFAULT_ENCODING ×17, ST_WRITE_TO_STATIC ×12, DMI_RANDOM_USED_ONLY_ONCE ×4, MS_SHOULD_BE_FINAL ×4, plus 7 one-off patterns). Encoding fixes are explicit, NOT silent UTF-8 fallbacks: CP437 for Zip APPNOTE-spec entries, NPE-on-null for `ZipOutputStream.setEncoding`, `Charset.defaultCharset()` for process I/O, BOMWriter for the text editor's read-encoding round-trip. One suppression remains: `ThemeCache.foregroundColors`/`backgroundColors` MS_MUTABLE_ARRAY — documented architectural tradeoff (per-cell-render hot path). Vendored `com.sun.*` / `sun.net.www.*` package-level suppressions kept. | this PR | +| **20** | done | **SpotBugs baseline drawdown to ~zero** — fixed the legacy own-code SpotBugs baseline entries (DM_DEFAULT_ENCODING ×17, ST_WRITE_TO_STATIC ×12, DMI_RANDOM_USED_ONLY_ONCE ×4, MS_SHOULD_BE_FINAL ×4, plus 7 one-off patterns). Encoding fixes are explicit, NOT silent UTF-8 fallbacks: CP437 for Zip APPNOTE-spec entries, NPE-on-null for `ZipOutputStream.setEncoding`, `Charset.defaultCharset()` for process I/O, BOMWriter for the text editor's read-encoding round-trip. One suppression remained temporarily: `ThemeCache.foregroundColors`/`backgroundColors` MS_MUTABLE_ARRAY. Vendored `com.sun.*` / `sun.net.www.*` package-level suppressions were also kept temporarily. Phase 33 removes that remaining baseline. | this PR | | **21+** | open | **Architecture refactors — REVIEW REQUIRED.** Tracked separately; do NOT execute without explicit approval per `BUGS.md` §5/§6. | n/a | | **22** | done | **Modern logging migration** — internal `barebones-logging` facade backed by JDK logging APIs; `--debug` support; SLF4J/logback removed from production dependencies. | landed in #30 | | **23** | done | **Systematic dependency upgrade pass** — audited every `gradle/libs.versions.toml` entry against Maven Central / Gradle Plugin Portal release metadata; removed `jsr305`; documented major/pre-release pins. | this PR | @@ -51,7 +51,8 @@ Source: forked from https://github.com/mucommander/mucommander to https://github | **29** | done | **JUnit 5 + protocol scope cleanup** — migrate legacy tests to JUnit 5, improve S3 endpoint URL parsing, remove retired-protocol future scope, and evaluate NFSv4 replacement options. | landed in #37 | | **30** | done | **Architecture refactor batch** — archive format `ServiceLoader`, remove vendored `apache-bzip2`, centralize runtime tunables, and make javac unchecked/deprecation warnings fail the build. | landed in #38 | | **31** | done | **Repo skill + architecture/docs/check sweep** — add repo-local Java GUI slop cleanup skill, document current architecture, align stale docs/comments with the implementation, and harden CI against fake-green checks. | landed in #39 | -| **32** | in progress | **Repo-wide Java GUI slop sweep** — run the repo-local slop-cleaning skill against current `origin/main`, record each finding in `BUGS.md`, fix actionable issues, and keep continuity docs current. | this PR | +| **32** | done | **Repo-wide Java GUI slop sweep** — run the repo-local slop-cleaning skill against current `origin/main`, record each finding in `BUGS.md`, fix actionable issues, and keep continuity docs current. | landed in #40 | +| **33** | in progress | **Clear remaining ignored SpotBugs findings** — remove the last `ThemeCache` own-code suppression and surface/fix vendored Sun NFS/RPC URL-handler findings so SpotBugs runs without an exclude filter. | this PR | **Hard rule**: only one branch / one PR is in flight at a time. The user — not the LLM — decides when a PR is ready and when the next one starts. The LLM does not autonomously open new PRs to fan out work in parallel. @@ -364,17 +365,16 @@ that's otherwise mechanical. - Add **SpotBugs + FindSecBugs** as a Gradle-driven CI step (`.github/workflows/spotbugs.yaml`, PR + push-to-main triggered). - Fails the build on any HIGH-confidence finding not listed in - `config/spotbugs/exclude.xml`. SARIF uploaded to GitHub Code - Scanning. + Fails the build on every HIGH-confidence finding. SARIF uploaded + to GitHub Code Scanning. - Add **OWASP Dependency-Check** as a scheduled weekly CI run (`.github/workflows/dependency-check.yaml`, Monday 06:00 UTC + workflow_dispatch). Fails on CVSS ≥ 7.0 not suppressed in `config/dependency-check/suppression.xml`. SARIF uploaded to GitHub Code Scanning. -- The Phase-9 SpotBugs baseline (`config/spotbugs/exclude.xml`) - captures **95 pre-existing HIGH-confidence findings** in the - brownfield muCommander code. Categorisation: +- The Phase-9 SpotBugs baseline captured **95 pre-existing + HIGH-confidence findings** in the brownfield muCommander code. + Categorisation: * `com.sun.*` / `sun.net.www.*` — vendored upstream (33 findings) suppressed wholesale via `` matches. * Per-(class, bug-pattern) suppressions for our own code (62 @@ -382,9 +382,8 @@ that's otherwise mechanical. * Top patterns: `DM_DEFAULT_ENCODING` (charset reliance), `ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD` (static caches), `HE_EQUALS_USE_HASHCODE` (broken `equals/hashCode` contract). -- Post-Phase-9 cleanup phases will progressively remove suppressions - from `config/spotbugs/exclude.xml` until empty (then the file can - be deleted and SpotBugs runs purely on regression). +- Phase 33 removed the final baseline and deleted the SpotBugs + exclude filter; SpotBugs now runs purely on regression. ### Phase 12 — Keychain-backed credentials (one PR) @@ -1025,20 +1024,19 @@ reassigned them; the `static` exposure was sloppy not load-bearing. progress <= 100)` — always true. Fixed to `&&` (the obvious intent). -**Documented suppression kept**: +**Temporary baseline left for Phase 33**: - `ThemeCache.foregroundColors` / `backgroundColors` - `MS_MUTABLE_ARRAY`: per-cell-render hot path; refactoring to - defensive-copy accessors would be unacceptable overhead. Setters - for the related fields were already extracted in the ST_WRITE - pass; only the array-element writes remain direct (and SpotBugs - doesn't flag those). + `MS_MUTABLE_ARRAY`: the arrays were still public static storage. +- Vendored `com.sun.*` / `sun.net.www.*` package filters still hid + the NFS/RPC URL-handler findings. -**Vendored `com.sun.*` / `sun.net.www.*` package suppressions kept** -— upstream code, not ours to fix. +Phase 33 removed both remainders: the theme arrays are private behind +typed accessors, vendored findings were fixed, and the SpotBugs +exclude filter was deleted. -**Exit criteria** (met): `config/spotbugs/exclude.xml` contains the -vendored packages plus exactly one documented own-code exception; -`./gradlew test spotbugsMain` green. +**Exit criteria** (met): `./gradlew test spotbugsMain` green with the +then-current temporary baseline. Phase 33 supersedes this with a +fully unfiltered SpotBugs run. ### Phase 21+ — Architecture refactors (parking lot) @@ -1370,6 +1368,27 @@ compile plus MinIO S3 integration test, `./gradlew cleanTest test --stacktrace`, and `./gradlew check --stacktrace`. Next work is to commit/push to PR #40 and watch CI. +### Phase 33 — Clear remaining ignored SpotBugs findings (this PR) + +Phase 33 starts from `origin/main` after PR #40 was merged. The active branch is +`phase-33/spotbugs-baseline-drawdown`; no PR was open at branch creation. + +Initial findings recorded in `BUGS.md` 1.60: +- the only remaining own-code SpotBugs suppression was + `ThemeCache.foregroundColors` / `backgroundColors` `MS_MUTABLE_ARRAY`; +- the only other suppressions were wholesale vendored Sun NFS/RPC and + URL-handler package filters. + +Current status: the theme color arrays are private and direct +renderer/table/tree reads now use tiny typed accessors. The SpotBugs +exclude filter has been removed entirely. The first unfiltered run surfaced +5 `sun-net-www` findings and 29 `barebones-protocol-nfs` findings; those were +fixed without keeping any replacement filter. Local unfiltered +`./gradlew spotbugsMain spotbugsTest --stacktrace` is green. +Follow-up validation also passed with `git diff --check`, `./gradlew cleanTest +test --stacktrace`, and `./gradlew check --stacktrace`. Next work is to commit, +push, open the single Phase 33 PR, and watch CI. + **Exit criteria**: all actionable findings discovered in this sweep are either fixed or explicitly documented as deferred; local validation includes at least `./gradlew cleanTest test --stacktrace`, `./gradlew check --stacktrace`, diff --git a/barebones-core/src/main/java/dev/barebones/commander/ui/dialog/pref/general/ShortcutsTable.java b/barebones-core/src/main/java/dev/barebones/commander/ui/dialog/pref/general/ShortcutsTable.java index ff1aefe38d..031c278e8d 100644 --- a/barebones-core/src/main/java/dev/barebones/commander/ui/dialog/pref/general/ShortcutsTable.java +++ b/barebones-core/src/main/java/dev/barebones/commander/ui/dialog/pref/general/ShortcutsTable.java @@ -511,8 +511,8 @@ public RecordingKeyStrokeField(KeyStroke currentKeyStroke, DescriptionData descr setBorder(BorderFactory.createEmptyBorder()); setHorizontalAlignment(JTextField.CENTER); setEditable(false); - setBackground(ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED]); - setForeground(ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED][ThemeCache.PLAIN_FILE]); + setBackground(ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.SELECTED)); + setForeground(ThemeCache.foregroundColor(ThemeCache.ACTIVE, ThemeCache.SELECTED, ThemeCache.PLAIN_FILE)); addKeyListener(this); // It is required to disable the traversal keys in order to support keys combination that include the TAB // key @@ -535,7 +535,7 @@ protected void paintBorder(Graphics g) { paintDottedBorder(g, getWidth(), getHeight(), - ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL]); + ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL)); } ///////////////////////////// @@ -884,7 +884,7 @@ public Component getTableCellRendererComponent(JTable table, // set cell's foreground color label.setForeground( - ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL][ThemeCache.PLAIN_FILE]); + ThemeCache.foregroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL, ThemeCache.PLAIN_FILE)); } // Any other column else { @@ -919,17 +919,17 @@ public Component getTableCellRendererComponent(JTable table, customized = false; } - label.setForeground(ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL][customized + label.setForeground(ThemeCache.foregroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL, customized ? ThemeCache.PLAIN_FILE - : ThemeCache.HIDDEN_FILE]); + : ThemeCache.HIDDEN_FILE)); } } // set outline for the focused cell - label.setOutline(hasFocus ? ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED] : null); + label.setOutline(hasFocus ? ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.SELECTED) : null); // set cell's background color - label.setBackground(ThemeCache.backgroundColors[ThemeCache.ACTIVE][rowIndex % 2 == 0 ? ThemeCache.NORMAL - : ThemeCache.ALTERNATE]); + label.setBackground(ThemeCache.backgroundColor(ThemeCache.ACTIVE, rowIndex % 2 == 0 ? ThemeCache.NORMAL + : ThemeCache.ALTERNATE)); return label; } diff --git a/barebones-core/src/main/java/dev/barebones/commander/ui/main/table/FileTableCellRenderer.java b/barebones-core/src/main/java/dev/barebones/commander/ui/main/table/FileTableCellRenderer.java index f6c1019f83..0312c4a6ce 100644 --- a/barebones-core/src/main/java/dev/barebones/commander/ui/main/table/FileTableCellRenderer.java +++ b/barebones-core/src/main/java/dev/barebones/commander/ui/main/table/FileTableCellRenderer.java @@ -103,7 +103,7 @@ public static Font getCellFont() { } public Color getBakgroundOfSelectedFileInInactiveTable() { - return ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.SELECTED]; + return ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.SELECTED); } /** @@ -204,7 +204,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole else { String text = (String)value; if(matches || isSelected) - label.setForeground(ThemeCache.foregroundColors[focusedIndex][selectedIndex][colorIndex]); + label.setForeground(ThemeCache.foregroundColor(focusedIndex, selectedIndex, colorIndex)); else label.setForeground(ThemeCache.unmatchedForeground); @@ -241,12 +241,12 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole // Set background color depending on whether the row is selected or not, and whether the table has focus or not if(selectedIndex == ThemeCache.SELECTED) - label.setBackground(ThemeCache.backgroundColors[focusedIndex][ThemeCache.SELECTED], ThemeCache.backgroundColors[focusedIndex][ThemeCache.SECONDARY]); + label.setBackground(ThemeCache.backgroundColor(focusedIndex, ThemeCache.SELECTED), ThemeCache.backgroundColor(focusedIndex, ThemeCache.SECONDARY)); else if(matches) { if(table.hasFocus() && search.isActive()) - label.setBackground(ThemeCache.backgroundColors[focusedIndex][ThemeCache.NORMAL]); + label.setBackground(ThemeCache.backgroundColor(focusedIndex, ThemeCache.NORMAL)); else - label.setBackground(ThemeCache.backgroundColors[focusedIndex][(rowIndex % 2 == 0) ? ThemeCache.NORMAL : ThemeCache.ALTERNATE]); + label.setBackground(ThemeCache.backgroundColor(focusedIndex, (rowIndex % 2 == 0) ? ThemeCache.NORMAL : ThemeCache.ALTERNATE)); } else label.setBackground(ThemeCache.unmatchedBackground); diff --git a/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreePanel.java b/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreePanel.java index 944e58c450..59511c2926 100644 --- a/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreePanel.java +++ b/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreePanel.java @@ -127,7 +127,7 @@ public FoldersTreePanel(FolderPanel folderPanel) { model = new FilesTreeModel(treeFileFilter, sort); tree = new JTree(model); tree.setFont(ThemeCache.tableFont); - tree.setBackground(ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.NORMAL]); + tree.setBackground(ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.NORMAL)); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); @@ -363,12 +363,12 @@ public void locationChanged(LocationEvent locationEvent) { // - FocusListener code ---------------------------------------------------- // ------------------------------------------------------------------------- - public void focusGained(FocusEvent e) { - tree.setBackground(ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL]); + public void focusGained(FocusEvent e) { + tree.setBackground(ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL)); } public void focusLost(FocusEvent e) { - tree.setBackground(ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.NORMAL]); + tree.setBackground(ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.NORMAL)); } @@ -377,9 +377,9 @@ public void focusLost(FocusEvent e) { public void colorChanged(ColorChangedEvent event) { if (tree.hasFocus()) { - tree.setBackground(ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL]); + tree.setBackground(ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL)); } else { - tree.setBackground(ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.NORMAL]); + tree.setBackground(ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.NORMAL)); } tree.repaint(); } diff --git a/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreeRenderer.java b/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreeRenderer.java index d7aa04346c..57060c7ddb 100644 --- a/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreeRenderer.java +++ b/barebones-core/src/main/java/dev/barebones/commander/ui/main/tree/FoldersTreeRenderer.java @@ -47,29 +47,29 @@ public FoldersTreeRenderer(JTree tree) { @Override public Color getBackgroundSelectionColor() { if (tree!=null && tree.hasFocus()) { - return ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED]; + return ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.SELECTED); } else { - return ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.SELECTED]; + return ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.SELECTED); } } @Override public Color getBackgroundNonSelectionColor() { if (tree!=null && tree.hasFocus()) { - return ThemeCache.backgroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL]; + return ThemeCache.backgroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL); } else { - return ThemeCache.backgroundColors[ThemeCache.INACTIVE][ThemeCache.NORMAL]; + return ThemeCache.backgroundColor(ThemeCache.INACTIVE, ThemeCache.NORMAL); } } @Override public Color getForeground() { if (tree!=null && tree.hasFocus()) { - return selected ? ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.SELECTED][ThemeCache.FOLDER] : - ThemeCache.foregroundColors[ThemeCache.ACTIVE][ThemeCache.NORMAL][ThemeCache.FOLDER]; + return selected ? ThemeCache.foregroundColor(ThemeCache.ACTIVE, ThemeCache.SELECTED, ThemeCache.FOLDER) : + ThemeCache.foregroundColor(ThemeCache.ACTIVE, ThemeCache.NORMAL, ThemeCache.FOLDER); } else { - return selected ? ThemeCache.foregroundColors[ThemeCache.INACTIVE][ThemeCache.SELECTED][ThemeCache.FOLDER] : - ThemeCache.foregroundColors[ThemeCache.INACTIVE][ThemeCache.NORMAL][ThemeCache.FOLDER]; + return selected ? ThemeCache.foregroundColor(ThemeCache.INACTIVE, ThemeCache.SELECTED, ThemeCache.FOLDER) : + ThemeCache.foregroundColor(ThemeCache.INACTIVE, ThemeCache.NORMAL, ThemeCache.FOLDER); } } diff --git a/barebones-core/src/main/java/dev/barebones/commander/ui/theme/ThemeCache.java b/barebones-core/src/main/java/dev/barebones/commander/ui/theme/ThemeCache.java index 016debfb6d..2a96a7ad56 100644 --- a/barebones-core/src/main/java/dev/barebones/commander/ui/theme/ThemeCache.java +++ b/barebones-core/src/main/java/dev/barebones/commander/ui/theme/ThemeCache.java @@ -32,8 +32,8 @@ public class ThemeCache implements ThemeListener { // - Color definitions ----------------------------------------------------------- // ------------------------------------------------------------------------------- - public static Color[][][] foregroundColors; - public static Color[][] backgroundColors; + private static final Color[][][] foregroundColors = new Color[2][2][7]; + private static final Color[][] backgroundColors = new Color[2][4]; public static Color unmatchedForeground; public static Color unmatchedBackground; public static Color activeOutlineColor; @@ -62,9 +62,6 @@ public class ThemeCache implements ThemeListener { // - Initialisation -------------------------------------------------------------- // ------------------------------------------------------------------------------- static { - foregroundColors = new Color[2][2][7]; - backgroundColors = new Color[2][4]; - // Active background colors. backgroundColors[ACTIVE][NORMAL] = ThemeManager.getCurrentColor(Theme.FILE_TABLE_BACKGROUND_COLOR); backgroundColors[ACTIVE][SELECTED] = ThemeManager.getCurrentColor(Theme.FILE_TABLE_SELECTED_BACKGROUND_COLOR); @@ -145,6 +142,14 @@ public static void removeThemeListener(ThemeListener listener) { listeners.remove(listener); } + public static Color foregroundColor(int focusIndex, int selectionIndex, int fileKindIndex) { + return foregroundColors[focusIndex][selectionIndex][fileKindIndex]; + } + + public static Color backgroundColor(int focusIndex, int backgroundIndex) { + return backgroundColors[focusIndex][backgroundIndex]; + } + private static void fireColorChanged(ColorChangedEvent event) { listeners.forEach(listener -> listener.colorChanged(event)); } @@ -385,9 +390,8 @@ public void fontChanged(FontChangedEvent event) { // methods (forced to be instance because they implement // ThemeListener) don't write directly to scalar static fields, // which trips SpotBugs ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD. - // The array-element writes (foregroundColors[i][j][k] = ...) - // are not flagged because SpotBugs counts that as a write to - // an array, not to a static field reference. + // The color arrays stay private so callers cannot mutate cache + // storage; renderers read through the small static accessors above. private static void setUnmatchedForeground(java.awt.Color c) { unmatchedForeground = c; } private static void setUnmatchedBackground(java.awt.Color c) { unmatchedBackground = c; } private static void setActiveOutlineColor (java.awt.Color c) { activeOutlineColor = c; } diff --git a/barebones-protocol-nfs/src/main/java/com/sun/file/XFileAccessor.java b/barebones-protocol-nfs/src/main/java/com/sun/file/XFileAccessor.java index c26084250b..4a3f40e5e4 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/file/XFileAccessor.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/file/XFileAccessor.java @@ -40,6 +40,7 @@ import com.sun.xfile.*; import java.io.*; +import java.nio.charset.StandardCharsets; /** * The XFileAccessor interface is implemented by filesystems that @@ -105,7 +106,7 @@ private String unEscape(String s) { int d1 = hD.indexOf(s.toLowerCase().charAt(p2 + 1)); int d2 = hD.indexOf(s.toLowerCase().charAt(p2 + 2)); if (d1 > 0 && d2 > 0) { - ns += new String(new byte[] {(byte)(d1 << 4 | d2)}); + ns += new String(new byte[] {(byte)(d1 << 4 | d2)}, StandardCharsets.ISO_8859_1); p2 += 2; continue; } diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/ChannelBinding.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/ChannelBinding.java index b30c754dad..da921e6f0d 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/ChannelBinding.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/ChannelBinding.java @@ -38,6 +38,8 @@ package com.sun.gssapi; import java.net.InetAddress; +import java.util.Arrays; +import java.util.Objects; /** * The JGSS accommodates the concept of caller-provided channel @@ -156,16 +158,12 @@ public boolean equals(Object obj) { ChannelBinding cb = (ChannelBinding)obj; - //check for application data being null in one but not the other - if ((getApplicationData() == null && - cb.getApplicationData() != null) || - (getApplicationData() != null && - cb.getApplicationData() == null)) - return (false); + return (Objects.equals(this.m_initiator, cb.getInitiatorAddress()) && + Objects.equals(this.m_acceptor, cb.getAcceptorAddress()) && + Arrays.equals(this.m_appData, cb.getApplicationData())); + } - return (this.m_initiator.equals(cb.getInitiatorAddress()) && - this.m_acceptor.equals(cb.getAcceptorAddress()) && - (this.getApplicationData() == null || - this.m_appData.equals(cb.getApplicationData()))); + public int hashCode() { + return Objects.hash(m_initiator, m_acceptor, Arrays.hashCode(m_appData)); } } diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSCredential.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSCredential.java index 181a45b882..1010e8a060 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSCredential.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSCredential.java @@ -505,6 +505,19 @@ public boolean equals(Object another) { //all internal creds are equal, so we are equal too... return (true); } + + public int hashCode() { + + int hash = 0; + for (Enumeration e = m_mechCreds.elements(); + e.hasMoreElements();) { + + GSSCredSpi intCred = (GSSCredSpi)e.nextElement(); + hash += intCred.getMechanism().hashCode(); + } + + return (hash); + } /** diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSManager.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSManager.java index a5029e19d6..63df4be47c 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSManager.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSManager.java @@ -203,7 +203,7 @@ public static Oid[] getMechsForName(Oid nameType) { * @exception GSSException with major code set to BAD_MECH if * no jgss providers exist. */ - public static Oid getDefaultMech() throws GSSException { + public static synchronized Oid getDefaultMech() throws GSSException { if (m_defaultMech != null) return (m_defaultMech.getOid()); @@ -717,9 +717,5 @@ static boolean putMechInfo(MechInfo aMech) { //private table storing the mapping - private static Hashtable M_table; - - static { - M_table = new Hashtable<>(13); - } + private static final Hashtable M_table = new Hashtable<>(13); } //end of Class MechTable diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSName.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSName.java index a4048047db..4edcdfca6e 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSName.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/GSSName.java @@ -37,6 +37,7 @@ package com.sun.gssapi; +import java.util.Arrays; import java.util.Vector; import java.util.Enumeration; @@ -67,7 +68,7 @@ * @see Oid */ -public class GSSName { +public class GSSName implements Cloneable { /** * Name type used to indicate a host-based service name form. It @@ -302,6 +303,24 @@ public boolean equals(Object another) { } catch (GSSException e) { return false; } } + + public int hashCode() { + + if (m_mechNames.size() < 1) { + int hash = 17; + hash = 31 * hash + (m_nameType == null ? 0 : m_nameType.hashCode()); + hash = 31 * hash + (m_nameStr == null ? 0 : m_nameStr.hashCode()); + hash = 31 * hash + Arrays.hashCode(m_nameBytes); + return (hash); + } + + int hash = 0; + for (Enumeration e = m_mechNames.elements(); e.hasMoreElements(); ) { + GSSNameSpi mechName = (GSSNameSpi)e.nextElement(); + hash += mechName.getMech().hashCode(); + } + return (hash); + } /** @@ -335,7 +354,7 @@ public boolean equals(GSSName another) throws GSSException { return (m_nameStr.equals(another.m_nameStr)); if (m_nameBytes != null && another.m_nameBytes != null) - return (m_nameBytes.equals(another.m_nameBytes)); + return (Arrays.equals(m_nameBytes, another.m_nameBytes)); return false; } diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/Oid.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/Oid.java index a0233de6cf..0554fe54a0 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/Oid.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/Oid.java @@ -226,6 +226,10 @@ public boolean equals(Object Obj) { return (true); } + public int hashCode() { + return (m_v.hashCode()); + } + /** * Returns the full ASN.1 DER encoding for this oid object. diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSClient.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSClient.java index b0ac0b9287..4edddacf5f 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSClient.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSClient.java @@ -251,7 +251,8 @@ private static void sendMsgToPeer(GSSContext aCtxt, String msg) print("\nWrapping message for server..."); MessageProp mInfo = new MessageProp(0, true); - byte []tok = aCtxt.wrap(msg.getBytes(), 0, msg.length(), mInfo); + byte[] msgBytes = msg.getBytes(StandardCharsets.UTF_8); + byte []tok = aCtxt.wrap(msgBytes, 0, msgBytes.length, mInfo); DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeInt(tok.length); dos.write(tok); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSServer.java b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSServer.java index d88fd89aff..1a3f47a25c 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSServer.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/gssapi/samples/GSSServer.java @@ -45,6 +45,7 @@ import java.io.*; import java.net.*; +import java.nio.charset.StandardCharsets; import com.sun.gssapi.*; @@ -274,7 +275,7 @@ private static void exchangeWithPeer(GSSContext aCtxt, DataInputStream dis, MessageProp mInfo = new MessageProp(); aCtxt.unwrap(dis, bos, mInfo); - print("\tMessage from peer:\t" + new String(bos.toByteArray())); + print("\tMessage from peer:\t" + new String(bos.toByteArray(), StandardCharsets.UTF_8)); mInfo.setQOP(0); mInfo.setPrivacy(false); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Buffer.java b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Buffer.java index 6eaddfbac1..adfc77b6c8 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Buffer.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Buffer.java @@ -101,9 +101,7 @@ public Buffer(Nfs nfs, long foffset, int bufsize) { maxOffset = 0; setDaemon(true); // NFS threads die when app exits - try { - setName("Buffer-" + (foffset / bufsize)); - } catch (Exception e) {}; // non-essential, ignore + setName("Buffer-" + (foffset / bufsize)); action = IDLE; start(); } diff --git a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs2.java b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs2.java index 372ee72e13..1bade25703 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs2.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs2.java @@ -38,6 +38,7 @@ package com.sun.nfs; import java.io.*; +import java.nio.charset.StandardCharsets; import com.sun.rpc.*; /** @@ -453,11 +454,12 @@ public String lookupSec() throws IOException { call.xdr_raw(new byte[32]); // v2 public file handle // send "0x81pathname" over the wire - int len = name.getBytes().length + 2; + byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8); + int len = nameBytes.length + 2; byte[] b = new byte[len]; b[0] = (byte) 0x81; b[1] = (byte) sec_index; - System.arraycopy(name.getBytes(), 0, b, 2, name.getBytes().length); + System.arraycopy(nameBytes, 0, b, 2, nameBytes.length); call.xdr_bytes(b); Xdr reply = rpc.rpc_call(call, 5 * 1000, 3); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs3.java b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs3.java index 4c124131d4..e244446005 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs3.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/nfs/Nfs3.java @@ -38,6 +38,7 @@ package com.sun.nfs; import java.io.*; +import java.nio.charset.StandardCharsets; import com.sun.rpc.*; /** @@ -499,12 +500,12 @@ public String lookupSec() throws IOException { call.xdr_bytes(new byte[0]); // v3 public file handle // send "0x81/sec_inext/pathname" over the wire - int len = name.getBytes().length + 2; + byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8); + int len = nameBytes.length + 2; byte[] b = new byte[len]; b[0] = (byte) 0x81; b[1] = (byte) sec_index; - System.arraycopy(name.getBytes(), 0, b, 2, - name.getBytes().length); + System.arraycopy(nameBytes, 0, b, 2, nameBytes.length); call.xdr_bytes(b); Xdr reply = rpc.rpc_call(call, 5 * 1000, 3); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/nfs/NfsURL.java b/barebones-protocol-nfs/src/main/java/com/sun/nfs/NfsURL.java index 10107b2858..de610608d3 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/nfs/NfsURL.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/nfs/NfsURL.java @@ -38,6 +38,7 @@ package com.sun.nfs; import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; /** * This is just a dumb URL parser class. @@ -107,7 +108,7 @@ public NfsURL(String url) throws MalformedURLException { location = url.substring(0, q); r = url.indexOf(':', p); if (r > 0 && r < q) { - byte[] opts = url.substring(r + 1, q).toLowerCase().getBytes(); + byte[] opts = url.substring(r + 1, q).toLowerCase().getBytes(StandardCharsets.US_ASCII); for (int i = 0; i < opts.length; i++) { if (opts[i] >= '0' && opts[i] <= '9') { port = (port * 10) + (opts[i] - '0'); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/nfs/XFileExtensionAccessor.java b/barebones-protocol-nfs/src/main/java/com/sun/nfs/XFileExtensionAccessor.java index 0ac6e86f4e..5fa23bcfd0 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/nfs/XFileExtensionAccessor.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/nfs/XFileExtensionAccessor.java @@ -40,12 +40,12 @@ import java.io.*; import com.sun.xfile.*; -public class XFileExtensionAccessor +class NfsExtensionAccessor extends com.sun.xfile.XFileExtensionAccessor { XFile xf; - public XFileExtensionAccessor(XFile xf) { + public NfsExtensionAccessor(XFile xf) { super(xf); if (! xf.getFileSystemName().equals("nfs")) @@ -149,3 +149,9 @@ public String[] getExports() return new Mount().getExports(new NfsURL(xf.toString()).getHost()); } } + +public class XFileExtensionAccessor extends NfsExtensionAccessor { + public XFileExtensionAccessor(XFile xf) { + super(xf); + } +} diff --git a/barebones-protocol-nfs/src/main/java/com/sun/rpc/CredUnix.java b/barebones-protocol-nfs/src/main/java/com/sun/rpc/CredUnix.java index 9c1bd5e5f8..5553977a05 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/rpc/CredUnix.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/rpc/CredUnix.java @@ -37,6 +37,8 @@ package com.sun.rpc; +import java.nio.charset.StandardCharsets; + import java.io.*; /** @@ -206,12 +208,12 @@ public void setCred(int uid, int gid, int[] gids) { * obvious to a casual snooper. */ private String disguise(String s) { - byte[] b = s.getBytes(); + byte[] b = s.getBytes(StandardCharsets.ISO_8859_1); for (int i = 0; i < b.length; i++) b[i] = (byte)((b[i] & 0x7f) ^ 0x5b); - return (new String(b)); + return (new String(b, StandardCharsets.ISO_8859_1)); } /** diff --git a/barebones-protocol-nfs/src/main/java/com/sun/rpc/Xdr.java b/barebones-protocol-nfs/src/main/java/com/sun/rpc/Xdr.java index 05e4ef5bc8..f95b4524cc 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/rpc/Xdr.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/rpc/Xdr.java @@ -37,6 +37,8 @@ package com.sun.rpc; +import java.nio.charset.StandardCharsets; + import java.io.*; /** @@ -293,7 +295,7 @@ public void xdr_float(float f) { public String xdr_string() { int len = xdr_int(); - String s = new String(buf, off, len); + String s = new String(buf, off, len, StandardCharsets.UTF_8); xdr_skip(len); return s; } @@ -304,7 +306,7 @@ public String xdr_string() { * @param s string */ public void xdr_string(String s) { - xdr_bytes(s.getBytes()); + xdr_bytes(s.getBytes(StandardCharsets.UTF_8)); } /** diff --git a/barebones-protocol-nfs/src/main/java/com/sun/rpc/samples/RPCGSSClient.java b/barebones-protocol-nfs/src/main/java/com/sun/rpc/samples/RPCGSSClient.java index c808ef1404..35a4cd7a72 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/rpc/samples/RPCGSSClient.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/rpc/samples/RPCGSSClient.java @@ -169,7 +169,7 @@ public static void main(String args[]) { replymsg = rpc.rpc_call(callmsg, 3 * 1000, 3); name = replymsg.xdr_string(); addr = replymsg.xdr_string(); - if (addr.getBytes().length != 0) { + if (!addr.isEmpty()) { print(name + " = " + addr); } else { print("no value"); diff --git a/barebones-protocol-nfs/src/main/java/com/sun/xfile/XFile.java b/barebones-protocol-nfs/src/main/java/com/sun/xfile/XFile.java index 885efbb302..dde7702cb0 100644 --- a/barebones-protocol-nfs/src/main/java/com/sun/xfile/XFile.java +++ b/barebones-protocol-nfs/src/main/java/com/sun/xfile/XFile.java @@ -331,7 +331,9 @@ private Class loadClass(String proto, String suffix, Hashtable loadClass(String proto, String suffix, Hashtable\n\n"); // Hand the input stream off to HotJava - is = new ByteArrayInputStream(buf.toString().getBytes()); + is = new ByteArrayInputStream(buf.toString().getBytes(StandardCharsets.UTF_8)); } else { // Mark the input stream we return as containing a certain file type diff --git a/build.gradle.kts b/build.gradle.kts index e0702014cb..cbbd5c71eb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -228,13 +228,8 @@ tasks.named("cyclonedxDirectBom") { // SpotBugs + FindSecBugs across every Java subproject. Reports // HIGH-confidence findings to SARIF (uploaded to GitHub Code -// Scanning by the CI workflow) and HTML, and **fails the build on -// any finding** that isn't suppressed by config/spotbugs/exclude.xml. -// -// The exclude file holds the Phase-9 baseline — 95 (source, pattern) -// pairs that pre-existed in the brownfield muCommander code. Each -// suppression is a real bug to fix in a follow-up; deleting a line -// from the exclude file surfaces the underlying finding. +// Scanning by the CI workflow) and HTML, and fails the build on +// every high-confidence finding without a project-level exclude filter. allprojects { plugins.withId("com.github.spotbugs") { dependencies { @@ -245,7 +240,6 @@ allprojects { effort.set(com.github.spotbugs.snom.Effort.MAX) reportLevel.set(com.github.spotbugs.snom.Confidence.HIGH) ignoreFailures.set(false) - excludeFilter.set(rootProject.file("config/spotbugs/exclude.xml")) } tasks.withType().configureEach { reports.create("sarif") { required.set(true) } diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml deleted file mode 100644 index cb4d01afe1..0000000000 --- a/config/spotbugs/exclude.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/sun-net-www/src/main/java/sun/net/www/MessageHeader.java b/sun-net-www/src/main/java/sun/net/www/MessageHeader.java index 22b16407dd..91862f3647 100644 --- a/sun-net-www/src/main/java/sun/net/www/MessageHeader.java +++ b/sun-net-www/src/main/java/sun/net/www/MessageHeader.java @@ -97,7 +97,7 @@ public synchronized String findValue(String k) { // return the location of the key public synchronized int getKey(String k) { for (int i = nkeys; --i >= 0;) - if ((keys[i] == k) || + if ((keys[i] == null && k == null) || (k != null && k.equalsIgnoreCase(keys[i]))) return i; return -1; @@ -131,14 +131,16 @@ public synchronized String findNextValue(String k, String v) { if (keys[i] == null) if (foundV) return values[i]; - else if (values[i] == v) + else if ((values[i] == null && v == null) || + (values[i] != null && values[i].equals(v))) foundV = true; } else for (int i = nkeys; --i >= 0;) if (k.equalsIgnoreCase(keys[i])) if (foundV) return values[i]; - else if (values[i] == v) + else if ((values[i] == null && v == null) || + (values[i] != null && values[i].equals(v))) foundV = true; return null; } diff --git a/sun-net-www/src/main/java/sun/net/www/MimeEntry.java b/sun-net-www/src/main/java/sun/net/www/MimeEntry.java index 6b7791bb66..ad67d81fc8 100644 --- a/sun-net-www/src/main/java/sun/net/www/MimeEntry.java +++ b/sun-net-www/src/main/java/sun/net/www/MimeEntry.java @@ -150,8 +150,7 @@ public String getImageFileName() { } public synchronized void setImageFileName(String filename) { - File file = new File(filename); - if (file.getParent() == null) { + if (!hasPathComponent(filename)) { imageFileName = System.getProperty( "java.net.ftp.imagepath."+filename); } @@ -164,6 +163,10 @@ public synchronized void setImageFileName(String filename) { } } + private static boolean hasPathComponent(String filename) { + return filename.indexOf('/') >= 0 || filename.indexOf('\\') >= 0; + } + public String getTempFileTemplate() { return tempFileNameTemplate; } diff --git a/sun-net-www/src/main/java/sun/net/www/MimeTable.java b/sun-net-www/src/main/java/sun/net/www/MimeTable.java index ee7715678b..dc927021d4 100644 --- a/sun-net-www/src/main/java/sun/net/www/MimeTable.java +++ b/sun-net-www/src/main/java/sun/net/www/MimeTable.java @@ -49,9 +49,8 @@ public class MimeTable implements FileNameMap { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { - tempFileTemplate = - System.getProperty("content.types.temp.file.template", - "/tmp/%s"); + setTempFileTemplate(System.getProperty( + "content.types.temp.file.template", "/tmp/%s")); mailcapLocations = new String[] { System.getProperty("user.mailcap"), @@ -212,6 +211,10 @@ String getTempFileTemplate() { return tempFileTemplate; } + private static void setTempFileTemplate(String value) { + tempFileTemplate = value; + } + public synchronized Enumeration elements() { return entries.elements(); } @@ -255,7 +258,7 @@ void parse(Properties entries) { String tempFileTemplate = (String)entries.get("temp.file.template"); if (tempFileTemplate != null) { entries.remove("temp.file.template"); - MimeTable.tempFileTemplate = tempFileTemplate; + setTempFileTemplate(tempFileTemplate); } // now, parse the mime-type spec's diff --git a/sun-net-www/src/main/java/sun/net/www/URLConnection.java b/sun-net-www/src/main/java/sun/net/www/URLConnection.java index b3af24c594..b6c390264c 100644 --- a/sun-net-www/src/main/java/sun/net/www/URLConnection.java +++ b/sun-net-www/src/main/java/sun/net/www/URLConnection.java @@ -35,7 +35,7 @@ * @author James Gosling */ -public abstract class URLConnection extends java.net.URLConnection { +abstract class BarebonesURLConnection extends java.net.URLConnection { /** The URL that it is connected to */ @@ -50,7 +50,7 @@ public abstract class URLConnection extends java.net.URLConnection { * URL.openConnection. * @param u The URL that this connects to. */ - public URLConnection (URL u) { + public BarebonesURLConnection (URL u) { super(u); properties = new MessageHeader(); } @@ -271,3 +271,9 @@ public static synchronized boolean isProxiedHost(String host) { return proxiedHosts.containsKey(host.toLowerCase()); } } + +public abstract class URLConnection extends BarebonesURLConnection { + public URLConnection(URL u) { + super(u); + } +}