From dca45a9b1846a59cd3c471294891b89c9d77db7b Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 16 Sep 2020 14:42:11 +0000
Subject: [PATCH] i2psnark: Defensive checks for v2 format files and magnet
 links

---
 .../i2psnark/java/src/org/klomp/snark/MagnetURI.java |  8 ++++++++
 apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java | 12 +++++++++++-
 apps/i2psnark/java/src/org/klomp/snark/Peer.java     |  7 +++----
 .../src/org/klomp/snark/web/I2PSnarkServlet.java     |  4 ++++
 4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/apps/i2psnark/java/src/org/klomp/snark/MagnetURI.java b/apps/i2psnark/java/src/org/klomp/snark/MagnetURI.java
index dadba5849d..2baa06436c 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/MagnetURI.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/MagnetURI.java
@@ -24,6 +24,13 @@ public class MagnetURI {
     public static final String MAGNET_FULL = MAGNET + "?xt=urn:btih:";
     /** http://sponge.i2p/files/maggotspec.txt */
     public static final String MAGGOT = "maggot://";
+    /**
+     *  https://blog.libtorrent.org/2020/09/bittorrent-v2/
+     *  TODO, dup param parsing, as a dual v1/v2 link
+     *  will contain two xt params
+     *  @since 0.9.48
+     */
+    public static final String MAGNET_FULL_V2 = MAGNET + "?xt=urn:btmh:";
 
     /**
      *  @param url non-null
@@ -35,6 +42,7 @@ public class MagnetURI {
         if (url.startsWith(MAGNET)) {
             // magnet:?xt=urn:btih:0691e40aae02e552cfcb57af1dca56214680c0c5&tr=http://tracker2.postman.i2p/announce.php
             String xt = getParam("xt", url);
+            // TODO btmh
             if (xt == null || !xt.startsWith("urn:btih:"))
                 throw new IllegalArgumentException();
             ihash = xt.substring("urn:btih:".length());
diff --git a/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java b/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
index 8e72164889..f4aeb21f4f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java
@@ -238,8 +238,18 @@ public class MetaInfo
     piece_length = val.getInt();
 
     val = info.get("pieces");
-    if (val == null)
+    if (val == null) {
+        // BEP 52
+        // We do the check here because a torrent file could be combined v1/v2,
+        // so a version 2 value isn't by itself fatal
+        val = info.get("meta version");
+        if (val != null) {
+            int version = val.getInt();
+            if (version != 1)
+                throw new InvalidBEncodingException("Version " + version + " torrent file not supported");
+        }
         throw new InvalidBEncodingException("Missing piece bytes");
+    }
     piece_hashes = val.getBytes();
 
     val = info.get("length");
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
index 580d61bafe..ba633cb18f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
@@ -81,15 +81,14 @@ public class Peer implements Comparable<Peer>
   private long downloaded_old[] = {-1,-1,-1};
 
   private static final byte[] HANDSHAKE = DataHelper.getASCII("BitTorrent protocol");
+  // See BEP 4 for definitions
   //  bytes per bt spec:                         0011223344556677
   private static final long OPTION_EXTENSION = 0x0000000000100000l;
   private static final long OPTION_FAST      = 0x0000000000000004l;
   //private static final long OPTION_DHT       = 0x0000000000000001l;
-  /** we use a different bit since the compact format is different */
-/* no, let's use an extension message
-  static final long OPTION_I2P_DHT   = 0x0000000040000000l;
-*/
   //private static final long OPTION_AZMP      = 0x1000000000000000l;
+  // hybrid support TODO
+  private static final long OPTION_V2        = 0x0000000000000010L;
   private long options;
   private final boolean _isIncoming;
   private int _totalCommentsSent;
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index a06470abd9..b4737ee610 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -2801,6 +2801,10 @@ public class I2PSnarkServlet extends BasicServlet {
      *  @since 0.8.4
      */
     private void addMagnet(String url, File dataDir) {
+        if (url.startsWith(MagnetURI.MAGNET_FULL_V2)) {
+            _manager.addMessage("Version 2 magnet links are not supported");
+            return;
+        }
         try {
             MagnetURI magnet = new MagnetURI(_manager.util(), url);
             String name = magnet.getName();
-- 
GitLab