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]

Reply via email to