mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-23 23:10:17 +05:30
fix(pdf): guard pdfSplit against non-positive interval infinite loop
The interval split mode looped for (i = 0; i < totalPages; i += interval), which spins forever when interval <= 0. Both the single-file dialog and the batch dialog can reach it (the batch dialog's validateOperationData only checks truthiness, so -1 passes). Guard at the source in the main process: reject non-positive or non-integer intervals before the loop, protecting both paths and any future caller. Amit Haridas
This commit is contained in:
@@ -112,6 +112,9 @@ async function pdfSplit(data) {
|
|||||||
}
|
}
|
||||||
} else if (data.splitMode === 'interval') {
|
} else if (data.splitMode === 'interval') {
|
||||||
const interval = data.interval;
|
const interval = data.interval;
|
||||||
|
if (!Number.isInteger(interval) || interval <= 0) {
|
||||||
|
return { success: false, message: 'Split interval must be a positive integer.' };
|
||||||
|
}
|
||||||
for (let i = 0; i < totalPages; i += interval) {
|
for (let i = 0; i < totalPages; i += interval) {
|
||||||
const pages = [];
|
const pages = [];
|
||||||
for (let j = i; j < i + interval && j < totalPages; j++) {
|
for (let j = i; j < i + interval && j < totalPages; j++) {
|
||||||
|
|||||||
@@ -492,3 +492,54 @@ describe('PDFOperations - Task 27 honest encryption failure', () => {
|
|||||||
expect(rotated.getPageCount()).toBe(1);
|
expect(rotated.getPageCount()).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('PDFOperations - pdfSplit interval guard', () => {
|
||||||
|
let tmpDir, inputPath, outputFolder;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pdfops_split_'));
|
||||||
|
inputPath = path.join(tmpDir, 'in.pdf');
|
||||||
|
outputFolder = path.join(tmpDir, 'out');
|
||||||
|
fs.mkdirSync(outputFolder);
|
||||||
|
|
||||||
|
const doc = await PDFDocument.create();
|
||||||
|
doc.addPage([600, 800]);
|
||||||
|
doc.addPage([600, 800]);
|
||||||
|
fs.writeFileSync(inputPath, await doc.save());
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
// A non-positive (or non-integer) interval previously made the split loop
|
||||||
|
// spin forever (i += 0 never advances the counter), so Jest's per-test
|
||||||
|
// timeout is the hang detector for these cases.
|
||||||
|
it.each([0, -1, 1.5])(
|
||||||
|
'rejects interval %s without writing any output files',
|
||||||
|
async (interval) => {
|
||||||
|
const result = await PDFOperations.pdfSplit({
|
||||||
|
inputPath,
|
||||||
|
outputFolder,
|
||||||
|
splitMode: 'interval',
|
||||||
|
interval,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.message).toBe('Split interval must be a positive integer.');
|
||||||
|
expect(fs.readdirSync(outputFolder)).toEqual([]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('still splits every N pages for a valid positive interval', async () => {
|
||||||
|
const result = await PDFOperations.pdfSplit({
|
||||||
|
inputPath,
|
||||||
|
outputFolder,
|
||||||
|
splitMode: 'interval',
|
||||||
|
interval: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(fs.readdirSync(outputFolder).sort()).toEqual(['in_part_1.pdf', 'in_part_2.pdf']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user