Skip to content

Commit

Permalink
fix: url encoding of url-unsafe characters (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
chdsbd authored Apr 17, 2021
1 parent 3ff8e33 commit 08bd7c5
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 18 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## 1.0.1 - 2021-04-17

### Fixed

- Fixed URL escaping of branch and file names.

## 1.0.0 - 2021-04-17

### Added
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ The "main" branch is configured via `githubinator.mainBranches` (see "Extension

## Release Notes

## 1.0.1

- Fixed URL escaping of branch and file names.

## 1.0.0

- support multiple default branches. vscode-githubinator now attempts to open `main`, then `master`, `trunk`, `develop`, and `dev`. Configure these branches with the `githubinator.mainBranches` option.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "githubinator",
"displayName": "Githubinator",
"description": "Quickly open files on Github and other providers. View blame information, copy permalinks and more. See the \"commands\" section of the README for more details.",
"version": "1.0.0",
"version": "1.0.1",
"publisher": "chdsbd",
"license": "SEE LICENSE IN LICENSE",
"icon": "images/logo256.png",
Expand Down Expand Up @@ -301,6 +301,7 @@
},
"devDependencies": {
"@types/ini": "^1.3.30",
"@types/lodash": "^4.14.168",
"@types/mocha": "^2.2.42",
"@types/mz": "^0.0.32",
"@types/node": "^10.12.21",
Expand All @@ -312,6 +313,7 @@
"dependencies": {
"gitconfiglocal": "^2.1.0",
"ini": "^1.3.5",
"lodash": "^4.17.21",
"mz": "^2.7.0"
}
}
7 changes: 4 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,11 @@ async function githubinator({
return err("could not find url")
}
if (openUrl) {
vscode.env.openExternal(vscode.Uri.parse(url))
// @ts-ignore This works. Using vscode.Uri.parse double encodes characters which breaks URLs.
await vscode.env.openExternal(url)
}
if (copyToClipboard) {
vscode.env.clipboard.writeText(url)
vscode.window.showInformationMessage("URL copied to clipboard.")
await vscode.env.clipboard.writeText(url)
await vscode.window.showInformationMessage("URL copied to clipboard.")
}
}
35 changes: 21 additions & 14 deletions src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from "path"
import * as url from "url"
import { IProviderConfig } from "./extension"
import { cleanHostname } from "./utils"
import { flatten } from "lodash"

interface IBaseGetUrls {
readonly selection: [number | null, number | null]
Expand Down Expand Up @@ -102,6 +103,12 @@ abstract class BaseProvider {
abstract getUrls(params: IBaseGetUrls): Promise<IUrlInfo | null>
}

export function pathJoin(...args: string[]): string {
return path.join(
...flatten(args.map(x => x.split("/"))).map(encodeURIComponent),
)
}

export class Github extends BaseProvider {
DEFAULT_HOSTNAMES = ["github.com"]
PROVIDER_NAME = "github"
Expand Down Expand Up @@ -132,7 +139,7 @@ export class Github extends BaseProvider {
return null
}
const u = new url.URL(
path.join(
pathJoin(
repoInfo.org,
repoInfo.repo,
mode,
Expand All @@ -150,11 +157,11 @@ export class Github extends BaseProvider {
const blameUrl = createUrl("blame")
const historyUrl = createUrl("commits", false)
const compareUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo, "compare", head.value),
pathJoin(repoInfo.org, repoInfo.repo, "compare", head.value),
rootUrl,
).toString()
const prUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo, "pull", "new", head.value),
pathJoin(repoInfo.org, repoInfo.repo, "pull", "new", head.value),
rootUrl,
).toString()
return {
Expand Down Expand Up @@ -190,15 +197,15 @@ export class Gitlab extends BaseProvider {
const lines =
start != null && end != null ? `L${start + 1}-${end + 1}` : null
const repoUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo),
pathJoin(repoInfo.org, repoInfo.repo),
rootUrl,
).toString()
const createUrl = (mode: string, hash = true) => {
if (relativeFilePath == null) {
return null
}
const u = new url.URL(
path.join(
pathJoin(
repoInfo.org,
repoInfo.repo,
mode,
Expand All @@ -216,12 +223,12 @@ export class Gitlab extends BaseProvider {
const blameUrl = createUrl("blame")
const historyUrl = createUrl("commits", false)
const compareUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo, "compare", head.value),
pathJoin(repoInfo.org, repoInfo.repo, "compare", head.value),
rootUrl,
).toString()
// https://gitlab.com/recipeyak/recipeyak/merge_requests/new?merge_request%5Bsource_branch%5D=master
const prUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo, "merge_requests", "new"),
pathJoin(repoInfo.org, repoInfo.repo, "merge_requests", "new"),
rootUrl,
)
prUrl.search = `merge_request%5Bsource_branch%5D=${head.value}`
Expand Down Expand Up @@ -258,15 +265,15 @@ export class Bitbucket extends BaseProvider {
const lines =
start != null && end != null ? `lines-${start + 1}:${end + 1}` : null
const repoUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo),
pathJoin(repoInfo.org, repoInfo.repo),
rootUrl,
).toString()
const createUrl = (mode: string, hash = true) => {
if (relativeFilePath == null) {
return null
}
const u = new url.URL(
path.join(
pathJoin(
repoInfo.org,
repoInfo.repo,
mode,
Expand All @@ -283,7 +290,7 @@ export class Bitbucket extends BaseProvider {
const blobUrl = createUrl("blob")
const blameUrl = createUrl("annotate")
const compareUrl = new url.URL(
path.join(
pathJoin(
repoInfo.org,
repoInfo.repo,
"branches",
Expand All @@ -295,7 +302,7 @@ export class Bitbucket extends BaseProvider {
const historyUrl = createUrl("history-node", false)
// "https://bitbucket.org/recipeyak/recipeyak/pull-requests/new?source=db99a912f5c4bffe11d91e163cd78ed96589611b"
const prUrl = new url.URL(
path.join(repoInfo.org, repoInfo.repo, "pull-requests", "new"),
pathJoin(repoInfo.org, repoInfo.repo, "pull-requests", "new"),
rootUrl,
)
prUrl.search = `source=${head.value}`
Expand Down Expand Up @@ -337,7 +344,7 @@ export class VisualStudio extends BaseProvider {
? `&line=${start + 1}&lineEnd=${end + 1}`
: null
const repoUrl = new url.URL(
path.join(repoInfo.org, "_git", repoInfo.repo),
pathJoin(repoInfo.org, "_git", repoInfo.repo),
rootUrl,
)
let filePath = relativeFilePath
Expand All @@ -359,12 +366,12 @@ export class VisualStudio extends BaseProvider {
historyUrl.search = baseSearch + "&_a=history"
}
const compareUrl = new url.URL(
path.join(repoInfo.org, "_git", repoInfo.repo, "branches"),
pathJoin(repoInfo.org, "_git", repoInfo.repo, "branches"),
rootUrl,
)
compareUrl.search = `targetVersion=${version}&_a=commits`
const prUrl = new url.URL(
path.join(repoInfo.org, "_git", repoInfo.repo, "pullrequestcreate"),
pathJoin(repoInfo.org, "_git", repoInfo.repo, "pullrequestcreate"),
rootUrl,
)
prUrl.search = `sourceRef=${head.value}`
Expand Down
26 changes: 26 additions & 0 deletions src/test/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,35 @@ import {
createSha,
createBranch,
Github,
pathJoin,
} from "../providers"
import * as assert from "assert"

suite("utils", async () => {
test("pathJoin", () => {
assert.strictEqual(
pathJoin(
"ghost",
"ghost.github.io",
"blob",
"fixit/-#123✅",
"C#/C#.Package",
),
"ghost/ghost.github.io/blob/fixit/-%23123%E2%9C%85/C%23/C%23.Package",
)
assert.strictEqual(
pathJoin(
"ghost",
"ghost.github.io",
"blob",
"chris/fix#123-✅",
"blah-#🤷🏻‍♂️.txt",
),
"ghost/ghost.github.io/blob/chris/fix%23123-%E2%9C%85/blah-%23%F0%9F%A4%B7%F0%9F%8F%BB%E2%80%8D%E2%99%82%EF%B8%8F.txt",
)
})
})

suite("Github", async () => {
test("ssh", async () => {
for (let url of [
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
resolved "https://registry.yarnpkg.com/@types/ini/-/ini-1.3.30.tgz#d1485459c9fad84e937414b832a2adb649eab379"
integrity sha512-2+iF8zPSbpU83UKE+PNd4r/MhwNAdyGpk3H+VMgEH3EhjFZq1kouLgRoZrmIcmoGX97xFvqdS44DkICR5Nz3tQ==

"@types/lodash@^4.14.168":
version "4.14.168"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==

"@types/mocha@^2.2.42":
version "2.2.48"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab"
Expand Down Expand Up @@ -336,6 +341,11 @@ js-yaml@^3.7.0:
argparse "^1.0.7"
esprima "^4.0.0"

lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

[email protected], minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
Expand Down

0 comments on commit 08bd7c5

Please sign in to comment.