[tor-commits] [metrics-lib/master] Accept extra arguments in extra-info descriptors.

karsten at torproject.org karsten at torproject.org
Tue May 9 15:18:32 UTC 2017


commit 71885a8e694b2a37b8a868389e4ea6d1ac037b30
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Wed May 3 09:41:10 2017 +0200

    Accept extra arguments in extra-info descriptors.
    
    According to the specification it's valid to add extra arguments to
    descriptor lines unless they are tagged with "[No extra arguments]".
    This is not the case for any of the statistics-related lines in
    extra-info descriptors, so we should allow extra arguments there.
    
    Fixes #21934.
---
 CHANGELOG.md                                       |   4 +
 .../descriptor/impl/BandwidthHistoryImpl.java      |   4 +-
 .../descriptor/impl/ExtraInfoDescriptorImpl.java   |  12 +-
 .../torproject/descriptor/impl/ParseHelper.java    |  16 ---
 .../impl/ExtraInfoDescriptorImplTest.java          | 127 +++++++++++++++++++++
 .../descriptor/impl/ServerDescriptorImplTest.java  |   6 +-
 6 files changed, 142 insertions(+), 27 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index da9cb37..a7f0aac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@
      below crypto blocks were silently skipped.
    - Add support for six new key-value pairs added by OnionPerf.
 
+ * Minor changes
+   - Accept extra arguments in statistics-related extra-info
+     descriptor lines, as permitted by dir-spec.txt.
+
 
 # Changes in version 1.6.0 - 2017-02-17
 
diff --git a/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java b/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
index 8f18b62..ef29a3b 100644
--- a/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
@@ -15,7 +15,7 @@ public class BandwidthHistoryImpl implements BandwidthHistory {
       String[] partsNoOpt) throws DescriptorParseException {
     boolean isValid = false;
     this.line = line;
-    if (partsNoOpt.length == 5 || partsNoOpt.length == 6) {
+    if (partsNoOpt.length >= 5) {
       try {
         this.historyEndMillis = ParseHelper.parseTimestampAtIndex(line,
             partsNoOpt, 1, 2);
@@ -32,7 +32,7 @@ public class BandwidthHistoryImpl implements BandwidthHistory {
               && partsNoOpt[4].equals("s)")) {
             /* There are no bandwidth values to parse. */
             isValid = true;
-          } else if (partsNoOpt.length == 6) {
+          } else if (partsNoOpt.length >= 6) {
             /* There are bandwidth values to parse. */
             values = partsNoOpt[5].split(",", -1);
           } else if (partsNoOpt[4].length() > 2) {
diff --git a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index 136f31e..bbaae19 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -324,7 +324,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
 
   private void parseGeoipDbDigestLine(String line, String lineNoOpt,
       String[] partsNoOpt) throws DescriptorParseException {
-    if (partsNoOpt.length != 2) {
+    if (partsNoOpt.length < 2) {
       throw new DescriptorParseException("Illegal line '" + line
           + "' in extra-info descriptor.");
     }
@@ -334,7 +334,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
 
   private void parseGeoip6DbDigestLine(String line, String lineNoOpt,
       String[] partsNoOpt) throws DescriptorParseException {
-    if (partsNoOpt.length != 2) {
+    if (partsNoOpt.length < 2) {
       throw new DescriptorParseException("Illegal line '" + line
           + "' in extra-info descriptor.");
     }
@@ -344,7 +344,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
 
   private void parseGeoipStartTimeLine(String line, String lineNoOpt,
       String[] partsNoOpt) throws DescriptorParseException {
-    if (partsNoOpt.length != 3) {
+    if (partsNoOpt.length < 3) {
       throw new DescriptorParseException("Illegal line '" + line
           + "' in extra-info descriptor.");
     }
@@ -369,7 +369,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
 
   private long[] parseStatsEndLine(String line, String[] partsNoOpt,
       int partsNoOptExpectedLength) throws DescriptorParseException {
-    if (partsNoOpt.length != partsNoOptExpectedLength
+    if (partsNoOpt.length < partsNoOptExpectedLength
         || partsNoOpt[3].length() < 2 || !partsNoOpt[3].startsWith("(")
         || !partsNoOpt[4].equals("s)")) {
       throw new DescriptorParseException("Illegal line '" + line + "'.");
@@ -424,7 +424,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
   private double parseShareLine(String line, String[] partsNoOpt)
       throws DescriptorParseException {
     double share = -1.0;
-    if (partsNoOpt.length == 2 && partsNoOpt[1].length() >= 2
+    if (partsNoOpt.length >= 2 && partsNoOpt[1].length() >= 2
         && partsNoOpt[1].endsWith("%")) {
       String shareString = partsNoOpt[1];
       shareString = shareString.substring(0, shareString.length() - 1);
@@ -550,7 +550,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
       String lineNoOpt, String[] partsNoOpt)
       throws DescriptorParseException {
     int circuits = -1;
-    if (partsNoOpt.length == 2) {
+    if (partsNoOpt.length >= 2) {
       try {
         circuits = Integer.parseInt(partsNoOpt[1]);
       } catch (NumberFormatException e) {
diff --git a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
index f73a591..fa6ca75 100644
--- a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
+++ b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
@@ -341,10 +341,6 @@ public class ParseHelper {
     if (partsNoOpt.length < index) {
       throw new DescriptorParseException("Line '" + line + "' does not "
           + "contain a key-value list at index " + index + ".");
-    } else if (partsNoOpt.length > index + 1 ) {
-      throw new DescriptorParseException("Line '" + line + "' contains "
-          + "unrecognized values beyond the expected key-value list at "
-          + "index " + index + ".");
     } else if (partsNoOpt.length > index) {
       if (!commaSeparatedKeyValueListPatterns.containsKey(keyLength)) {
         String keyPattern = "[0-9a-zA-Z?<>\\-_]"
@@ -390,10 +386,6 @@ public class ParseHelper {
     if (partsNoOpt.length < index) {
       throw new DescriptorParseException("Line '" + line + "' does not "
           + "contain a key-value list at index " + index + ".");
-    } else if (partsNoOpt.length > index + 1 ) {
-      throw new DescriptorParseException("Line '" + line + "' contains "
-          + "unrecognized values beyond the expected key-value list at "
-          + "index " + index + ".");
     } else if (partsNoOpt.length > index) {
       String[] listElements = partsNoOpt[index].split(",", -1);
       for (String listElement : listElements) {
@@ -428,10 +420,6 @@ public class ParseHelper {
       throw new DescriptorParseException("Line '" + line + "' does not "
           + "contain a comma-separated value list at index " + index
           + ".");
-    } else if (partsNoOpt.length > index + 1) {
-      throw new DescriptorParseException("Line '" + line + "' contains "
-          + "unrecognized values beyond the expected comma-separated "
-          + "value list at index " + index + ".");
     } else if (partsNoOpt.length > index) {
       String[] listElements = partsNoOpt[index].split(",", -1);
       result = new Integer[listElements.length];
@@ -456,10 +444,6 @@ public class ParseHelper {
       throw new DescriptorParseException("Line '" + line + "' does not "
           + "contain a comma-separated value list at index " + index
           + ".");
-    } else if (partsNoOpt.length > index + 1) {
-      throw new DescriptorParseException("Line '" + line + "' contains "
-          + "unrecognized values beyond the expected comma-separated "
-          + "value list at index " + index + ".");
     } else if (partsNoOpt.length > index) {
       String[] listElements = partsNoOpt[index].split(",", -1);
       result = new Double[listElements.length];
diff --git a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
index c29df8c..118ada8 100644
--- a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
@@ -1093,6 +1093,14 @@ public class ExtraInfoDescriptorImplTest {
         + "81281024,,60625920,67922944");
   }
 
+  @Test()
+  public void testDirreqWriteHistoryExtraArg() throws DescriptorParseException {
+    DescriptorBuilder.createWithDirreqWriteHistoryLine(
+        "dirreq-write-history "
+        + "2012-02-11 09:03:39 (900 s) 81281024,64996352,60625920,"
+        + "67922944 bin_size=1024");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testDirreqReadHistoryMissingBytesEnd()
       throws DescriptorParseException {
@@ -1131,6 +1139,17 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testGeoipDbDigestExtraArg() throws DescriptorParseException {
+    ExtraInfoDescriptor descriptor = DescriptorBuilder
+        .createWithGeoip6DbDigestLine("geoip-db-digest "
+            + "916A3CA8B7DF61473D5AE5B21711F35F301CE9E8 "
+            + "yblgrXtEgF3glaKv5ZvHhRREUI1t1c37SxparXSmYR4Q1yiK5zg4HE8eT9ILPRW9"
+            + "3I5W/pZGQxL8Bu42dGjnAQ");
+    assertEquals("916A3CA8B7DF61473D5AE5B21711F35F301CE9E8",
+        descriptor.getGeoipDbDigest());
+  }
+
+  @Test()
   public void testGeoip6DbDigestValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = DescriptorBuilder
         .createWithGeoip6DbDigestLine("geoip6-db-digest "
@@ -1140,6 +1159,17 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testGeoip6DbDigestExtraArg() throws DescriptorParseException {
+    ExtraInfoDescriptor descriptor = DescriptorBuilder
+        .createWithGeoip6DbDigestLine("geoip6-db-digest "
+            + "916A3CA8B7DF61473D5AE5B21711F35F301CE9E8 "
+            + "yblgrXtEgF3glaKv5ZvHhRREUI1t1c37SxparXSmYR4Q1yiK5zg4HE8eT9ILPRW9"
+            + "3I5W/pZGQxL8Bu42dGjnAQ");
+    assertEquals("916A3CA8B7DF61473D5AE5B21711F35F301CE9E8",
+        descriptor.getGeoip6DbDigest());
+  }
+
+  @Test()
   public void testGeoipStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = GeoipStatsBuilder
         .createWithDefaultLines();
@@ -1242,6 +1272,14 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testGeoipClientOriginsExtraArg()
+      throws DescriptorParseException {
+    GeoipStatsBuilder.createWithGeoipClientOriginsLine(
+        "geoip-client-origins de=1152,de=952,cn=896,us=712,it=504 "
+            + "ru=352 fr=208 gb=208 ir=200");
+  }
+
+  @Test()
   public void testDirreqStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = DirreqStatsBuilder
         .createWithDefaultLines();
@@ -1279,6 +1317,13 @@ public class ExtraInfoDescriptorImplTest {
         + "2012-02-11 00:59:53 (172800 s)");
   }
 
+  @Test()
+  public void testDirreqStatsExtraArg()
+      throws DescriptorParseException {
+    DirreqStatsBuilder.createWithDirreqStatsEndLine("dirreq-stats-end "
+        + "2012-02-11 00:59:53 (172800 s) XXXXXXXXXXXXXXXXXXXXXXXXXXX");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testDirreqV3IpsThreeLetterCountry()
       throws DescriptorParseException {
@@ -1287,6 +1332,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testDirreqV3IpsExtraArg()
+      throws DescriptorParseException {
+    DirreqStatsBuilder.createWithDirreqV3IpsLine("dirreq-v3-ips "
+        + "ab=12,cd=34 ef=56");
+  }
+
+  @Test()
   public void testDirreqV2IpsDigitCountry()
       throws DescriptorParseException {
     DirreqStatsBuilder.createWithDirreqV2IpsLine("dirreq-v2-ips 00=8");
@@ -1312,6 +1364,13 @@ public class ExtraInfoDescriptorImplTest {
         + "ok==10848");
   }
 
+  @Test()
+  public void testDirreqV3RespExtraArg()
+      throws DescriptorParseException {
+    DirreqStatsBuilder.createWithDirreqV3RespLine("dirreq-v3-resp "
+        + "ok=1084 4801=ko");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testDirreqV2RespNull()
       throws DescriptorParseException {
@@ -1333,6 +1392,13 @@ public class ExtraInfoDescriptorImplTest {
         + "0.37");
   }
 
+  @Test()
+  public void testDirreqV3ShareExtraArg()
+      throws DescriptorParseException {
+    DirreqStatsBuilder.createWithDirreqV3ShareLine("dirreq-v3-share "
+        + "0.37% 123456");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testDirreqV3DirectDlSpace()
       throws DescriptorParseException {
@@ -1362,6 +1428,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testDirreqV3TunneledDlExtraArg()
+      throws DescriptorParseException {
+    DirreqStatsBuilder.createWithDirreqV2TunneledDlLine(
+        "dirreq-v2-tunneled-dl complete=-8 incomplete=1/-8");
+  }
+
+  @Test()
   public void testEntryStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = EntryStatsBuilder
         .createWithDefaultLines();
@@ -1443,6 +1516,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testCellCircuitsPerDecileExtraArg()
+      throws DescriptorParseException {
+    CellStatsBuilder.createWithCellCircuitsPerDecileLine(
+        "cell-circuits-per-decile 866 866 866 866 866");
+  }
+
+  @Test()
   public void testConnBiDirectValid()
       throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = DescriptorBuilder
@@ -1465,6 +1545,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testConnBiDirectStatsExtraArg()
+      throws DescriptorParseException {
+    DescriptorBuilder.createWithConnBiDirectLine("conn-bi-direct "
+        + "2012-02-11 01:59:39 (86400 s) 42173,1591,1310,1744 +1");
+  }
+
+  @Test()
   public void testExitStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = ExitStatsBuilder
         .createWithDefaultLines();
@@ -1541,6 +1628,12 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testExitStatsStreamsExtraArg() throws DescriptorParseException {
+    ExitStatsBuilder.createWithExitStreamsOpenedLine(
+        "exit-streams-opened 25=21474 3648");
+  }
+
+  @Test()
   public void testBridgeStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = BridgeStatsBuilder
         .createWithDefaultLines();
@@ -1570,6 +1663,13 @@ public class ExtraInfoDescriptorImplTest {
         + "2012-02-11 01:59:39 (0 s)");
   }
 
+  @Test()
+  public void testBridgeStatsEndExtraArg()
+      throws DescriptorParseException {
+    BridgeStatsBuilder.createWithBridgeStatsEndLine("bridge-stats-end "
+        + "2012-02-11 01:59:39 (86400 s) 99999999999999999999999999999999");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testBridgeIpsDouble()
       throws DescriptorParseException {
@@ -1585,6 +1685,12 @@ public class ExtraInfoDescriptorImplTest {
         0x69, 0x70, 0x73 }, false);               // "ips" (no newline)
   }
 
+  @Test()
+  public void testBridgeIpsExtraArg()
+      throws DescriptorParseException {
+    BridgeStatsBuilder.createWithBridgeIpsLine("bridge-ips ir=24 5");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testBridgeIpVersionsDouble()
       throws DescriptorParseException {
@@ -1592,6 +1698,13 @@ public class ExtraInfoDescriptorImplTest {
         "bridge-ip-versions v4=24.5");
   }
 
+  @Test()
+  public void testBridgeIpVersionsExtraArg()
+      throws DescriptorParseException {
+    BridgeStatsBuilder.createWithBridgeIpVersionsLine(
+        "bridge-ip-versions v4=24 5");
+  }
+
   @Test(expected = DescriptorParseException.class)
   public void testBridgeIpTransportsDouble()
       throws DescriptorParseException {
@@ -1607,6 +1720,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testBridgeIpTransportsExtraArg()
+      throws DescriptorParseException {
+    BridgeStatsBuilder.createWithBridgeIpTransportsLine(
+        "bridge-ip-transports obfs2=24 5");
+  }
+
+  @Test()
   public void testHidservStatsValid() throws DescriptorParseException {
     ExtraInfoDescriptor descriptor = HidservStatsBuilder
         .createWithDefaultLines();
@@ -1670,6 +1790,13 @@ public class ExtraInfoDescriptorImplTest {
   }
 
   @Test()
+  public void testHidservDirOnionsSeenExtraArg()
+      throws DescriptorParseException {
+    HidservStatsBuilder.createWithHidservDirOnionsSeenLine(
+        "hidserv-dir-onions-seen -3 delta_f=8 epsilon=0.30 bin_size=8 pi=3");
+  }
+
+  @Test()
   public void testRouterSignatureOpt()
       throws DescriptorParseException {
     DescriptorBuilder.createWithRouterSignatureLines("opt "
diff --git a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
index 80dc815..b713dd6 100644
--- a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
@@ -1245,11 +1245,11 @@ public class ServerDescriptorImplTest {
         "write-history 2012-01-01 03:51:44 (900 ");
   }
 
-  @Test(expected = DescriptorParseException.class)
-  public void testWriteHistoryTrailingNumber()
+  @Test()
+  public void testWriteHistoryExtraArg()
       throws DescriptorParseException {
     DescriptorBuilder.createWithWriteHistoryLine("write-history "
-        + "2012-01-01 03:51:44 (900 s) 4345856 1");
+        + "2012-01-01 03:51:44 (900 s) 4345856 bin_size=1024");
   }
 
   @Test()





More information about the tor-commits mailing list