Skip to content

Commit 5b6371f

Browse files
committed
Fix archive encoding when there is an empty uri authority
This commit fixes a bug uncovered by c66fe07. The findSourceArchive function in databases.ts creates a codeql-zip-archive uri with an empty authority component. This will fail to decode. Until recently, this situation never happened. But in the commit linked above, we start decoding some of these incorrectly encoded uris. This commit fixes that issue.
1 parent 542bb85 commit 5b6371f

File tree

3 files changed

+49
-10
lines changed

3 files changed

+49
-10
lines changed

extensions/ql-vscode/src/archive-filesystem-provider.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ class InvalidSourceArchiveUriError extends Error {
100100

101101
/** Decodes an encoded source archive URI into its corresponding paths. Inverse of `encodeSourceArchiveUri`. */
102102
export function decodeSourceArchiveUri(uri: vscode.Uri): ZipFileReference {
103+
if (!uri.authority) {
104+
// Uri is malformed, but this is recoverable
105+
logger.log(`Warning: ${new InvalidSourceArchiveUriError(uri).message}`);
106+
return {
107+
pathWithinSourceArchive: '',
108+
sourceArchiveZipPath: uri.path
109+
};
110+
}
103111
const match = sourceArchiveUriAuthorityPattern.exec(uri.authority);
104112
if (match === null)
105113
throw new InvalidSourceArchiveUriError(uri);

extensions/ql-vscode/src/databases.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,18 @@ async function findSourceArchive(
121121

122122
if (await fs.pathExists(basePath)) {
123123
return vscode.Uri.file(basePath);
124+
} else if (await fs.pathExists(zipPath)) {
125+
return encodeSourceArchiveUri({
126+
pathWithinSourceArchive: '',
127+
sourceArchiveZipPath: zipPath
128+
});
124129
}
125-
else if (await fs.pathExists(zipPath)) {
126-
return vscode.Uri.file(zipPath).with({ scheme: zipArchiveScheme });
127-
}
128130
}
129-
if (!silent)
130-
showAndLogInformationMessage(`Could not find source archive for database '${databasePath}'. Assuming paths are absolute.`);
131+
if (!silent) {
132+
showAndLogInformationMessage(
133+
`Could not find source archive for database '${databasePath}'. Assuming paths are absolute.`
134+
);
135+
}
131136
return undefined;
132137
}
133138

extensions/ql-vscode/src/vscode-tests/no-workspace/archive-filesystem-provider.test.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { expect } from 'chai';
22
import * as path from 'path';
33

4-
import { encodeSourceArchiveUri, ArchiveFileSystemProvider, decodeSourceArchiveUri, ZipFileReference } from '../../archive-filesystem-provider';
5-
import { FileType, FileSystemError } from 'vscode';
4+
import { encodeSourceArchiveUri, ArchiveFileSystemProvider, decodeSourceArchiveUri, ZipFileReference, zipArchiveScheme } from '../../archive-filesystem-provider';
5+
import { FileType, FileSystemError, Uri } from 'vscode';
66

77
describe('archive-filesystem-provider', () => {
88
it('reads empty file correctly', async () => {
@@ -112,15 +112,31 @@ describe('source archive uri encoding', function() {
112112
const testCases: { name: string; input: ZipFileReference }[] = [
113113
{
114114
name: 'mixed case and unicode',
115-
input: { sourceArchiveZipPath: '/I-\u2665-codeql.zip', pathWithinSourceArchive: '/foo/bar' }
115+
input: {
116+
sourceArchiveZipPath: '/I-\u2665-codeql.zip',
117+
pathWithinSourceArchive: '/foo/bar'
118+
}
116119
},
117120
{
118121
name: 'Windows path',
119-
input: { sourceArchiveZipPath: 'C:/Users/My Name/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
122+
input: {
123+
sourceArchiveZipPath: 'C:/Users/My Name/folder/src.zip',
124+
pathWithinSourceArchive: '/foo/bar.ext'
125+
}
120126
},
121127
{
122128
name: 'Unix path',
123-
input: { sourceArchiveZipPath: '/home/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
129+
input: {
130+
sourceArchiveZipPath: '/home/folder/src.zip',
131+
pathWithinSourceArchive: '/foo/bar.ext'
132+
}
133+
},
134+
{
135+
name: 'Empty path',
136+
input: {
137+
sourceArchiveZipPath: '/home/folder/src.zip',
138+
pathWithinSourceArchive: ''
139+
}
124140
}
125141
];
126142
for (const testCase of testCases) {
@@ -129,4 +145,14 @@ describe('source archive uri encoding', function() {
129145
expect(output).to.eql(testCase.input);
130146
});
131147
}
148+
149+
it('should handle malformed uri with no authority', () => {
150+
// This handles codeql-zip-archive uris generated using the `with` method
151+
const uri = Uri.parse('file:/a/b/c/src.zip').with({ scheme: zipArchiveScheme });
152+
expect(uri.authority).to.eq('');
153+
expect(decodeSourceArchiveUri(uri)).to.deep.eq({
154+
sourceArchiveZipPath: '/a/b/c/src.zip',
155+
pathWithinSourceArchive: ''
156+
});
157+
});
132158
});

0 commit comments

Comments
 (0)