3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 15:22:16 +00:00

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 * 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 * 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.URISyntaxException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull; 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 { private void parseParameters(@Nullable NetworkParameters params, String addressToken, String[] nameValuePairTokens) throws BitcoinURIParseException {
// Attempt to decode the rest of the tokens into a parameter map. // Attempt to decode the rest of the tokens into a parameter map.
for (String nameValuePairToken : nameValuePairTokens) { for (String nameValuePairToken : nameValuePairTokens) {
String[] tokens = nameValuePairToken.split("="); final int sepIndex = nameValuePairToken.indexOf('=');
if (tokens.length != 2 || "".equals(tokens[0])) { if (sepIndex == -1)
throw new BitcoinURIParseException("Malformed Bitcoin URI - cannot parse name value pair '" + throw new BitcoinURIParseException("Malformed Bitcoin URI - no separator in '" +
nameValuePairToken + "'"); nameValuePairToken + "'");
} if (sepIndex == 0)
throw new BitcoinURIParseException("Malformed Bitcoin URI - empty name '" +
String nameToken = tokens[0].toLowerCase(); nameValuePairToken + "'");
String valueToken = tokens[1]; final String nameToken = nameValuePairToken.substring(0, sepIndex).toLowerCase(Locale.ENGLISH);
final String valueToken = nameValuePairToken.substring(sepIndex + 1);
// Parse the amount. // Parse the amount.
if (FIELD_AMOUNT.equals(nameToken)) { if (FIELD_AMOUNT.equals(nameToken)) {
@ -219,7 +221,8 @@ public class BitcoinURI {
} else { } else {
// Known fields and unknown parameters that are optional. // Known fields and unknown parameters that are optional.
try { try {
putWithValidation(nameToken, URLDecoder.decode(valueToken, "UTF-8")); if (valueToken.length() > 0)
putWithValidation(nameToken, URLDecoder.decode(valueToken, "UTF-8"));
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// Unreachable. // Unreachable.
throw new RuntimeException(e); 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 * 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 * 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 @Test
public void testBad_Label() throws BitcoinURIParseException { public void testEmpty_Label() throws BitcoinURIParseException {
try { assertNull(new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS + "?label=").getLabel());
+ "?label=");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("label"));
}
} }
/**
* Handles a badly formatted message field
*
* @throws BitcoinURIParseException
* If something goes wrong
*/
@Test @Test
public void testBad_Message() throws BitcoinURIParseException { public void testEmpty_Message() throws BitcoinURIParseException {
try { assertNull(new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS + "?message=").getMessage());
+ "?message=");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("message"));
}
} }
/** /**
@ -322,21 +300,10 @@ public class BitcoinURITest {
} }
} }
/**
* Handles case when there are too many equals
*
* @throws BitcoinURIParseException
* If something goes wrong
*/
@Test @Test
public void testBad_TooManyEquals() throws BitcoinURIParseException { public void testGood_ManyEquals() throws BitcoinURIParseException {
try { assertEquals("aardvark=zebra", new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":"
testObject = new BitcoinURI(MainNetParams.get(), BitcoinURI.BITCOIN_SCHEME + ":" + MAINNET_GOOD_ADDRESS + MAINNET_GOOD_ADDRESS + "?label=aardvark=zebra").getLabel());
+ "?label=aardvark=zebra");
fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("cannot parse name value pair"));
}
} }
/** /**
@ -377,7 +344,7 @@ public class BitcoinURITest {
+ "?aardvark"); + "?aardvark");
fail("Expecting BitcoinURIParseException"); fail("Expecting BitcoinURIParseException");
} catch (BitcoinURIParseException e) { } catch (BitcoinURIParseException e) {
assertTrue(e.getMessage().contains("cannot parse name value pair")); assertTrue(e.getMessage().contains("no separator"));
} }
// Unknown and required field // Unknown and required field