From 529cc3d6e738f426bd100bed3df003742cdbd817 Mon Sep 17 00:00:00 2001 From: ottosch <17476+ottosch@users.noreply.github.com> Date: Thu, 12 Feb 2026 04:20:40 -0300 Subject: [PATCH] handle import of samourai wallet backup file with extraneous appended data --- .../sparrowwallet/sparrow/io/Samourai.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java b/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java index 6459c09d..0ed872ad 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Samourai.java @@ -29,10 +29,7 @@ public class Samourai implements KeystoreFileImport { try { String input = CharStreams.toString(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); - Gson gson = new Gson(); - Type stringStringMap = new TypeToken>() { - }.getType(); - Map map = gson.fromJson(input, stringStringMap); + Map map = this.parseJsonInput(input); String payload = input; if(map.containsKey("payload")) { @@ -53,7 +50,7 @@ public class Samourai implements KeystoreFileImport { throw new ImportException("Unsupported backup version: " + version); } - SamouraiBackup backup = gson.fromJson(decrypted, SamouraiBackup.class); + SamouraiBackup backup = new Gson().fromJson(decrypted, SamouraiBackup.class); DeterministicSeed seed = new DeterministicSeed(Utils.hexToBytes(backup.wallet.seed), password, 0); Keystore keystore = Keystore.fromSeed(seed, scriptType.getDefaultDerivation()); keystore.setLabel(getWalletModel().toDisplayString()); @@ -67,6 +64,24 @@ public class Samourai implements KeystoreFileImport { } } + private Map parseJsonInput(String input) { + Gson gson = new Gson(); + Type stringStringMap = new TypeToken>() { + }.getType(); + + try { + return gson.fromJson(input, stringStringMap); + } catch (JsonParseException e) { + int closingBracket = input.indexOf('}'); + if (closingBracket < 0) { + throw e; + } + + String fixedInput = input.substring(0, closingBracket + 1); + return gson.fromJson(fixedInput, stringStringMap); + } + } + @Override public boolean isKeystoreImportScannable() { return false;