forked from I2P_Developers/i2p.i2p
Data: Check key order when parsing RI mappings and fail-fast if out-of-order
before the signature check
This commit is contained in:
@ -134,7 +134,8 @@ public class DataHelper {
|
||||
* is repeated until there are no more bytes (not characters!) left as defined by the
|
||||
* first two byte integer.
|
||||
*
|
||||
* As of 0.9.18, throws DataFormatException on duplicate key
|
||||
* As of 0.9.18, throws DataFormatException on duplicate key
|
||||
* Does NOT enforce key ordering.
|
||||
*
|
||||
* @param rawStream stream to read the mapping from
|
||||
* @throws DataFormatException if the format is invalid
|
||||
@ -152,6 +153,7 @@ public class DataHelper {
|
||||
* Ditto, load into an existing properties
|
||||
*
|
||||
* As of 0.9.18, throws DataFormatException on duplicate key
|
||||
* Does NOT enforce key ordering.
|
||||
*
|
||||
* @param props The Properties to load into.
|
||||
* As of 0.9.38, if null, a new OrderedProperties will be created.
|
||||
@ -163,6 +165,26 @@ public class DataHelper {
|
||||
* @since 0.8.13
|
||||
*/
|
||||
public static Properties readProperties(InputStream rawStream, Properties props)
|
||||
throws DataFormatException, IOException {
|
||||
return readProperties(rawStream, props, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ditto, load into an existing properties
|
||||
*
|
||||
* As of 0.9.18, throws DataFormatException on duplicate key
|
||||
*
|
||||
* @param props The Properties to load into.
|
||||
* As of 0.9.38, if null, a new OrderedProperties will be created.
|
||||
* @param rawStream stream to read the mapping from
|
||||
* @param enforceOrder if true, throw DataFormatException if keys are not ordered
|
||||
* @throws DataFormatException if the format is invalid
|
||||
* @throws IOException if there is a problem reading the data
|
||||
* @return the parameter props, or (as of 0.9.38) a new OrderedProperties if props is null,
|
||||
* and an immutable EmptyProperties if empty.
|
||||
* @since 0.9.66
|
||||
*/
|
||||
public static Properties readProperties(InputStream rawStream, Properties props, boolean enforceOrder)
|
||||
throws DataFormatException, IOException {
|
||||
int size = (int) readLong(rawStream, 2);
|
||||
if (size == 0) {
|
||||
@ -174,11 +196,15 @@ public class DataHelper {
|
||||
// full read guaranteed
|
||||
read(rawStream, data);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(data);
|
||||
String prev = "";
|
||||
while (in.available() > 0) {
|
||||
String key = readString(in);
|
||||
String cached = _propertiesKeyCache.get(key);
|
||||
if (cached != null)
|
||||
key = cached;
|
||||
if (enforceOrder && key.compareTo(prev) <= 0)
|
||||
throw new DataFormatException("option " + key + " out of order");
|
||||
prev = key;
|
||||
int b = in.read();
|
||||
if (b != '=')
|
||||
throw new DataFormatException("Bad key");
|
||||
|
@ -292,7 +292,9 @@ public class RouterAddress extends DataStructureImpl {
|
||||
_transportStyle = "NTCP";
|
||||
else if (_transportStyle.equals("SSU2"))
|
||||
_transportStyle = "SSU2";
|
||||
DataHelper.readProperties(in, _options);
|
||||
// enforce mapping order so bad ones will fail-fast
|
||||
// before the signature check
|
||||
DataHelper.readProperties(in, _options, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -606,7 +606,9 @@ public class RouterInfo extends DatabaseEntry {
|
||||
_peers.add(peerIdentityHash);
|
||||
}
|
||||
}
|
||||
DataHelper.readProperties(din, _options);
|
||||
// enforce mapping order so bad ones will fail-fast
|
||||
// before the signature check
|
||||
DataHelper.readProperties(din, _options, true);
|
||||
_signature = new Signature(type);
|
||||
_signature.readBytes(in);
|
||||
|
||||
|
Reference in New Issue
Block a user