Skip to content

fix: strip URI scheme prefixes from hostname input#533

Merged
torlando-tech merged 1 commit intorelease/v0.8.xfrom
fix/strip-hostname-uri-scheme-v0.8.x
Feb 23, 2026
Merged

fix: strip URI scheme prefixes from hostname input#533
torlando-tech merged 1 commit intorelease/v0.8.xfrom
fix/strip-hostname-uri-scheme-v0.8.x

Conversation

@torlando-tech
Copy link
Copy Markdown
Owner

Summary

  • validateHostname() now strips http:// and https:// prefixes (and any path component) before validation, so users who paste a full URL get the hostname extracted automatically
  • entityToConfig() uses the cleaned value from validation, fixing existing poison data in the database on read
  • validateConfigState() writes the cleaned hostname back to UI state so subsequent saves persist the sanitized value

Context

Fixes COLUMBA-43 — users entering http://rns.soon.it as a TCP host caused a fatal IllegalStateException when editing the interface config. 5 occurrences across 2 users on v0.8.12-beta.

Test plan

  • 5 new unit tests for scheme stripping (http, https, trailing slash, path, IP)
  • All existing InputValidatorTest, InterfaceRepositoryTest, and InterfaceManagementViewModelTest pass
  • Manual: enter http://rns.soon.it as TCP host, verify it saves as rns.soon.it
  • Manual: edit an existing interface with a scheme-prefixed host in the DB, verify no crash

🤖 Generated with Claude Code

Users pasting URLs like "http://rns.soon.it" instead of bare hostnames
caused a fatal IllegalStateException when editing the interface config.
validateHostname() now strips http:// and https:// prefixes, and callers
use the cleaned value instead of the raw input.

Fixes COLUMBA-43

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 23, 2026

Greptile Summary

This PR fixes a crash (IllegalStateException) caused by users entering full URLs (e.g., http://rns.soon.it) as TCP hostnames. The fix strips http:// and https:// scheme prefixes (and any path component) in InputValidator.validateHostname(), and propagates the cleaned value through both the repository layer (fixing existing poison data on read) and the ViewModel layer (updating UI state so subsequent saves persist the sanitized value).

  • InputValidator.validateHostname() now strips URI scheme prefixes, trailing slashes, and path components before validation
  • InterfaceRepository.entityToConfig() uses the cleaned hostname from ValidationResult.Success for TCPClient and TCPServer types, sanitizing existing bad data on read
  • InterfaceManagementViewModel.validateConfigState() writes the cleaned hostname back to _configState so the UI reflects the sanitized value
  • 5 new unit tests cover scheme stripping for http, https, trailing slashes, paths, and IP addresses
  • Issue: The RNode (TCP mode) and UDP interface branches in entityToConfig() still use the old pattern that discards the cleaned value — these should be updated for consistency to fully close the poison-data bug across all interface types

Confidence Score: 3/5

  • The core fix is correct and well-tested for TCPClient/TCPServer, but the same sanitization was not applied to RNode and UDP interface types, leaving a gap.
  • Score of 3 reflects that the primary fix is sound and backed by tests, but the inconsistent application across interface types in entityToConfig() means the poison-data issue is not fully resolved. The RNode TCP-mode and UDP branches still pass raw hostnames/IPs, which could trigger the same crash if users paste URLs there.
  • Pay close attention to app/src/main/java/com/lxmf/messenger/repository/InterfaceRepository.kt — specifically the RNode (line 274-280) and UDP (lines 332-346) validation branches that still discard the cleaned hostname.

Important Files Changed

Filename Overview
app/src/main/java/com/lxmf/messenger/util/validation/InputValidator.kt Core fix: validateHostname() now strips http:// and https:// scheme prefixes and path components. Logic is correct for the common case but does not handle port numbers in pasted URLs (e.g., http://host:8080).
app/src/main/java/com/lxmf/messenger/repository/InterfaceRepository.kt TCPClient and TCPServer branches now use the cleaned hostname from validation. However, RNode (TCP mode) and UDP branches still discard the cleaned value, leaving them vulnerable to the same poison-data issue this PR aims to fix.
app/src/main/java/com/lxmf/messenger/viewmodel/InterfaceManagementViewModel.kt Validation success branch now writes the cleaned hostname back to UI state for TCPClient and TCPServer. Formatting changes are consistent with the project's code style. No issues found.
app/src/test/java/com/lxmf/messenger/util/validation/InputValidatorTest.kt Adds 5 well-structured unit tests covering http/https scheme stripping, trailing slashes, paths, and IP addresses. Good coverage of the new behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["User enters hostname\n(e.g., http://rns.soon.it)"] --> B["InputValidator.validateHostname()"]
    B --> C["Strip scheme prefix\n(http:// / https://)"]
    C --> D["Strip trailing slash\nand path components"]
    D --> E{"Validate cleaned\nhostname"}
    E -->|Valid| F["ValidationResult.Success\n(cleaned value)"]
    E -->|Invalid| G["ValidationResult.Error"]

    F --> H["ViewModel:\nWrite back to _configState\n(targetHost / listenIp)"]
    F --> I["Repository:\nentityToConfig uses\ncleaned value"]

    H --> J["User sees sanitized\nhostname in UI"]
    I --> K["InterfaceConfig created\nwith clean hostname"]

    G --> L["Error shown to user"]

    style C fill:#d4edda,stroke:#28a745
    style D fill:#d4edda,stroke:#28a745
    style H fill:#d4edda,stroke:#28a745
    style I fill:#fff3cd,stroke:#ffc107
Loading

Last reviewed commit: 7e2138f

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +286 to +293
val cleaned =
host
.trim()
.removePrefix("http://")
.removePrefix("https://")
.removeSuffix("/")
.split("/")
.first() // Strip any path component after the hostname
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URLs with port numbers produce confusing errors

If a user pastes http://example.com:8080, this logic produces example.com:8080 after stripping the scheme. The :8080 portion is not a valid hostname character, so validation fails with "Invalid hostname or IP address" — which is technically correct but may confuse users.

Consider also stripping a trailing :port component (e.g., via split(":").first()), or at minimum providing a more specific error message when a colon is detected in the cleaned value (e.g., "Remove the port number — enter hostname and port separately").

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/src/main/java/com/lxmf/messenger/util/validation/InputValidator.kt
Line: 286-293

Comment:
**URLs with port numbers produce confusing errors**

If a user pastes `http://example.com:8080`, this logic produces `example.com:8080` after stripping the scheme. The `:8080` portion is not a valid hostname character, so validation fails with "Invalid hostname or IP address" — which is technically correct but may confuse users.

Consider also stripping a trailing `:port` component (e.g., via `split(":").first()`), or at minimum providing a more specific error message when a colon is detected in the cleaned value (e.g., "Remove the port number — enter hostname and port separately").

How can I resolve this? If you propose a fix, please make it concise.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 23, 2026

Additional Comments (1)

app/src/main/java/com/lxmf/messenger/repository/InterfaceRepository.kt
RNode TCP host not sanitized on read

The TCPClient and TCPServer branches were updated to use hostResult.value (the cleaned hostname), but the RNode TCP-mode branch at line 274–280 still uses the old else -> {} pattern and passes the raw tcpHost to InterfaceConfig.RNode at line 308. If a user stores http://somehost as an RNode TCP host, it will not be sanitized on read — the same class of bug this PR fixes for TCPClient/TCPServer.

Similarly, the UDP interface branch (lines 332–346) uses the same old pattern for listenIp and forwardIp, discarding the cleaned value.

Consider applying the same val cleanedHost = when (...) { Success -> result.value } pattern here for consistency.

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/src/main/java/com/lxmf/messenger/repository/InterfaceRepository.kt
Line: 274-280

Comment:
**RNode TCP host not sanitized on read**

The `TCPClient` and `TCPServer` branches were updated to use `hostResult.value` (the cleaned hostname), but the `RNode` TCP-mode branch at line 274–280 still uses the old `else -> {}` pattern and passes the raw `tcpHost` to `InterfaceConfig.RNode` at line 308. If a user stores `http://somehost` as an RNode TCP host, it will not be sanitized on read — the same class of bug this PR fixes for `TCPClient`/`TCPServer`.

Similarly, the `UDP` interface branch (lines 332–346) uses the same old pattern for `listenIp` and `forwardIp`, discarding the cleaned value.

Consider applying the same `val cleanedHost = when (...) { Success -> result.value }` pattern here for consistency.

How can I resolve this? If you propose a fix, please make it concise.

@torlando-tech torlando-tech merged commit 015f53b into release/v0.8.x Feb 23, 2026
2 checks passed
@torlando-tech torlando-tech deleted the fix/strip-hostname-uri-scheme-v0.8.x branch February 23, 2026 22:30
torlando-tech added a commit that referenced this pull request Feb 23, 2026
…vel stripping

Address Greptile review feedback on #533:
- Strip trailing :port from hostnames (e.g. "example.com:8080" → "example.com")
- Use cleaned values from validateHostname() in RNode TCP and UDP entityToConfig branches
- Strip http:// and https:// in UI text field onValueChange handlers for immediate feedback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
torlando-tech added a commit that referenced this pull request Feb 23, 2026
…vel stripping

Address Greptile review feedback on #533:
- Strip trailing :port from hostnames (e.g. "example.com:8080" → "example.com")
- Use cleaned values from validateHostname() in RNode TCP and UDP entityToConfig branches
- Strip http:// and https:// in UI text field onValueChange handlers for immediate feedback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant