Fix archive encoding when there is an empty uri authority

This commit fixes a bug uncovered by
c66fe07b06.

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.
This commit is contained in:
Andrew Eisenberg
2020-10-20 14:04:53 -07:00
parent 542bb85490
commit 5b6371fb94
3 changed files with 49 additions and 10 deletions

View File

@@ -100,6 +100,14 @@ class InvalidSourceArchiveUriError extends Error {
/** Decodes an encoded source archive URI into its corresponding paths. Inverse of `encodeSourceArchiveUri`. */
export function decodeSourceArchiveUri(uri: vscode.Uri): ZipFileReference {
if (!uri.authority) {
// Uri is malformed, but this is recoverable
logger.log(`Warning: ${new InvalidSourceArchiveUriError(uri).message}`);
return {
pathWithinSourceArchive: '',
sourceArchiveZipPath: uri.path
};
}
const match = sourceArchiveUriAuthorityPattern.exec(uri.authority);
if (match === null)
throw new InvalidSourceArchiveUriError(uri);

View File

@@ -121,13 +121,18 @@ async function findSourceArchive(
if (await fs.pathExists(basePath)) {
return vscode.Uri.file(basePath);
}
else if (await fs.pathExists(zipPath)) {
return vscode.Uri.file(zipPath).with({ scheme: zipArchiveScheme });
} else if (await fs.pathExists(zipPath)) {
return encodeSourceArchiveUri({
pathWithinSourceArchive: '',
sourceArchiveZipPath: zipPath
});
}
}
if (!silent)
showAndLogInformationMessage(`Could not find source archive for database '${databasePath}'. Assuming paths are absolute.`);
if (!silent) {
showAndLogInformationMessage(
`Could not find source archive for database '${databasePath}'. Assuming paths are absolute.`
);
}
return undefined;
}

View File

@@ -1,8 +1,8 @@
import { expect } from 'chai';
import * as path from 'path';
import { encodeSourceArchiveUri, ArchiveFileSystemProvider, decodeSourceArchiveUri, ZipFileReference } from '../../archive-filesystem-provider';
import { FileType, FileSystemError } from 'vscode';
import { encodeSourceArchiveUri, ArchiveFileSystemProvider, decodeSourceArchiveUri, ZipFileReference, zipArchiveScheme } from '../../archive-filesystem-provider';
import { FileType, FileSystemError, Uri } from 'vscode';
describe('archive-filesystem-provider', () => {
it('reads empty file correctly', async () => {
@@ -112,15 +112,31 @@ describe('source archive uri encoding', function() {
const testCases: { name: string; input: ZipFileReference }[] = [
{
name: 'mixed case and unicode',
input: { sourceArchiveZipPath: '/I-\u2665-codeql.zip', pathWithinSourceArchive: '/foo/bar' }
input: {
sourceArchiveZipPath: '/I-\u2665-codeql.zip',
pathWithinSourceArchive: '/foo/bar'
}
},
{
name: 'Windows path',
input: { sourceArchiveZipPath: 'C:/Users/My Name/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
input: {
sourceArchiveZipPath: 'C:/Users/My Name/folder/src.zip',
pathWithinSourceArchive: '/foo/bar.ext'
}
},
{
name: 'Unix path',
input: { sourceArchiveZipPath: '/home/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
input: {
sourceArchiveZipPath: '/home/folder/src.zip',
pathWithinSourceArchive: '/foo/bar.ext'
}
},
{
name: 'Empty path',
input: {
sourceArchiveZipPath: '/home/folder/src.zip',
pathWithinSourceArchive: ''
}
}
];
for (const testCase of testCases) {
@@ -129,4 +145,14 @@ describe('source archive uri encoding', function() {
expect(output).to.eql(testCase.input);
});
}
it('should handle malformed uri with no authority', () => {
// This handles codeql-zip-archive uris generated using the `with` method
const uri = Uri.parse('file:/a/b/c/src.zip').with({ scheme: zipArchiveScheme });
expect(uri.authority).to.eq('');
expect(decodeSourceArchiveUri(uri)).to.deep.eq({
sourceArchiveZipPath: '/a/b/c/src.zip',
pathWithinSourceArchive: ''
});
});
});