Skip to content

Add an extra percent encoding layer when encoding DocumentURIs to LSP requests #1636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 21, 2024

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Aug 19, 2024

The URI standard RFC 3986 is ambiguous about whether percent encoding and their represented characters are considered equivalent. VS Code considers them equivalent and treats them the same:

vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString() -> 'x://a?b%3Dxxxx%3Dyyyy'
vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString(/*skipEncoding=*/true) -> 'x://a?b=xxxx=yyyy'

This causes issues because SourceKit-LSP's macro expansion URLs encoded by URLComponents use = do denote the separation of a key and a value in the outer query. The value of the parent key may itself contain query items, which use the escaped form '%3D'. Simplified, such a URL may look like scheme://host?parent=scheme://host?line%3D2.

But after running this through VS Code's URI type = and %3D get canonicalized and are indistinguishable.

To avoid this ambiguity, always percent escape the characters we use to distinguish URL query parameters, producing the following URL: scheme://host?parent%3Dscheme://host%3Fline%253D2.


EDIT: This should be a temporary fix. After some URI spec reading, I’ve concluded that the URI decoding in VS Code is incorrect (swiftlang/vscode-swift#1017 (review) and swiftlang/vscode-swift#1017 (comment)).

I would like to merge this PR for now to enable semantic functionality in nested macro expansions for @lokesh-tr’s GSoC project and the investigate a proper fix for URI de/encoding on the VS Code side after which we can revert this workaround.

@ahoppen
Copy link
Member Author

ahoppen commented Aug 19, 2024

@swift-ci Please test

@lokesh-tr
Copy link
Contributor

@ahoppen Thanks for this fix, I will test this out and give you an update.

@lokesh-tr
Copy link
Contributor

@ahoppen This PR in combination with my semantic functionality PR fixes the issue and also makes semantic functionality to work as expected without needing any change in vscode-swift extension repo.

🎉

Thank you so much for fixing this

… requests

The URI standard RFC 3986 is ambiguous about whether percent encoding and their represented characters are considered equivalent. VS Code considers them equivalent and treats them the same:

```js
vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString() -> 'x://a?b%3Dxxxx%3Dyyyy'
vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString(/*skipEncoding=*/true) -> 'x://a?b=xxxx=yyyy'
```

This causes issues because SourceKit-LSP's macro expansion URLs encoded by URLComponents use `=` do denote the separation of a key and a value in the outer query. The value of the `parent` key may itself contain query items, which use the escaped form '%3D'. Simplified, such a URL may look like `scheme://host?parent=scheme://host?line%3D2`.

But after running this through VS Code's URI type `=` and `%3D` get canonicalized and are indistinguishable.

To avoid this ambiguity, always percent escape the characters we use to distinguish URL query parameters, producing the following URL: `scheme://host?parent%3Dscheme://host%3Fline%253D2`.
@ahoppen ahoppen force-pushed the more-percent-encoding branch from b96f8e9 to b2c17c7 Compare August 20, 2024 04:41
@ahoppen
Copy link
Member Author

ahoppen commented Aug 20, 2024

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented Aug 20, 2024

@swift-ci Please test Windows

@ahoppen ahoppen merged commit 3cc1cbc into swiftlang:main Aug 21, 2024
3 checks passed
@ahoppen ahoppen deleted the more-percent-encoding branch August 21, 2024 15:06
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