Skip to content

fix(install.ps1): use ordinal IndexOf when stripping index URL credentials - #7286

Merged
danielhanchen merged 2 commits into
unslothai:mainfrom
Solaris-star:fix/7279-install-ps1-ordinal-url-parse
Jul 22, 2026
Merged

danielhanchen merged 2 commits into
unslothai:mainfrom
Solaris-star:fix/7279-install-ps1-ordinal-url-parse

Conversation

@Solaris-star

Copy link
Copy Markdown
Contributor

Summary

  • On non-English Windows locales (e.g. th-TH), culture-aware String.IndexOf can mis-locate punctuation-only markers like ://.
  • That corrupts scheme/authority parsing in Remove-IndexUrlCredentials and crashes with Substring ArgumentOutOfRangeException right after GPU detection.
  • Force StringComparison.Ordinal for scheme / path / userinfo parsing in install.ps1.

Fixes #7279

Test plan

  • Logic-level checks for plain URL, credentials, query string, no-scheme input
  • Windows th-TH locale: irm https://raw.githubusercontent.com/unslothai/unsloth/main/install.ps1 | iex should pass PyTorch index URL step without Substring crash

…tials

On non-English Windows locales, culture-aware String.IndexOf can
mis-locate punctuation-only markers like ://, which corrupts scheme and
authority parsing and crashes Remove-IndexUrlCredentials with a Substring
ArgumentOutOfRangeException (issue 7279).

Force Ordinal comparison for URL scheme/host parsing.

Fixes #7279

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request updates the Remove-IndexUrlCredentials function in install.ps1 to use culture-invariant ordinal string comparisons, preventing potential crashes on non-English Windows locales. The reviewer suggests a more robust refactoring of the function using the built-in [System.Uri] and [System.UriBuilder] classes to avoid manual string parsing.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread install.ps1
Comment on lines 2031 to 2049
function Remove-IndexUrlCredentials {
param([string]$Url)
$sep = $Url.IndexOf('://')
# URL parsing must be culture-invariant. On non-English Windows locales
# (e.g. th-TH), culture-aware IndexOf can mis-locate punctuation-only
# markers like "://", corrupting scheme/authority and crashing on
# Substring (issue #7279). Always use Ordinal comparison here.
$sep = $Url.IndexOf('://', [System.StringComparison]::Ordinal)
if ($sep -lt 0) { return $Url }
$scheme = $Url.Substring(0, $sep)
$rest = $Url.Substring($sep + 3)
# Drop query / fragment (may hold auth tokens).
$q = $rest.IndexOfAny([char[]]('?', '#'))
if ($q -ge 0) { $rest = $rest.Substring(0, $q) }
$slash = $rest.IndexOf('/')
$slash = $rest.IndexOf('/', [System.StringComparison]::Ordinal)
$authority = if ($slash -ge 0) { $rest.Substring(0, $slash) } else { $rest }
$at = $authority.LastIndexOf('@')
$at = $authority.LastIndexOf('@', [System.StringComparison]::Ordinal)
$host_ = if ($at -ge 0) { $authority.Substring($at + 1) } else { $authority }
if ($slash -ge 0) { return "${scheme}://${host_}$($rest.Substring($slash))" }
return "${scheme}://${host_}"

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.

medium

While using StringComparison.Ordinal is a good fix for the culture-specific issue, the entire function can be made more robust and maintainable by using the built-in [System.Uri] and [System.UriBuilder] classes for URL parsing and manipulation. This avoids manual string parsing, which can be error-prone.

This refactoring correctly removes user credentials, query strings, and fragments, while also handling various URL edge cases more gracefully. Note that this change will normalize URLs by adding a trailing slash to host-only URLs (e.g., https://example.com becomes https://example.com/), which is a standard practice.

function Remove-IndexUrlCredentials {
    param([string]$Url)

    if (-not ([System.Uri]::IsWellFormedUriString($Url, [System.UriKind]::Absolute))) {
        return $Url
    }

    try {
        $uri = [System.Uri]$Url
        $builder = [System.UriBuilder]::new($uri.Scheme, $uri.Host, $uri.Port, $uri.AbsolutePath)
        return $builder.Uri.AbsoluteUri
    } catch {
        return $Url
    }
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, but keeping the minimal ordinal fix here. This helper is documented to match the string parsing in install.sh and studio/install_python_stack.py, so a UriBuilder rewrite would diverge from those siblings. It also changes output: System.UriBuilder normalizes host-only URLs by appending a trailing slash (https://download.pytorch.org becomes https://download.pytorch.org/), and System.Uri applies its own path, percent-encoding and IDN normalization, any of which can alter a wheel index or mirror URL. The ordinal fix resolves the crash with no behavior change on well-formed URLs, so it stays.

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 4a11022f28

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 78b33a803a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danielhanchen
danielhanchen merged commit 5308c24 into unslothai:main Jul 22, 2026
1 check passed
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.

install.ps1 crashes with Substring ArgumentOutOfRangeException on non-English Windows locale (Remove-IndexUrlCredentials)

3 participants