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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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: ''
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user