bitflicker64 commented on code in PR #3105:
URL: https://github.com/apache/hugegraph/pull/3105#discussion_r3662057853


##########
hugegraph-server/hugegraph-dist/src/assembly/static/bin/util.sh:
##########
@@ -118,18 +119,170 @@ function process_id() {
     return "$pid"
 }
 
-# check the port of rest server is occupied
-function check_port() {
-    local port=$(echo "$1" | sed 's|.*:||' | sed 's|/.*||')
-    if ! command_available "lsof"; then
-        echo "Required lsof but it is unavailable"
-        exit 1
+# Extract a validated TCP port from a configured server URL.
+# Echoes the port on success.  Returns 1 when the value carries no usable port
+# or is ambiguous, in which case the caller skips the preflight.
+function parse_port_from_url() {
+    local url="$1"
+
+    # ServerOptions tolerates surrounding whitespace, so strip it first.
+    url="${url#"${url%%[![:space:]]*}"}"
+    url="${url%"${url##*[![:space:]]}"}"
+    [[ -z "$url" ]] && return 1
+
+    # The scheme is optional and case-insensitive.
+    local scheme="" rest="$url"
+    if [[ "$url" == *"://"* ]]; then
+        scheme=$(echo "${url%%://*}" | tr '[:upper:]' '[:lower:]')
+        rest="${url#*://}"
     fi
-    lsof -i :"$port" >/dev/null
-    if [ $? -eq 0 ]; then
-        echo "The port $port has already been used"
-        exit 1
+
+    # The authority ends at the first '/', '?' or '#'.
+    local authority="${rest%%[/?#]*}"
+    [[ -z "$authority" ]] && return 1
+
+    # Drop any userinfo prefix; its colon would otherwise look like an
+    # unbracketed IPv6 separator.
+    authority="${authority##*@}"
+    [[ -z "$authority" ]] && return 1
+
+    local port=""
+    if [[ "$authority" =~ ^\[[^]]*\](:([0-9]+))?$ ]]; then
+        # Bracketed IPv6, with or without a port: [::1] or [::1]:8080
+        port="${BASH_REMATCH[2]}"
+    elif [[ "$authority" == *:*:* ]]; then
+        # Unbracketed IPv6 is ambiguous: in "::1:8080" the trailing group may
+        # be a port or another hextet.  Refuse to guess.
+        # TODO(check_port): no preflight runs at all for this form.  If
+        # ServerOptions ever guarantees a normalized bracketed value here, this
+        # branch can resolve the port instead of skipping the check.
+        echo "WARN: ambiguous IPv6 authority '$authority' in server URL;" \
+             "use bracket notation such as [::1]:8080." >&2
+        return 1
+    elif [[ "$authority" == *:* ]]; then
+        port="${authority##*:}"
+    fi
+
+    # Fall back to the scheme's default port.
+    # TODO(check_port): a scheme-less value with no explicit port (e.g. plain
+    # "127.0.0.1") has no derivable port, so it is skipped rather than guessed.
+    # Reading the configured default from ServerOptions would close this gap.
+    if [[ -z "$port" ]]; then
+        case "$scheme" in
+            http)  port="80" ;;
+            https) port="443" ;;
+            *)     return 1 ;;
+        esac
     fi
+
+    [[ "$port" =~ ^[0-9]+$ ]] || return 1
+    # Normalise leading-zero forms; Java reads 08080 as decimal 8080.
+    port=$((10#$port))

Review Comment:
   Confirmed and fixed in `a413325b`. Your repro is correct, and the case is a 
bit wider than the value you found.
   
   `18446744073709551617` wraps to `1`, but the worse shape is a value that 
wraps into a plausible port:
   
   ```
   before: parse_port_from_url "http://127.0.0.1:18446744073709559616";  ->  8000
   after : rc=1 (skipped)
   ```
   
   That one mattered more than the wrap to `1`: the preflight would have 
aborted startup with "The port 8000 has already been used", naming a port the 
operator never configured, for what is really a malformed value.
   
   The fix normalises the leading-zero form textually and bounds the digit 
count before any arithmetic:
   
   ```bash
   port="${port#"${port%%[!0]*}"}"
   [[ -z "$port" ]] && return 1
   (( ${#port} <= 5 )) || return 1
   (( port >= 1 && port <= 65535 )) || return 1
   ```
   
   Leading zeroes are still accepted, since `new 
URI("http://127.0.0.1:0000000000000008080";).getPort()` returns `8080` — I 
checked rather than assumed. `00000` returns `0` there and is skipped.
   
   Four cases added to the URL-parsing table: both wrapping values, `00000`, 
and the long leading-zero form. The suite is **48 passed, 0 failed**, and 
restoring `port=$((10#$port))` fails exactly the two overflow cases, so they 
are not vacuous.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to