fix: prevent romaji conversion stack overflow on long task names

This commit is contained in:
nrslib 2026-02-20 12:43:40 +09:00
parent 67f6fc685c
commit 291e05a24d
2 changed files with 43 additions and 12 deletions

View File

@ -248,6 +248,16 @@ describe('summarizeTaskName', () => {
expect(result).not.toMatch(/^-|-$/); // No leading/trailing hyphens
});
it('should handle very long names in romanization mode without stack overflow', async () => {
const result = await summarizeTaskName('a'.repeat(12000), {
cwd: '/project',
useLLM: false,
});
expect(result).toBe('a'.repeat(30));
expect(mockProviderCall).not.toHaveBeenCalled();
});
it('should use romaji by default', async () => {
// Given: branchNameStrategy is not set (undefined)
mockResolveConfigValues.mockReturnValue({

View File

@ -14,12 +14,33 @@ import type { SummarizeOptions } from './types.js';
export type { SummarizeOptions };
const log = createLogger('summarize');
const MAX_ROMAJI_CHUNK_SIZE = 1024;
function toRomajiSafely(text: string): string {
const romajiOptions = { customRomajiMapping: {} };
try {
if (text.length <= MAX_ROMAJI_CHUNK_SIZE) {
return wanakana.toRomaji(text, romajiOptions);
}
const convertedChunks: string[] = [];
for (let i = 0; i < text.length; i += MAX_ROMAJI_CHUNK_SIZE) {
convertedChunks.push(
wanakana.toRomaji(text.slice(i, i + MAX_ROMAJI_CHUNK_SIZE), romajiOptions),
);
}
return convertedChunks.join('');
} catch {
// Avoid blocking branch/task creation on rare parser edge cases or deep recursion
// with very long mixed/ASCII inputs.
return text;
}
}
/**
* Convert Japanese text to romaji slug.
*/
function toRomajiSlug(text: string): string {
const romaji = wanakana.toRomaji(text, { customRomajiMapping: {} });
const romaji = toRomajiSafely(text);
return slugify(romaji);
}