Skip to content

feat(IpAddress): paste url support port#7377

Merged
ArgoZhang merged 3 commits intomainfrom
refactor-ip
Dec 19, 2025
Merged

feat(IpAddress): paste url support port#7377
ArgoZhang merged 3 commits intomainfrom
refactor-ip

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented Dec 19, 2025

Link issues

fixes #7376

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

New Features:

  • Allow the IpAddress input to extract and use an IPv4 address from pasted text that may include additional characters like URLs or ports.

Copilot AI review requested due to automatic review settings December 19, 2025 09:15
@bb-auto bb-auto bot added the enhancement New feature or request label Dec 19, 2025
@bb-auto bb-auto bot added this to the v10.1.0 milestone Dec 19, 2025
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Dec 19, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds support for pasting full URLs or strings containing an IPv4 address into the IpAddress component by extracting a valid IPv4 substring with regex and populating the IPv4 cells from that match, while simplifying parsing and removing value clamping.

Sequence diagram for handling pasted URL in IpAddress component

sequenceDiagram
    actor User
    participant Browser
    participant IpAddressInput as IpAddressInput
    participant IpAddressJs as IpAddressRazorJs

    User->>Browser: Paste string containing URL or IPv4
    Browser->>IpAddressInput: paste event with raw value
    IpAddressInput->>IpAddressJs: handlePaste(raw)

    IpAddressJs->>IpAddressJs: match = raw.match(ipRegex)
    IpAddressJs->>IpAddressJs: parts = match ? match[0] : null
    alt No IPv4 match
        IpAddressJs-->>IpAddressInput: return (ignore paste)
    else IPv4 match found
        IpAddressJs->>IpAddressJs: octets = parts.split('.')
        loop For each octet p (max 4)
            IpAddressJs->>IpAddressJs: num = parseInt(p, 10)
            IpAddressJs->>IpAddressInput: set cell value to num
            IpAddressJs->>IpAddressJs: update prevValues[pos]
        end
        IpAddressJs-->>IpAddressInput: paste handling complete
    end
Loading

File-Level Changes

Change Details Files
Support pasting strings/URLs that contain an IPv4 address into the IpAddress component and populate the four IPv4 cells from the matched address.
  • Replace the previous non-digit and non-dot stripping logic with a regular expression that finds a valid IPv4 address within the pasted text.
  • If no valid IPv4 address is found in the pasted content, abort processing without modifying the input cells.
  • Split the matched IPv4 string by dots to get octets and iterate through them to fill up to four IPv4 cells.
  • Remove clamping of octet values between 0 and 255 and use direct integer parsing for each octet before assigning values to the cells and prevValues.
src/BootstrapBlazor/Components/IpAddress/IpAddress.razor.js

Assessment against linked issues

Issue Objective Addressed Explanation
#7376 Enable the IpAddress component to correctly handle pasting a URL that includes a port (e.g., http://127.0.0.1:8080) by extracting and filling only the IPv4 address into the IP cells.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@ArgoZhang ArgoZhang merged commit 395749c into main Dec 19, 2025
7 of 8 checks passed
@ArgoZhang ArgoZhang deleted the refactor-ip branch December 19, 2025 09:16
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Consider keeping the clamping logic (Math.max(0, Math.min(255, ...))) when parsing octets so the component is more defensive against any unexpected inputs or future changes to the regex.
  • The parts variable now changes type from string to being treated like an array (parts.split('.')); renaming it (e.g., ipString) or splitting immediately after the match would make the code’s intent and data flow clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider keeping the clamping logic (`Math.max(0, Math.min(255, ...))`) when parsing octets so the component is more defensive against any unexpected inputs or future changes to the regex.
- The `parts` variable now changes type from `string` to being treated like an array (`parts.split('.')`); renaming it (e.g., `ipString`) or splitting immediately after the match would make the code’s intent and data flow clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the IP address component to support pasting URLs that include port numbers. Previously, the paste handler used simple string manipulation to extract digits and dots, which would fail when pasting values like "192.168.1.1:8080". The new implementation uses a regex pattern to extract valid IPv4 addresses from the pasted content.

Key Changes:

  • Replaced string manipulation (replace(/[^\d.]/g, '')) with regex pattern matching to extract valid IPv4 addresses
  • Changed from filtering parts array to extracting the first matched IP address from the pasted text
  • Removed defensive validation (Math.max/Math.min bounds checking) from the parseInt operation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return;
}
const num = Math.max(0, Math.min(255, parseInt(p, 10) || 0));
const num = parseInt(p, 10);
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

Removing the Math.max and Math.min validation is unsafe. While the regex validates that matched IPs have octets in the 0-255 range, the parseInt on line 113 should still include fallback validation. The original code protected against any unexpected parsing issues by ensuring values are always bounded. Without the '|| 0' fallback, parseInt could theoretically return NaN in edge cases, and without the Math.min(255, ...) check, there's no defensive programming against future code changes. This defensive validation should be retained.

Suggested change
const num = parseInt(p, 10);
const parsed = parseInt(p, 10);
const num = Math.max(0, Math.min(255, isNaN(parsed) ? 0 : parsed));

Copilot uses AI. Check for mistakes.
}
const parts = raw.replace(/[^\d.]/g, '').split('.').filter(p => p.length);

const ipRegex = /\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The IP address regex pattern is complex and should be extracted to a constant at the module level with a descriptive name like IP_ADDRESS_PATTERN. This improves code maintainability by making the pattern reusable and easier to test or modify. The regex could also use a comment explaining its purpose of extracting valid IPv4 addresses from text that may contain additional content like ports.

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +104
const ipRegex = /\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
const match = raw.match(ipRegex);
const parts = match ? match[0] : null;
if (parts === null) {
return;
}
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The new paste behavior that extracts IP addresses from URLs with ports lacks test coverage. Tests should be added to verify that pasting values like "192.168.1.1:8080" correctly extracts "192.168.1.1", and that edge cases like malformed URLs, URLs without IPs, or multiple IPs are handled appropriately.

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov bot commented Dec 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (6ecb251) to head (8f4b15b).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #7377   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          748       748           
  Lines        32766     32766           
  Branches      4545      4545           
=========================================
  Hits         32766     32766           
Flag Coverage Δ
BB 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(IpAddress): paste url support port

2 participants