Fix parsing of empty labels and messages, and parsing of labels and messages with an unescaped equals sign in their value.

This commit is contained in:
Andreas Schildbach 2014-04-21 18:51:07 +02:00 committed by Mike Hearn
parent b3162cbc17
commit b0fa5435a2
2 changed files with 23 additions and 53 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012, 2014 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,6 +32,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
@ -192,14 +193,15 @@ public class BitcoinURI {
private void parseParameters(@Nullable NetworkParameters params, String addressToken, String[] nameValuePairTokens) throws BitcoinURIParseException {
// Attempt to decode the rest of the tokens into a parameter map.
for (String nameValuePairToken : nameValuePairTokens) {
String[] tokens = nameValuePairToken.split("=");
if (tokens.length != 2 || "".equals(tokens[0])) {
throw new BitcoinURIParseException("Malformed Bitcoin URI - cannot parse name value pair '" +
final int sepIndex = nameValuePairToken.indexOf('=');
if (sepIndex == -1)
throw new BitcoinURIParseException("Malformed Bitcoin URI - no separator in '" +
nameValuePairToken + "'");
}
String nameToken = tokens[0].toLowerCase();
String valueToken = tokens[1];
if (sepIndex == 0)
throw new BitcoinURIParseException("Malformed Bitcoin URI - empty name '" +
nameValuePairToken + "'");
final String nameToken = nameValuePairToken.substring(0, sepIndex).toLowerCase(Locale.ENGLISH);
final String valueToken = nameValuePairToken.substring(sepIndex + 1);
// Parse the amount.
if (FIELD_AMOUNT.equals(nameToken)) {
@ -219,7 +221,8 @@ public class BitcoinURI {
} else {
// Known fields and unknown parameters that are optional.
try {
putWithValidation(nameToken, URLDecoder.decode(valueToken, "UTF-8"));
if (valueToken.length() > 0)
putWithValidation(nameToken, URLDecoder.decode(valueToken, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// Unreachable.
throw new RuntimeException(e);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012, 2014 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -271,38 +271,16 @@ public class BitcoinURITest {
}
}
/**
* Handles a badly formatted label field
*
* @throws BitcoinURIParseException
* If something goes wrong
*/
@Test
public void testBad_Label() throws BitcoinURIParseException {
try {
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
+ "?label=");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("label"));
}
public void testEmpty_Label() throws BitcoinURIParseException {
assertNull(new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
+ "?label=").getLabel());
}
/**
* Handles a badly formatted message field
*
* @throws BitcoinURIParseException
* If something goes wrong
*/
@Test
public void testBad_Message() throws BitcoinURIParseException {
try {
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
+ "?message=");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("message"));
}
public void testEmpty_Message() throws BitcoinURIParseException {
assertNull(new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
+ "?message=").getMessage());
}
/**
@ -322,21 +300,10 @@ public class BitcoinURITest {
}
}
/**
* Handles case when there are too many equals
*
* @throws BitcoinURIParseException
* If something goes wrong
*/
@Test
public void testBad_TooManyEquals() throws BitcoinURIParseException {
try {
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
+ "?label=aardvark=zebra");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("cannot parse name value pair"));
}
public void testGood_ManyEquals() throws BitcoinURIParseException {
assertEquals("aardvark=zebra", new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":"
+ MAINNET_GOOD_ADDRESS + "?label=aardvark=zebra").getLabel());
}
/**
@ -377,7 +344,7 @@ public class BitcoinURITest {
+ "?aardvark");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("cannot parse name value pair"));
assertTrue(e.getMessage().contains("no separator"));
}
// Unknown and required field