Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions extensions/ql-vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [UNRELEASED]

- Replace certain control codes (`U+0000` - `U+001F`) with their corresponding control labels (`U+2400` - `U+241F`) in the results view. [#963](https://github.com/github/vscode-codeql/pull/963)

## 1.5.6 - 07 October 2021

- Add progress messages to LGTM download option. This makes the two-step process (selecting a project, then selecting a language) more clear. [#960](https://github.com/github/vscode-codeql/pull/960)
Expand Down
12 changes: 6 additions & 6 deletions extensions/ql-vscode/src/view/RawTableValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ interface Props {
}

export default function RawTableValue(props: Props): JSX.Element {
const v = props.value;
const rawValue = props.value;
if (
typeof v === 'string'
|| typeof v === 'number'
|| typeof v === 'boolean'
typeof rawValue === 'string'
|| typeof rawValue === 'number'
|| typeof rawValue === 'boolean'
) {
return <span>{v.toString()}</span>;
return <span>{renderLocation(undefined, rawValue.toString())}</span>;
}

return renderLocation(v.url, v.label, props.databaseUri);
return renderLocation(rawValue.url, rawValue.label, props.databaseUri);
}
43 changes: 32 additions & 11 deletions extensions/ql-vscode/src/view/result-table-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export const oddRowClassName = 'vscode-codeql__result-table-row--odd';
export const pathRowClassName = 'vscode-codeql__result-table-row--path';
export const selectedRowClassName = 'vscode-codeql__result-table-row--selected';

const CONTROL_CODE = '\u001F'.codePointAt(0)!;
const CONTROL_LABEL = '\u2400'.codePointAt(0)!;

export function jumpToLocationHandler(
loc: ResolvableLocationValue,
databaseUri: string,
Expand Down Expand Up @@ -67,24 +70,42 @@ export function openFile(filePath: string): void {
});
}

function convertedNonprintableChars(label: string) {
// If the label was empty, use a placeholder instead, so the link is still clickable.
if (!label) {
return '[empty string]';
} else if (label.match(/^\s+$/)) {
return `[whitespace: "${label}"]`;
} else {
/**
* If the label contains certain non-printable characters, loop through each
* character and replace it with the cooresponding unicode control label.
*/
const convertedLabelArray: any[] = [];
for (let i = 0; i < label.length; i++) {
const labelCheck = label.codePointAt(i)!;
if (labelCheck <= CONTROL_CODE) {
convertedLabelArray[i] = String.fromCodePoint(labelCheck + CONTROL_LABEL);
} else {
convertedLabelArray[i] = label.charAt(i);
}
}
return convertedLabelArray.join('');
}
}

/**
* Render a location as a link which when clicked displays the original location.
*/
export function renderLocation(
loc: UrlValue | undefined,
label: string | undefined,
databaseUri: string,
loc?: UrlValue,
label?: string,
databaseUri?: string,
title?: string,
callback?: () => void
): JSX.Element {

// If the label was empty, use a placeholder instead, so the link is still clickable.
let displayLabel = label;
if (!label) {
displayLabel = '[empty string]';
} else if (label.match(/^\s+$/)) {
displayLabel = `[whitespace: "${label}"]`;
}
const displayLabel = convertedNonprintableChars(label!);

if (loc === undefined) {
return <span>{displayLabel}</span>;
Expand All @@ -93,7 +114,7 @@ export function renderLocation(
}

const resolvableLoc = tryGetResolvableLocation(loc);
if (resolvableLoc !== undefined) {
if (databaseUri !== undefined && resolvableLoc !== undefined) {
return (
<a href="#"
className="vscode-codeql__result-table-location-link"
Expand Down