forked from I2P_Developers/i2p.i2p
i2psnark: Fix bencoded scrape response for zzzot (ticket #1994)
requires zzzot 0.16.0
This commit is contained in:
@ -23,13 +23,17 @@ package org.klomp.snark.bencode;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
|
||||||
public class BEncoder
|
public class BEncoder
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -155,6 +159,12 @@ public class BEncoder
|
|||||||
out.write(bs);
|
out.write(bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys must be Strings or (supported as of 0.9.31) byte[]s
|
||||||
|
* A mix in the same Map is not supported.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if keys are not all Strings or all byte[]s
|
||||||
|
*/
|
||||||
public static byte[] bencode(Map<?, ?> m)
|
public static byte[] bencode(Map<?, ?> m)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -169,31 +179,71 @@ public class BEncoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys must be Strings or (supported as of 0.9.31) byte[]s
|
||||||
|
* A mix in the same Map is not supported.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if keys are not all Strings or all byte[]s
|
||||||
|
*/
|
||||||
public static void bencode(Map<?, ?> m, OutputStream out)
|
public static void bencode(Map<?, ?> m, OutputStream out)
|
||||||
throws IOException, IllegalArgumentException
|
throws IOException, IllegalArgumentException
|
||||||
{
|
{
|
||||||
out.write('d');
|
out.write('d');
|
||||||
|
|
||||||
// Keys must be sorted. XXX - But is this the correct order?
|
|
||||||
Set<?> s = m.keySet();
|
Set<?> s = m.keySet();
|
||||||
List<String> l = new ArrayList<String>(s.size());
|
List<String> l = null;
|
||||||
for (Object k : s) {
|
List<byte[]> b = null;
|
||||||
// Keys must be Strings.
|
try {
|
||||||
if (String.class.isAssignableFrom(k.getClass()))
|
for (Object k : s) {
|
||||||
l.add((String) k);
|
if (l != null) {
|
||||||
else
|
l.add((String) k);
|
||||||
throw new IllegalArgumentException("Cannot bencode map: contains non-String key of type " + k.getClass());
|
} else if (b != null) {
|
||||||
|
b.add((byte[]) k);
|
||||||
|
} else if (String.class.isAssignableFrom(k.getClass())) {
|
||||||
|
l = new ArrayList<String>(s.size());
|
||||||
|
l.add((String) k);
|
||||||
|
} else if (byte[].class.isAssignableFrom(k.getClass())) {
|
||||||
|
b = new ArrayList<byte[]>(s.size());
|
||||||
|
b.add((byte[]) k);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot bencode map: contains key of type " + k.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new IllegalArgumentException("Cannot bencode map: mixed keys", cce);
|
||||||
}
|
}
|
||||||
Collections.sort(l);
|
|
||||||
|
|
||||||
Iterator<String> it = l.iterator();
|
if (l != null) {
|
||||||
while(it.hasNext())
|
// Keys must be sorted. XXX - This is not the correct order.
|
||||||
{
|
// Spec says to sort by bytes, not lexically
|
||||||
String key = it.next();
|
Collections.sort(l);
|
||||||
bencode(key, out);
|
for (String key : l) {
|
||||||
bencode(m.get(key), out);
|
bencode(key, out);
|
||||||
}
|
bencode(m.get(key), out);
|
||||||
|
}
|
||||||
|
} else if (b != null) {
|
||||||
|
// Works for arrays of equal lengths, otherwise is probably not
|
||||||
|
// what the bittorrent spec intends.
|
||||||
|
Collections.sort(b, new BAComparator());
|
||||||
|
for (byte[] key : b) {
|
||||||
|
bencode(key, out);
|
||||||
|
bencode(m.get(key), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out.write('e');
|
out.write('e');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorter arrays are less. See DataHelper.compareTo()
|
||||||
|
* Works for arrays of equal lengths, otherwise is probably not
|
||||||
|
* what the bittorrent spec intends.
|
||||||
|
*
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
private static class BAComparator implements Comparator<byte[]>, Serializable {
|
||||||
|
public int compare(byte[] l, byte[] r) {
|
||||||
|
return DataHelper.compareTo(l, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
2017-05-21 zzz
|
||||||
|
* i2psnark: Fix bencoded scrape response for zzzot (ticket #1994)
|
||||||
|
|
||||||
2017-05-21 str4d
|
2017-05-21 str4d
|
||||||
* i2psnark: Integrate ratings and comments into themes
|
* i2psnark: Integrate ratings and comments into themes
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 7;
|
public final static long BUILD = 8;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user