From 10664bdd9a5f3f0d9b593a8936149a942ea9bc31 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 20 Aug 2025 07:56:16 +0200 Subject: [PATCH 1/2] Fix offset handling in ipv6 parsing --- .../common/network/InetAddresses.java | 4 +- .../common/network/InetAddressesTests.java | 38 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/network/InetAddresses.java b/server/src/main/java/org/elasticsearch/common/network/InetAddresses.java index e315984b6e668..802638daaaf40 100644 --- a/server/src/main/java/org/elasticsearch/common/network/InetAddresses.java +++ b/server/src/main/java/org/elasticsearch/common/network/InetAddresses.java @@ -239,8 +239,8 @@ private static byte[] textToNumericFormatV6(byte[] ipUtf8, int offset, int lengt return null; // Invalid character } } - if (currentHextetStart != length) { - // Handle the last hextet + // Handle the last hextet unless the IP address ends with :: + if (currentHextetStart < offset + length) { if (putHextet(bytes, currentHextet) == false) { return null; } diff --git a/server/src/test/java/org/elasticsearch/common/network/InetAddressesTests.java b/server/src/test/java/org/elasticsearch/common/network/InetAddressesTests.java index 9d544c00f15ff..dd10b08fd0945 100644 --- a/server/src/test/java/org/elasticsearch/common/network/InetAddressesTests.java +++ b/server/src/test/java/org/elasticsearch/common/network/InetAddressesTests.java @@ -27,6 +27,7 @@ import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.Enumeration; +import java.util.List; import java.util.Locale; import static org.hamcrest.Matchers.equalTo; @@ -180,10 +181,12 @@ public void testConvertDottedQuadToHex() throws UnknownHostException { // Shouldn't hit DNS, because it's an IP string literal. InetAddress ipv6Addr = InetAddress.getByName(ipString); assertEquals(ipv6Addr, InetAddresses.forString(ipString)); + int extraLength = randomInt(8); + int offset = randomInt(extraLength); byte[] asBytes = ipString.getBytes(StandardCharsets.UTF_8); - byte[] bytes = new byte[32]; - System.arraycopy(asBytes, 0, bytes, 8, asBytes.length); - assertEquals(ipv6Addr, InetAddresses.forString(bytes, 8, asBytes.length)); + byte[] bytes = new byte[asBytes.length + extraLength]; + System.arraycopy(asBytes, 0, bytes, offset, asBytes.length); + assertEquals(ipv6Addr, InetAddresses.forString(bytes, offset, asBytes.length)); assertTrue(InetAddresses.isInetAddress(ipString)); } } @@ -206,6 +209,35 @@ public void testToAddrStringIPv6() { assertEquals("::1", InetAddresses.toAddrString(InetAddresses.forString("0:0:0:0:0:0:0:1"))); assertEquals("2001:658:22a:cafe::", InetAddresses.toAddrString(InetAddresses.forString("2001:0658:022a:cafe::"))); assertEquals("::102:304", InetAddresses.toAddrString(InetAddresses.forString("::1.2.3.4"))); + assertEquals("2001:db8::1:0:0:1", InetAddresses.toAddrString(InetAddresses.forString("2001:db8::1:0:0:1"))); + } + + public void testWithOffsets() { + List ipStrings = List.of( + "1:2:3:4:5:6:7:8", + "2001:0:0:4::8", + "2001::4:5:6:7:8", + "2001:0:3:4:5:6:7:8", + "0:0:3::ffff", + "::4:0:0:0:ffff", + "::5:0:0:ffff", + "1::4:0:0:7:8", + "::", + "::1", + "2001:658:22a:cafe::", + "::102:304", + "2001:db8::1:0:0:1", + "2001:db8::1:0:1:0" + ); + for (String ipString : ipStrings) { + byte[] bytes = ipString.getBytes(StandardCharsets.UTF_8); + int extraLength = randomInt(8); + int offset = randomInt(extraLength); + byte[] bytesWithPadding = new byte[bytes.length + extraLength]; + System.arraycopy(bytes, 0, bytesWithPadding, offset, bytes.length); + InetAddress addr = InetAddresses.forString(bytesWithPadding, offset, bytes.length); + assertEquals(ipString, InetAddresses.toAddrString(addr)); + } } public void testToUriStringIPv4() { From 442f29ba5b9aca7a412f59ec86e71253975a3a12 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 20 Aug 2025 15:19:46 +0200 Subject: [PATCH 2/2] Unmute IpFieldBlockLoaderTests --- muted-tests.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 2cc77cf8bb140..56476dc46ab9f 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -576,24 +576,6 @@ tests: - class: org.elasticsearch.xpack.ml.integration.TextEmbeddingQueryIT method: testModelWithPrefixStrings issue: https://github.com/elastic/elasticsearch/issues/133138 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderOfMultiField {preference=Params[syntheticSource=true, preference=DOC_VALUES]} - issue: https://github.com/elastic/elasticsearch/issues/133149 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderOfMultiField {preference=Params[syntheticSource=true, preference=STORED]} - issue: https://github.com/elastic/elasticsearch/issues/133150 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderOfMultiField {preference=Params[syntheticSource=true, preference=NONE]} - issue: https://github.com/elastic/elasticsearch/issues/133151 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderForFieldInObject {preference=Params[syntheticSource=true, preference=STORED]} - issue: https://github.com/elastic/elasticsearch/issues/133178 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderForFieldInObject {preference=Params[syntheticSource=true, preference=DOC_VALUES]} - issue: https://github.com/elastic/elasticsearch/issues/133179 -- class: org.elasticsearch.index.mapper.blockloader.IpFieldBlockLoaderTests - method: testBlockLoaderForFieldInObject {preference=Params[syntheticSource=true, preference=NONE]} - issue: https://github.com/elastic/elasticsearch/issues/133180 - class: org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT method: test {p0=search.vectors/90_sparse_vector/Indexing and searching multi-value sparse vectors in >=8.15} issue: https://github.com/elastic/elasticsearch/issues/133184