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:
parent
9e4064a9ba
commit
724b14cef6
|
@ -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]);
|
||||||
|
|
|
@ -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"));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue