fix: truncate article titles to safe UTF-8 budget
This commit is contained in:
7 files changed
+115
-15
No files matched your search
+37
-2
@@ -29,12 +29,11 @@ test('测试文章:标题、3 张配图、插入顺序、来源与段落完整
|
||||
assert.equal(output, originalBody);
|
||||
});
|
||||
|
||||
test('缺图、远程图片、超出目录、超大图片与超长标题在上传前被拒绝', () => {
|
||||
test('缺图、远程图片、超出目录与超大图片在上传前被拒绝', () => {
|
||||
assert.throws(() => core.compile('# 标题\n\n', 'a.md', new Map()), /找不到配图/);
|
||||
assert.throws(() => core.compile('# 标题\n\n', 'a.md', new Map()), /目录内/);
|
||||
assert.throws(() => core.imagePath('a.md', '../secret.jpg'), /超出/);
|
||||
assert.throws(() => core.imagePath('a.md', '%2fetc/passwd'), /相对路径/);
|
||||
assert.throws(() => core.compile('# ' + '长'.repeat(81) + '\n正文', 'a.md', new Map()), /80/);
|
||||
assert.throws(() => core.compile('# 标题\n\n', 'a.md', new Map([['big.png', {size:20*1024*1024}]])), /20 MB/);
|
||||
});
|
||||
|
||||
@@ -209,3 +208,39 @@ test('正文图片尚在加载时等待 load;终止后释放等待', async ()
|
||||
const cancelled=core.verifyEditorImages({querySelectorAll:()=>[pending]},['8'],controller.signal);
|
||||
controller.abort();await assert.rejects(cancelled,/终止/);assert.equal(pending.events.size,0);
|
||||
});
|
||||
|
||||
|
||||
test('标题按 UTF-8 预算截断,目录和文章包保持一致且重复处理稳定', async () => {
|
||||
const cases = [
|
||||
['A'.repeat(75), 'A'.repeat(75)],
|
||||
['A'.repeat(76), 'A'.repeat(75) + '...'],
|
||||
['中'.repeat(25), '中'.repeat(25)],
|
||||
['中'.repeat(26), '中'.repeat(25) + '...'],
|
||||
['A中,'.repeat(12), 'A中,'.repeat(10) + 'A中...'],
|
||||
['😀'.repeat(20), '😀'.repeat(18) + '...'],
|
||||
];
|
||||
for (const [title, expected] of cases) {
|
||||
assert.equal(core.shortTitle(title), expected);
|
||||
assert.equal(core.shortTitle(expected), expected);
|
||||
assert.ok(Buffer.byteLength(expected) <= 78);
|
||||
const markdown = '# ' + title + '\n正文';
|
||||
const direct = core.compile(markdown, 'a.md', new Map());
|
||||
const packaged = await core.preparePackage({schemaVersion:1, markdown, title, images:[]});
|
||||
assert.equal(direct.title, expected);
|
||||
assert.equal(packaged.title, expected);
|
||||
const python = execFileSync('python3', ['-c', 'import sys; from articles import short_title; print(short_title(sys.argv[1]), end="")', title], {cwd:path.join(__dirname, '..'), encoding:'utf8'});
|
||||
assert.equal(python, expected);
|
||||
}
|
||||
});
|
||||
|
||||
test('长标题预览、实际填写和返回结果一致', async () => {
|
||||
const h = harness();
|
||||
const title = '新闻,'.repeat(20);
|
||||
await h.api.stagePackage({schemaVersion:1, markdown:'# ' + title + '\n正文', images:[]});
|
||||
const expected = '新闻,'.repeat(8) + '新...';
|
||||
assert.equal(h.api.getState().title, expected);
|
||||
const result = await h.api.importPrepared();
|
||||
assert.equal(h.ids.get('subject').value, expected);
|
||||
assert.equal(result.title, expected);
|
||||
assert.equal(h.requests.length, 0);
|
||||
});
|
||||
Reference in new issue
Block a user