Skip to content

Commit 2535c6c

Browse files
authored
Merge branch 'main' into fix-201081
2 parents d022a7b + 5ce6349 commit 2535c6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+579
-293
lines changed

extensions/git/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2961,8 +2961,10 @@
29612961
"configurationDefaults": {
29622962
"[git-commit]": {
29632963
"editor.rulers": [
2964+
50,
29642965
72
29652966
],
2967+
"editor.wordWrap": "off",
29662968
"workbench.editor.restoreViewState": false
29672969
},
29682970
"[git-rebase]": {

extensions/git/src/git.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2543,7 +2543,7 @@ export class Repository {
25432543
return branch;
25442544
}
25452545

2546-
return Promise.reject<Branch>(new Error('No such branch'));
2546+
return Promise.reject<Branch>(new Error(`No such branch: ${name}`));
25472547
}
25482548

25492549
async getDefaultBranch(): Promise<Branch> {

extensions/xml/xml.language-configuration.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
{ "open": "(", "close": ")" },
1515
{ "open": "\"", "close": "\"", "notIn": ["string"] },
1616
{ "open": "'", "close": "'", "notIn": ["string"] },
17-
{ "open": "<!--", "close": "-->", "notIn": [ "comment", "string" ]},
18-
{ "open": "<![CDATA[", "close": "]]>", "notIn": [ "comment", "string" ]}
17+
{ "open": "<!--", "close": "-->", "notIn": [ "comment", "string" ]}
1918
],
2019
"surroundingPairs": [
2120
{ "open": "'", "close": "'" },

src/vs/base/common/labels.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,17 @@ export function unmnemonicLabel(label: string): string {
436436
}
437437

438438
/**
439-
* Splits a recent label in name and parent path, supporting both '/' and '\' and workspace suffixes
439+
* Splits a recent label in name and parent path, supporting both '/' and '\' and workspace suffixes.
440+
* If the location is remote, the remote name is included in the name part.
440441
*/
441-
export function splitRecentLabel(recentLabel: string) {
442+
export function splitRecentLabel(recentLabel: string): { name: string; parentPath: string } {
442443
if (recentLabel.endsWith(']')) {
443444
// label with workspace suffix
444445
const lastIndexOfSquareBracket = recentLabel.lastIndexOf(' [', recentLabel.length - 2);
445446
if (lastIndexOfSquareBracket !== -1) {
446447
const split = splitName(recentLabel.substring(0, lastIndexOfSquareBracket));
447-
return { name: split.name, parentPath: split.parentPath + recentLabel.substring(lastIndexOfSquareBracket) };
448+
const remoteNameWithSpace = recentLabel.substring(lastIndexOfSquareBracket);
449+
return { name: split.name + remoteNameWithSpace, parentPath: split.parentPath };
448450
}
449451
}
450452
return splitName(recentLabel);

src/vs/base/common/strings.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,25 @@ export function format2(template: string, values: Record<string, unknown>): stri
4848
return template.replace(_format2Regexp, (match, group) => (values[group] ?? match) as string);
4949
}
5050

51+
/**
52+
* Encodes the given value so that it can be used as literal value in html attributes.
53+
*
54+
* In other words, computes `$val`, such that `attr` in `<div attr="$val" />` has the runtime value `value`.
55+
* This prevents XSS injection.
56+
*/
57+
export function htmlAttributeEncodeValue(value: string): string {
58+
return value.replace(/[<>"'&]/g, ch => {
59+
switch (ch) {
60+
case '<': return '&lt;';
61+
case '>': return '&gt;';
62+
case '"': return '&quot;';
63+
case '\'': return '&apos;';
64+
case '&': return '&amp;';
65+
}
66+
return ch;
67+
});
68+
}
69+
5170
/**
5271
* Converts HTML characters inside the string to use entities instead. Makes the string safe from
5372
* being used e.g. in HTMLElement.innerHTML.

src/vs/base/test/common/strings.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,3 +532,13 @@ suite('Strings', () => {
532532

533533
ensureNoDisposablesAreLeakedInTestSuite();
534534
});
535+
536+
test('htmlAttributeEncodeValue', () => {
537+
assert.strictEqual(strings.htmlAttributeEncodeValue(''), '');
538+
assert.strictEqual(strings.htmlAttributeEncodeValue('abc'), 'abc');
539+
assert.strictEqual(strings.htmlAttributeEncodeValue('<script>alert("Hello")</script>'), '&lt;script&gt;alert(&quot;Hello&quot;)&lt;/script&gt;');
540+
assert.strictEqual(strings.htmlAttributeEncodeValue('Hello & World'), 'Hello &amp; World');
541+
assert.strictEqual(strings.htmlAttributeEncodeValue('"Hello"'), '&quot;Hello&quot;');
542+
assert.strictEqual(strings.htmlAttributeEncodeValue('\'Hello\''), '&apos;Hello&apos;');
543+
assert.strictEqual(strings.htmlAttributeEncodeValue('<>&\'"'), '&lt;&gt;&amp;&apos;&quot;');
544+
});

src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ import { ViewContext } from 'vs/editor/common/viewModel/viewContext';
2020
* This can end up producing multiple `LineDecorationToRender`.
2121
*/
2222
export class DecorationToRender {
23-
_decorationToRenderBrand: void = undefined;
23+
public readonly _decorationToRenderBrand: void = undefined;
2424

25-
public startLineNumber: number;
26-
public endLineNumber: number;
27-
public className: string;
2825
public readonly zIndex: number;
2926

30-
constructor(startLineNumber: number, endLineNumber: number, className: string, zIndex: number | undefined) {
31-
this.startLineNumber = +startLineNumber;
32-
this.endLineNumber = +endLineNumber;
33-
this.className = String(className);
27+
constructor(
28+
public readonly startLineNumber: number,
29+
public readonly endLineNumber: number,
30+
public readonly className: string,
31+
public readonly tooltip: string | null,
32+
zIndex: number | undefined,
33+
) {
3434
this.zIndex = zIndex ?? 0;
3535
}
3636
}
@@ -42,6 +42,7 @@ export class LineDecorationToRender {
4242
constructor(
4343
public readonly className: string,
4444
public readonly zIndex: number,
45+
public readonly tooltip: string | null,
4546
) { }
4647
}
4748

@@ -108,7 +109,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay {
108109
}
109110

110111
for (let i = startLineIndex; i <= prevEndLineIndex; i++) {
111-
output[i].add(new LineDecorationToRender(className, zIndex));
112+
output[i].add(new LineDecorationToRender(className, zIndex, d.tooltip));
112113
}
113114
}
114115

src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ export class LinesDecorationsOverlay extends DedupOverlay {
7878
const linesDecorationsClassName = d.options.linesDecorationsClassName;
7979
const zIndex = d.options.zIndex;
8080
if (linesDecorationsClassName) {
81-
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, linesDecorationsClassName, zIndex);
81+
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, linesDecorationsClassName, d.options.linesDecorationsTooltip ?? null, zIndex);
8282
}
8383
const firstLineDecorationClassName = d.options.firstLineDecorationClassName;
8484
if (firstLineDecorationClassName) {
85-
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.startLineNumber, firstLineDecorationClassName, zIndex);
85+
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.startLineNumber, firstLineDecorationClassName, d.options.linesDecorationsTooltip ?? null, zIndex);
8686
}
8787
}
8888
return r;
@@ -103,7 +103,12 @@ export class LinesDecorationsOverlay extends DedupOverlay {
103103
const decorations = toRender[lineIndex].getDecorations();
104104
let lineOutput = '';
105105
for (const decoration of decorations) {
106-
lineOutput += '<div class="cldr ' + decoration.className + common;
106+
let addition = '<div class="cldr ' + decoration.className;
107+
if (decoration.tooltip !== null) {
108+
addition += '" title="' + decoration.tooltip; // The tooltip is already escaped.
109+
}
110+
addition += common;
111+
lineOutput += addition;
107112
}
108113
output[lineIndex] = lineOutput;
109114
}

src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class MarginViewLineDecorationsOverlay extends DedupOverlay {
6464
const marginClassName = d.options.marginClassName;
6565
const zIndex = d.options.zIndex;
6666
if (marginClassName) {
67-
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, marginClassName, zIndex);
67+
r[rLen++] = new DecorationToRender(d.range.startLineNumber, d.range.endLineNumber, marginClassName, null, zIndex);
6868
}
6969
}
7070
return r;

src/vs/editor/common/languages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ export interface CommentReaction {
17781778
readonly count?: number;
17791779
readonly hasReacted?: boolean;
17801780
readonly canEdit?: boolean;
1781+
readonly reactors?: readonly string[];
17811782
}
17821783

17831784
/**

0 commit comments

Comments
 (0)