Merge "Fix double encoding of + sign"
diff --git a/polygerrit-ui/app/models/views/change_test.ts b/polygerrit-ui/app/models/views/change_test.ts
index 1e71bbd..837e362 100644
--- a/polygerrit-ui/app/models/views/change_test.ts
+++ b/polygerrit-ui/app/models/views/change_test.ts
@@ -74,7 +74,7 @@
...createChangeViewState(),
repo: 'x+/y+/z+/w' as RepoName,
};
- assert.equal(createChangeUrl(state), '/c/x%2B/y%2B/z%2B/w/+/42');
+ assert.equal(createChangeUrl(state), '/c/x%252B/y%252B/z%252B/w/+/42');
});
test('createDiffUrl', () => {
@@ -85,7 +85,7 @@
};
assert.equal(
createDiffUrl(params),
- '/c/test-project/+/42/12/x%2By/path.cpp'
+ '/c/test-project/+/42/12/x%252By/path.cpp'
);
window.CANONICAL_PATH = '/base';
@@ -93,10 +93,10 @@
window.CANONICAL_PATH = undefined;
params.repo = 'test' as RepoName;
- assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%252By/path.cpp');
params.basePatchNum = 6 as BasePatchSetNum;
- assert.equal(createDiffUrl(params), '/c/test/+/42/6..12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/test/+/42/6..12/x%252By/path.cpp');
params.diffView = {
path: 'foo bar/my+file.txt%',
@@ -105,7 +105,7 @@
delete params.basePatchNum;
assert.equal(
createDiffUrl(params),
- '/c/test/+/42/2/foo+bar/my%2Bfile.txt%2525'
+ '/c/test/+/42/2/foo+bar/my%252Bfile.txt%2525'
);
params.diffView = {
@@ -129,7 +129,7 @@
repo: 'x+/y' as RepoName,
diffView: {path: 'x+y/path.cpp'},
};
- assert.equal(createDiffUrl(params), '/c/x%2B/y/+/42/12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/x%252B/y/+/42/12/x%252By/path.cpp');
});
test('createEditUrl', () => {
@@ -140,7 +140,7 @@
};
assert.equal(
createEditUrl(params),
- '/c/test-project/+/42/12/x%2By/path.cpp,edit#31'
+ '/c/test-project/+/42/12/x%252By/path.cpp,edit#31'
);
window.CANONICAL_PATH = '/base';
diff --git a/polygerrit-ui/app/utils/url-util.ts b/polygerrit-ui/app/utils/url-util.ts
index 5e294cb..af1e32e 100644
--- a/polygerrit-ui/app/utils/url-util.ts
+++ b/polygerrit-ui/app/utils/url-util.ts
@@ -92,6 +92,9 @@
// to not double encode *everything* (just for readaiblity and simplicity),
// but `%` *must* be double encoded.
let output = url.replaceAll('%', '%25');
+ // `+` also requires double encoding, because `%2B` would be decoded to `+`
+ // and then replaced by ` `.
+ output = output.replaceAll('+', '%2B');
// This escapes ALL characters EXCEPT:
// A–Z a–z 0–9 - _ . ! ~ * ' ( )
@@ -138,6 +141,10 @@
* Single decode for URL components. Will decode plus signs ('+') to spaces.
* Note: because this function decodes once, it is not the inverse of
* encodeURL.
+ *
+ * This function must only be used for decoding data returned by the REST API.
+ * Don't use it for decoding browser URLs. The only place for decoding browser
+ * URLs must gr-page.ts.
*/
export function singleDecodeURL(url: string): string {
const withoutPlus = url.replace(/\+/g, '%20');
diff --git a/polygerrit-ui/app/utils/url-util_test.ts b/polygerrit-ui/app/utils/url-util_test.ts
index 16f85dd..7466a90 100644
--- a/polygerrit-ui/app/utils/url-util_test.ts
+++ b/polygerrit-ui/app/utils/url-util_test.ts
@@ -110,6 +110,10 @@
assert.equal(encodeURL('abc%def'), 'abc%2525def');
});
+ test('double encodes +', () => {
+ assert.equal(encodeURL('abc+def'), 'abc%252Bdef');
+ });
+
test('does not encode colon and slash', () => {
assert.equal(encodeURL(':/'), ':/');
});