Skip to content

Commit

Permalink
fix: fix infinite call stack depth on multilevel sort
Browse files Browse the repository at this point in the history
  • Loading branch information
1nVitr0 committed Jul 6, 2021
1 parent 3a0fe0d commit c1f5e29
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions src/providers/BlockSortProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Range, Selection, TextDocument } from "vscode";
import ConfigurationProvider from "./ConfigurationProvider";
import StringProcessingProvider, { Folding } from "./StringProcessingProvider";
import { Range, Selection, TextDocument } from 'vscode';
import ConfigurationProvider from './ConfigurationProvider';
import StringProcessingProvider, { Folding } from './StringProcessingProvider';

type SortingStrategy = "asc" | "desc" | "ascNatural" | "descNatural";
type SortingStrategy = 'asc' | 'desc' | 'ascNatural' | 'descNatural';

export default class BlockSortProvider {
public static sort: Record<SortingStrategy, (a: string, b: string) => number> = {
Expand All @@ -15,12 +15,13 @@ export default class BlockSortProvider {
protected static padNumbers(line: string) {
const { omitUuids, padding, sortNegativeValues } = ConfigurationProvider.getNaturalSortOptions();
let result = line;
if (omitUuids) result = result.replace(/\d+(?=[^a-zA-z]|$)|(?<=[^a-zA-z]|^)\d+/g, (match) => match.padStart(padding, "0"));
else result = result.replace(/\d+/g, (match) => match.padStart(padding, "0"));
if (omitUuids)
result = result.replace(/\d+(?=[^a-zA-z]|$)|(?<=[^a-zA-z]|^)\d+/g, (match) => match.padStart(padding, '0'));
else result = result.replace(/\d+/g, (match) => match.padStart(padding, '0'));

if (sortNegativeValues) {
result = result.replace(
new RegExp(`-\\d{${padding}}`, "g"),
new RegExp(`-\\d{${padding}}`, 'g'),
(match) => `-${(Math.pow(10, padding) + parseInt(match)).toString()}`
);
}
Expand All @@ -46,20 +47,20 @@ export default class BlockSortProvider {
textBlocks = textBlocks.map((block) => this.sortBlockHeaders(block, sort));

if (this.stringProcessor.isList(blocks) && textBlocks.length && !/,$/.test(textBlocks[textBlocks.length - 1])) {
textBlocks[textBlocks.length - 1] += ",";
textBlocks[textBlocks.length - 1] += ',';
this.applySort(textBlocks, sort);
textBlocks[textBlocks.length - 1] = textBlocks[textBlocks.length - 1].replace(/,\s*$/, "");
textBlocks[textBlocks.length - 1] = textBlocks[textBlocks.length - 1].replace(/,\s*$/, '');
} else {
this.applySort(textBlocks, sort);
}

if (textBlocks.length && !textBlocks[0].trim()) {
textBlocks.push(textBlocks.shift() || "");
textBlocks.push(textBlocks.shift() || '');
} else if (textBlocks.length && /^\s*\r?\n/.test(textBlocks[0])) {
// For some reason a newline for the second block gets left behind sometimes
const front = !/\r?\n$/.test(textBlocks[0]) && textBlocks[1] && !/^\r?\n/.test(textBlocks[1]);
textBlocks[0] = textBlocks[0].replace(/^\s*\r?\n/, "");
textBlocks[front ? 0 : textBlocks.length - 1] += "\n";
textBlocks[0] = textBlocks[0].replace(/^\s*\r?\n/, '');
textBlocks[front ? 0 : textBlocks.length - 1] += '\n';
}

return textBlocks;
Expand All @@ -69,7 +70,7 @@ export default class BlockSortProvider {
const startLine = range.start.line;
const text = this.document.getText(range);
const lines = text.split(/\r?\n/);
const firstLine = lines.shift() || "";
const firstLine = lines.shift() || '';
const initialIndent = this.stringProcessor.getIndent(firstLine);
const blocks: Range[] = [];

Expand All @@ -90,7 +91,7 @@ export default class BlockSortProvider {
blocks.push(this.document.validateRange(new Range(startLine + lastStart, 0, startLine + currentEnd, Infinity)));
lastStart = currentEnd + 1;
currentEnd = lastStart;
currentBlock = "";
currentBlock = '';
validBlock = false;
} else {
currentEnd++;
Expand Down Expand Up @@ -125,7 +126,9 @@ export default class BlockSortProvider {
}

const intersection = block.intersection(new Range(block.start.line + start, 0, block.start.line + end, Infinity));
if (intersection && !intersection.isEmpty) return this.getBlocks(intersection);
const lineDiff =
block.end.line - block.start.line - (intersection ? intersection.end.line - intersection.start.line : 0);
if (intersection && !intersection.isEmpty && lineDiff) return this.getBlocks(intersection);
return [];
}

Expand Down Expand Up @@ -185,14 +188,14 @@ export default class BlockSortProvider {
if (sortChildren === 0) return this.document.getText(block);

let blocks = this.getInnerBlocks(block);
if (!blocks.length) return this.document.getText(block);
if (blocks.length < 2) return this.document.getText(block);

const head: Range = new Range(block.start, blocks[0]?.start || block.start);
const tail: Range = new Range(blocks[blocks.length - 1]?.end || block.end, block.end);

return (
this.document.getText(head) +
this.sortBlocks(blocks, sort, sortChildren - 1).join("\n") +
this.sortBlocks(blocks, sort, sortChildren - 1).join('\n') +
this.document.getText(tail)
);
}
Expand All @@ -211,7 +214,7 @@ export default class BlockSortProvider {
this.applySort(headers, sort);
lines = [...headers, ...lines];

return lines.join("\n");
return lines.join('\n');
}

private applySort(blocks: string[], sort: (a: string, b: string) => number = BlockSortProvider.sort.asc) {
Expand Down

0 comments on commit c1f5e29

Please sign in to comment.