aboutsummaryrefslogtreecommitdiffstats
path: root/ui-console
diff options
context:
space:
mode:
authorKostya <mail@sartin.in>2026-08-18 07:29:50 +0000
committerKostya <mail@sartin.in>2026-08-18 07:29:50 +0000
commitdf265dea8b0ddf3ce073f5654229f41e6240e2cb (patch)
treec8a89a85fc6d00e3afa95a9e0eda660720c4c85c /ui-console
parentd2688a197bd680580699f05e8194f9180e4832fa (diff)
downloadguess-market-df265dea8b0ddf3ce073f5654229f41e6240e2cb.tar.gz
guess-market-df265dea8b0ddf3ce073f5654229f41e6240e2cb.tar.xz
guess-market-df265dea8b0ddf3ce073f5654229f41e6240e2cb.zip
Harden console path input against crashes
Menu.start() runs command.execute() with no surrounding try/catch, so an unchecked InvalidPathException from Path.of() on bad user input crashed the whole console loop. Centralize path parsing in InputProcessor.readPath(), which now validates and reprompts instead of throwing, and strips a surrounding pair of quotes so pasted/quoted paths still work.
Diffstat (limited to 'ui-console')
-rw-r--r--ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java3
-rw-r--r--ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java3
-rw-r--r--ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java3
-rw-r--r--ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java19
4 files changed, 20 insertions, 8 deletions
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java
index 11ec478..c5b3c77 100644
--- a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java
+++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java
@@ -1,6 +1,5 @@
1package market.guess.ui.console.command; 1package market.guess.ui.console.command;
2 2
3import java.nio.file.Path;
4import market.guess.api.CatalogContext; 3import market.guess.api.CatalogContext;
5import market.guess.ui.console.io.InputProcessor; 4import market.guess.ui.console.io.InputProcessor;
6 5
@@ -26,7 +25,7 @@ public final class LoadFileMenuCommand implements MenuCommand {
26 @Override 25 @Override
27 public void execute() { 26 public void execute() {
28 var path = io.readPath("Pleae enter the full file path to the XML file: "); 27 var path = io.readPath("Pleae enter the full file path to the XML file: ");
29 var result = catalog.loadEvents(Path.of(path)); 28 var result = catalog.loadEvents(path);
30 29
31 if (result.isSuccess()) { 30 if (result.isSuccess()) {
32 io.println( 31 io.println(
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java
index 26d00c1..30acef3 100644
--- a/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java
+++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java
@@ -1,6 +1,5 @@
1package market.guess.ui.console.command; 1package market.guess.ui.console.command;
2 2
3import java.nio.file.Path;
4import market.guess.api.CatalogContext; 3import market.guess.api.CatalogContext;
5import market.guess.ui.console.io.InputProcessor; 4import market.guess.ui.console.io.InputProcessor;
6 5
@@ -27,7 +26,7 @@ public final class LoadMarketStateMenuCommand implements MenuCommand {
27 @Override 26 @Override
28 public void execute() { 27 public void execute() {
29 var path = io.readPath("Which state file to load? "); 28 var path = io.readPath("Which state file to load? ");
30 var result = catalog.restoreState(Path.of(path)); 29 var result = catalog.restoreState(path);
31 30
32 if (result.isSuccess()) { 31 if (result.isSuccess()) {
33 io.println("Restored %d event(s) from %s.".formatted(result.getData().eventsLoaded(), path)); 32 io.println("Restored %d event(s) from %s.".formatted(result.getData().eventsLoaded(), path));
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java
index 77400d2..3c5d6b9 100644
--- a/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java
+++ b/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java
@@ -1,6 +1,5 @@
1package market.guess.ui.console.command; 1package market.guess.ui.console.command;
2 2
3import java.nio.file.Path;
4import market.guess.api.CatalogContext; 3import market.guess.api.CatalogContext;
5import market.guess.ui.console.io.InputProcessor; 4import market.guess.ui.console.io.InputProcessor;
6 5
@@ -29,7 +28,7 @@ public final class SaveMarketStateMenuCommand implements MenuCommand {
29 var path = io.readPath("Save to: "); 28 var path = io.readPath("Save to: ");
30 29
31 try { 30 try {
32 catalog.saveState(Path.of(path)); 31 catalog.saveState(path);
33 io.println("Saved current state to %s.".formatted(path)); 32 io.println("Saved current state to %s.".formatted(path));
34 } catch (Exception e) { 33 } catch (Exception e) {
35 io.println("Failed to save: %s".formatted(e.getMessage())); 34 io.println("Failed to save: %s".formatted(e.getMessage()));
diff --git a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java
index 7587768..512fdfe 100644
--- a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java
+++ b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java
@@ -1,5 +1,7 @@
1package market.guess.ui.console.io; 1package market.guess.ui.console.io;
2 2
3import java.nio.file.InvalidPathException;
4import java.nio.file.Path;
3import java.util.List; 5import java.util.List;
4import java.util.Scanner; 6import java.util.Scanner;
5import java.util.function.Function; 7import java.util.function.Function;
@@ -95,7 +97,7 @@ public final class InputProcessor {
95 } 97 }
96 } 98 }
97 99
98 public String readPath(String prompt) { 100 public Path readPath(String prompt) {
99 while (true) { 101 while (true) {
100 var raw = readLine(prompt); 102 var raw = readLine(prompt);
101 103
@@ -104,8 +106,21 @@ public final class InputProcessor {
104 continue; 106 continue;
105 } 107 }
106 108
107 return raw; 109 try {
110 return Path.of(unquote(raw));
111 } catch (InvalidPathException e) {
112 println("'%s' is not a valid file path.".formatted(raw));
113 }
114 }
115 }
116
117 private static String unquote(String raw) {
118 if (raw.length() >= 2
119 && ((raw.charAt(0) == '"' && raw.charAt(raw.length() - 1) == '"')
120 || (raw.charAt(0) == '\'' && raw.charAt(raw.length() - 1) == '\''))) {
121 return raw.substring(1, raw.length() - 1);
108 } 122 }
123 return raw;
109 } 124 }
110 125
111 public boolean readYesNo(String prompt) { 126 public boolean readYesNo(String prompt) {