Skip to content

fix: path, URI, JSON edit utility bugs - #334259

Open
Viraj Mishra (VirajMishra1) wants to merge 6 commits into
microsoft:mainfrom
VirajMishra1:fix-path-uri-util-bugs
Open

fix: path, URI, JSON edit utility bugs#334259
Viraj Mishra (VirajMishra1) wants to merge 6 commits into
microsoft:mainfrom
VirajMishra1:fix-path-uri-util-bugs

Conversation

@VirajMishra1

Copy link
Copy Markdown

fix: path, URI, JSON edit, and shell quoting bugs in utility modules

Five distinct correctness bugs across four files:

1. extpath.ts -- isRootOrDriveLetter checks wrong length variable

isRootOrDriveLetter normalizes the path then guards on path.length instead
of pathNormalized.length. A path like C:\\ (4 chars) normalizes to C:\
(3 chars), but path.length > 3 incorrectly rejects it. Same issue on the
drive-letter-only === 2 check.

2. jsonEdit.ts -- last-array-element removal corrupts the array

The deletion span was computed as parentEndOffset - 2 - offset.
parentEndOffset is one past the closing ], so the correct span is
parentEndOffset - 1 - offset. The extra -1 left a stale character before
], producing invalid JSON after removing the last array element.

3. terminalEnvironment.ts -- escapeNonWindowsPath uses invalid POSIX quoting

The singleQuotes branch produced 'path with '\'' embedded quote'.
Single-quoted strings in POSIX sh/bash/zsh are literal -- \' inside them is
not an escape sequence, it ends the string and emits a literal backslash-quote.
Fixed to $'...' (ANSI-C quoting), which correctly handles embedded single
quotes and matches the existing bothQuotes branch.

4. terminalEnvironment.ts -- collapseTildePath matches home path anywhere

normalizedPath.includes(normalizedUserHome) matches the home directory
anywhere in the path, e.g. /tmp/backup/home/viraj/file would incorrectly
collapse. Also susceptible to prefix collisions like /home/virajfoo.
Fixed to normalizedPath.startsWith(normalizedUserHome + '/') with an
additional equality check for the exact-home case.

5. uri.ts -- password in userinfo not fully percent-encoded

The password segment was encoded with encoder(..., false, true)
(isAuthority=true), which leaves : unencoded (safe in hostnames).
Per RFC 3986 ss. 3.2.1, : inside a password MUST be percent-encoded.
Fixed to encoder(..., false, false).

- extpath.ts: isRootOrDriveLetter checked path.length instead of
  pathNormalized.length, causing C:\\ (len 4) to be rejected even
  though it normalizes to the valid root C:\ (len 3)
- jsonEdit.ts: last-array-element removal used parentEndOffset - 2
  instead of - 1, leaving a stale character before the closing ]
- terminalEnvironment.ts: escapeNonWindowsPath singleQuotes branch for
  bash/sh/zsh/git-bash used plain '...' quoting, which cannot contain
  escaped single quotes; fixed to $'...' (ANSI-C quoting) matching
  the bothQuotes branch
- terminalEnvironment.ts: collapseTildePath used String.includes()
  instead of startsWith(), allowing a path like /home/virajfoo/x to
  incorrectly collapse when userHome is /home/viraj
- uri.ts: password component in userinfo was encoded with
  isAuthority=true, leaving ':' unencoded in passwords; fixed to false

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 3, 2026 14:18
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

Anthony Kim (@anthonykim1)

Matched files:

  • src/vs/platform/terminal/common/terminalEnvironment.ts

Copilot AI 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.

🟡 Changes recommended

The changes regress bare drive detection, mishandle POSIX sh, and do not fully encode passwords containing multiple colons.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes correctness issues in shared path, URI, JSON editing, and terminal utilities.

Changes:

  • Corrects normalized path and tilde-boundary checks.
  • Adjusts URI password encoding and JSON array removal spans.
  • Revises shell quoting for embedded single quotes.
File summaries
File Description
src/vs/base/common/extpath.ts Uses normalized lengths for root detection.
src/vs/base/common/jsonEdit.ts Corrects last-array-element deletion range.
src/vs/base/common/uri.ts Changes password-component encoding.
src/vs/platform/terminal/common/terminalEnvironment.ts Updates shell quoting and home-path matching.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 5
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/vs/base/common/extpath.ts Outdated
Comment thread src/vs/base/common/uri.ts
Comment thread src/vs/platform/terminal/common/terminalEnvironment.ts Outdated
Comment thread src/vs/base/common/jsonEdit.ts
Comment thread src/vs/platform/terminal/common/terminalEnvironment.ts Outdated
@VirajMishra1

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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.

Please create a separate PR for the terminal issue.

@VirajMishra1

Copy link
Copy Markdown
Author

Done, moved the terminal changes to #334988

@aeschli

Copy link
Copy Markdown
Contributor

Copilot please review

The early-return guard also needs path.length > 3, not
pathNormalized.length > 3. normalize('D:') can return 'D:.'
(3 chars), making pathNormalized.length === 3 while the original
path is only 2 chars — the guard must use the original path length.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

Add URI password-colon regression coverage and include or remove the unimplemented path and terminal fixes.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

src/vs/base/common/uri.ts:685

  • Please add a regression case for a password containing a colon, for example an authority like user:pa:ss@host expecting user:pa%3Ass@host. The existing user-info test only has one colon, so it does not verify that indexOf selects the user/password delimiter or that the password-specific encoding change preserves the remaining colon correctly.
			} else {
				// <user>:<pass>@<auth>
				res += encoder(userinfo.substr(0, idx), false, false);
				res += ':';
				res += encoder(userinfo.substr(idx + 1), false, false);

src/vs/base/common/uri.ts:678

  • The PR description claims fixes in extpath.ts and terminalEnvironment.ts, but neither file is changed in this patch, so those reported bugs remain: isRootOrDriveLetter still uses the unnormalized length (extpath.ts:323,328), collapseTildePath still uses an unbounded includes match (terminalEnvironment.ts:99), and the single-quote branches still emit invalid POSIX quoting (terminalEnvironment.ts:38,62). Please include the corresponding implementation and regression tests, or remove those fixes from the PR description.
			idx = userinfo.indexOf(':');
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

const offset = previous.offset + previous.length;
const parentEndOffset = parent.offset + parent.length;
edit = { offset, length: parentEndOffset - 2 - offset, content: '' };
edit = { offset, length: parentEndOffset - 1 - offset, content: '' };
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.

3 participants