godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.38k stars 21.26k forks source link

Incorrect results for 'is_valid_ip_address()' for compressed IPv6 adresses using '::' #99623

Open MarcusPaulsson opened 1 day ago

MarcusPaulsson commented 1 day ago

Tested versions

4.4 dev

System information

Godot v4.4.dev (0c45ace15) - Windows 10.0.18363 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 32.0.15.6614) - Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz (8 threads)

Issue description

The is_valid_ip_address() method has inconsistent behavior when validating IPv6 addresses with multiple occurrences of ::. According to the IPv6 standard, :: can only appear once in an address to represent consecutive zero segments, but currently, for example, the method incorrectly validates addresses like 2001:db8:::1 and 2001::1::1 as valid. These padding styles should not be possible.

Down below are some test cases that shows that the methods returns true when we expect false Image

Steps to reproduce

extends Node

func _ready() -> void:
        print("\nTesting is_valid_ip_address() Method:\n")

        print("Valid IPv4 Addresses:")
        print("Input: ", "192.168.1.1",         "\t -> Result:", "192.168.1.1".is_valid_ip_address())         # Expected: true
        print("Input: ", "255.255.255.255",     "\t -> Result:", "255.255.255.255".is_valid_ip_address())     # Expected: true (broadcast address)

        print("\nInvalid IPv4 Addresses:")
        print("Input: ", "256.256.256.256",     "\t -> Result:", "256.256.256.256".is_valid_ip_address())     # Expected: false (out of range)
        print("Input: ", "192.168.1",           "\t -> Result:", "192.168.1".is_valid_ip_address())           # Expected: false (missing octet)
        print("Input: ", "192.168.-1.1",        "\t -> Result:", "192.168.-1.1".is_valid_ip_address())        # Expected: false (negative octet)

        print("\nValid IPv6 Addresses:")
        print("Input: ", "::1",                 "\t -> Result:", "::1".is_valid_ip_address())                 # Expected: true (loopback address)
        print("Input: ", "2001:db8::",          "\t -> Result:", "2001:db8::".is_valid_ip_address())          # Expected: true (trailing `::`)

        print("\nInvalid IPv6 Addresses:")
        print("Input: ", "2001:db8:::1",        "\t -> Result:", "2001:db8:::1".is_valid_ip_address())        # Expected: false (multiple `::`)
        print("Input: ", "2001::1::1",          "\t -> Result:", "2001::1::1".is_valid_ip_address())          # Expected: false (multiple `::`)
        print("Input: ", "::ffff:999.999.999.999","\t -> Result:", "::ffff:999.999.999.999".is_valid_ip_address()) # Expected: false (invalid IPv4 in IPv6)

        print("\nEdge Cases:")
        print("Input: ", "",                    "\t -> Result:", "".is_valid_ip_address())                    # Expected: false (empty string)
        print("Input: ", ":1",                  "\t -> Result:", ":1".is_valid_ip_address())                  # Expected: false (incomplete address)
        print("Input: ", "12345::",             "\t -> Result:", "12345::".is_valid_ip_address())             # Expected: false (invalid segment length)

Minimal reproduction project (MRP)

N/A