This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 3604a50efc8 branch-4.1: [fix](ddl) reject invalid IPv4 default value
at CREATE TABLE time #62906 (#64488)
3604a50efc8 is described below
commit 3604a50efc84bb3acf26f5da889be4a870ef6f7b
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Jun 16 14:13:05 2026 +0800
branch-4.1: [fix](ddl) reject invalid IPv4 default value at CREATE TABLE
time #62906 (#64488)
Cherry-picked from #62906
Co-authored-by: 924060929 <[email protected]>
---
.../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-core/src/main/java/org/apache/doris/analysis/IPv4Literal.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv4Literal.java
index 4df2309fbb9..1a7f6f03b2d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv4Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IPv4Literal.java
@@ -62,22 +62,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..20524be9ff7
--- /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" normalizes to the
same string 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").getStringValue(),
+ new
org.apache.doris.analysis.IPv4Literal("010.000.000.001").getStringValue());
+ 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]