This is an automated email from the ASF dual-hosted git repository.
924060929 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 1a23a77d941 [fix](ddl) reject invalid IPv4 default value at CREATE
TABLE time (#62906)
1a23a77d941 is described below
commit 1a23a77d94153bf5a4511df806d6aa1592b935f3
Author: 924060929 <[email protected]>
AuthorDate: Sun Jun 14 17:54:26 2026 +0800
[fix](ddl) reject invalid IPv4 default value at CREATE TABLE time (#62906)
Problem Summary:
`IPv4Literal.parseIPv4toLong` silently returned `0L` for invalid input
(e.g. `'not_an_ip'`), so `ColumnDef.validateDefaultValue` accepted any
string as an IPv4 default value at CREATE TABLE time. The invalid
default only fails later at INSERT/stream load time.
Changed the three `return 0L` error paths to `throw AnalysisException`,
matching the behavior of `IPv6Literal` which already rejects invalid
defaults at DDL time.
---
.../org/apache/doris/analysis/IPv4Literal.java | 34 ++++---
.../trees/expressions/literal/IPV4LiteralTest.java | 100 +++++++++++++++++++++
2 files changed, 124 insertions(+), 10 deletions(-)
diff --git
a/fe/fe-catalog/src/main/java/org/apache/doris/analysis/IPv4Literal.java
b/fe/fe-catalog/src/main/java/org/apache/doris/analysis/IPv4Literal.java
index 57fd79867ed..1c57e69cf9b 100644
--- a/fe/fe-catalog/src/main/java/org/apache/doris/analysis/IPv4Literal.java
+++ b/fe/fe-catalog/src/main/java/org/apache/doris/analysis/IPv4Literal.java
@@ -56,22 +56,36 @@ public class IPv4Literal extends LiteralExpr {
this.value = other.value;
}
- private static long parseIPv4toLong(String ipv4) {
- String[] parts = ipv4.split("\\.");
+ private static long parseIPv4toLong(String ipv4) throws AnalysisException {
+ // Use limit -1 so a trailing dot keeps its empty part: "1.2.3.4."
stays 5 parts and is
+ // rejected by the count check below (plain split("\\.") drops the
trailing "" and would
+ // wrongly yield 4). An IPv4 address must be exactly 4 dot-separated
parts.
+ String[] parts = ipv4.split("\\.", -1);
if (parts.length != 4) {
- return 0L;
+ throw new AnalysisException("Invalid IPv4 format: " + ipv4);
}
long value = 0L;
for (int i = 0; i < 4; ++i) {
- short octet;
- try {
- octet = Short.parseShort(parts[i]);
- } catch (NumberFormatException e) {
- return 0L;
+ String part = parts[i];
+ // Each octet must be 1-3 ASCII digits. Short.parseShort alone is
too lax for a DDL
+ // validator: it accepts a leading '+' and Unicode digits
(fullwidth, Arabic-Indic,
+ // etc.), which BE's ASCII-only parse_ipv4 later rejects, turning
the stored default
+ // into a late failure at load time. So check ASCII digits
explicitly here. Leading
+ // zeros stay decimal ("010" -> 10), consistent with the BE parser
and Nereids.
+ if (part.isEmpty() || part.length() > 3) {
+ throw new AnalysisException("Invalid IPv4 format: " + ipv4);
}
- if (octet < 0 || octet > 255) {
- return 0L;
+ for (int j = 0; j < part.length(); ++j) {
+ char c = part.charAt(j);
+ if (c < '0' || c > '9') {
+ throw new AnalysisException("Invalid IPv4 format: " +
ipv4);
+ }
+ }
+ // Safe now: 1-3 ASCII digits never overflow short and never throw.
+ short octet = Short.parseShort(part);
+ if (octet > 255) {
+ throw new AnalysisException("Invalid IPv4 format: " + ipv4);
}
value = (value << 8) | octet;
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV4LiteralTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV4LiteralTest.java
new file mode 100644
index 00000000000..43b89b3dc48
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IPV4LiteralTest.java
@@ -0,0 +1,100 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.literal;
+
+import org.apache.doris.analysis.ColumnDef;
+import org.apache.doris.catalog.Type;
+import org.apache.doris.common.AnalysisException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class IPV4LiteralTest {
+
+ @Test
+ public void testValidIPv4() throws AnalysisException {
+ new org.apache.doris.analysis.IPv4Literal("0.0.0.0");
+ new org.apache.doris.analysis.IPv4Literal("192.168.1.1");
+ new org.apache.doris.analysis.IPv4Literal("255.255.255.255");
+ new org.apache.doris.analysis.IPv4Literal("10.0.0.1");
+ // leading zeros are decimal (not octal) and accepted, consistent with
the BE
+ // parser and the Nereids literal: "010.000.000.001" parses to the
same value as
+ // "10.0.0.1". Rejecting them here would break already-valid IPv4
defaults.
+ Assertions.assertEquals(
+ new
org.apache.doris.analysis.IPv4Literal("10.0.0.1").getValue(),
+ new
org.apache.doris.analysis.IPv4Literal("010.000.000.001").getValue());
+ new org.apache.doris.analysis.IPv4Literal("010.0.0.1");
+ }
+
+ @Test
+ public void testInvalidIPv4() {
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("not_an_ip"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("256.0.0.0"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new
org.apache.doris.analysis.IPv4Literal("999.999.999.999"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.3"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.3.4.5"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal(""));
+ // trailing dot / trailing empty octet: split("\\.") used to drop
these tokens
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.3.4."));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.3.4.."));
+ // signed octet: Short.parseShort used to accept a leading '+' or '-'
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.+3.4"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.-3.4"));
+ // leading empty octet and embedded whitespace are rejected
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal(".1.2.3"));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.3. 4"));
+ // a colon-containing IPv4-mapped IPv6 form must not be accepted as a
plain IPv4 literal
+ Assertions.assertThrows(AnalysisException.class,
+ () -> new
org.apache.doris.analysis.IPv4Literal("::ffff:1.2.3.4"));
+ // Unicode digits: Short.parseShort and Character.isDigit accept them,
but BE's parse_ipv4
+ // is ASCII-only, so reject them at CREATE TABLE time instead of
failing later at load.
+ Assertions.assertThrows(AnalysisException.class, // fullwidth digits
U+FF11.. for "127.0.0.1"
+ () -> new org.apache.doris.analysis.IPv4Literal("127.0.0.1"));
+ Assertions.assertThrows(AnalysisException.class, // Arabic-Indic digit
U+0663 in 3rd octet
+ () -> new org.apache.doris.analysis.IPv4Literal("1.2.٣.4"));
+ }
+
+ @Test
+ public void testValidateDefaultValueIPv4() throws AnalysisException {
+ ColumnDef.validateDefaultValue(Type.IPV4, "192.168.0.1", null);
+ ColumnDef.validateDefaultValue(Type.IPV4, "0.0.0.0", null);
+ ColumnDef.validateDefaultValue(Type.IPV4, "255.255.255.255", null);
+ }
+
+ @Test
+ public void testValidateDefaultValueIPv4Invalid() {
+ Assertions.assertThrows(AnalysisException.class,
+ () -> ColumnDef.validateDefaultValue(Type.IPV4, "not_an_ip",
null));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> ColumnDef.validateDefaultValue(Type.IPV4,
"999.999.999.999", null));
+ Assertions.assertThrows(AnalysisException.class,
+ () -> ColumnDef.validateDefaultValue(Type.IPV4, "256.0.0.1",
null));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]