Mapping API: Improve IP address validation

Until now, IP addresses were only checked for four dots, which
allowed invalid values like 127.0.0.111111

This adds an additional check for validation.

Closes #7131
This commit is contained in:
Alexander Reelsen 2014-08-08 08:48:38 +02:00
parent 9e4064a9ba
commit 724b14cef6
2 changed files with 58 additions and 26 deletions

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.mapper.ip; package org.elasticsearch.index.mapper.ip;
import com.google.common.net.InetAddresses;
import org.apache.lucene.analysis.NumericTokenStream; import org.apache.lucene.analysis.NumericTokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
@ -79,9 +80,12 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
public static long ipToLong(String ip) throws ElasticsearchIllegalArgumentException { public static long ipToLong(String ip) throws ElasticsearchIllegalArgumentException {
try { try {
if (!InetAddresses.isInetAddress(ip)) {
throw new ElasticsearchIllegalArgumentException("failed to parse ip [" + ip + "], not a valid ip address");
}
String[] octets = pattern.split(ip); String[] octets = pattern.split(ip);
if (octets.length != 4) { if (octets.length != 4) {
throw new ElasticsearchIllegalArgumentException("failed to parse ip [" + ip + "], not full ip address (4 dots)"); throw new ElasticsearchIllegalArgumentException("failed to parse ip [" + ip + "], not a valid ipv4 address (4 dots)");
} }
return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) + return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) +
(Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]); (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);

View File

@ -19,34 +19,62 @@
package org.elasticsearch.index.mapper.ip; package org.elasticsearch.index.mapper.ip;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.junit.Ignore; import org.elasticsearch.bootstrap.Elasticsearch;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
/** /**
* *
*/ */
@Ignore("No tests?") public class SimpleIpMappingTests extends ElasticsearchSingleNodeTest {
public class SimpleIpMappingTests extends ElasticsearchTestCase {
@Test
public void testSimpleMapping() throws Exception {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("ip").field("type", "ip").endObject().endObject()
.endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping);
ParsedDocument doc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder()
.startObject()
.field("ip", "127.0.0.1")
.endObject()
.bytes());
assertThat(doc.rootDoc().getField("ip").numericValue().longValue(), is(2130706433L));
assertThat(doc.rootDoc().get("ip"), is(nullValue()));
}
@Test
public void testThatValidIpCanBeConvertedToLong() throws Exception {
assertThat(IpFieldMapper.ipToLong("127.0.0.1"), is(2130706433L));
}
@Test
public void testThatInvalidIpThrowsException() throws Exception {
try {
IpFieldMapper.ipToLong("127.0.011.1111111");
fail("Expected ip address parsing to fail but did not happen");
} catch (ElasticsearchIllegalArgumentException e) {
assertThat(e.getMessage(), containsString("not a valid ip address"));
}
}
@Test
public void testThatIpv6AddressThrowsException() throws Exception {
try {
IpFieldMapper.ipToLong("2001:db8:0:8d3:0:8a2e:70:7344");
fail("Expected ip address parsing to fail but did not happen");
} catch (ElasticsearchIllegalArgumentException e) {
assertThat(e.getMessage(), containsString("not a valid ipv4 address"));
}
}
// No Longer enabled...
// @Test public void testAutoIpDetection() throws Exception {
// String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
// .startObject("properties").endObject()
// .endObject().endObject().string();
//
// XContentDocumentMapper defaultMapper = MapperTests.newParser().parse(mapping);
//
// ParsedDocument doc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder()
// .startObject()
// .field("ip1", "127.0.0.1")
// .field("ip2", "0.1")
// .field("ip3", "127.0.0.1.2")
// .endObject()
// .copiedBytes());
//
// assertThat(doc.doc().getFieldable("ip1"), notNullValue());
// assertThat(doc.doc().get("ip1"), nullValue()); // its numeric
// assertThat(doc.doc().get("ip2"), equalTo("0.1"));
// assertThat(doc.doc().get("ip3"), equalTo("127.0.0.1.2"));
// }
} }