From 8429d9e4211d75954db211ac50e4d998ff4658c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sat, 10 Oct 2026 00:12:31 -0400 Subject: [PATCH] ElyPDF worker: kept links are counted as they are kept (P-12) --- crates/ely-pdf-engine/shim/ely_insert.c | 23 ++++++++++++----------- tasks/BUGS.md | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/crates/ely-pdf-engine/shim/ely_insert.c b/crates/ely-pdf-engine/shim/ely_insert.c index 77dc1e9..e1bd6af 100644 --- a/crates/ely-pdf-engine/shim/ely_insert.c +++ b/crates/ely-pdf-engine/shim/ely_insert.c @@ -13,10 +13,10 @@ typedef struct int page; } inner_link; -/* Takes page references off the source's annotations, links noted. */ -static int unhook(fz_context *ctx, pdf_document *src, inner_link *links, int room) +/* Takes page references off; links noted, `*n` counted as kept. */ +static void unhook(fz_context *ctx, pdf_document *src, inner_link *links, int room, int *n) { - int i, j, n = 0, count = pdf_count_pages(ctx, src); + int i, j, count = pdf_count_pages(ctx, src); for (i = 0; i < count; i++) { pdf_obj *annots = pdf_dict_get(ctx, pdf_lookup_page_obj(ctx, src, i), PDF_NAME(Annots)); @@ -26,7 +26,7 @@ static int unhook(fz_context *ctx, pdf_document *src, inner_link *links, int roo pdf_obj *page = ely_target(ctx, src, annot); int to = page ? pdf_lookup_page_number(ctx, src, page) : -1; pdf_dict_del(ctx, annot, PDF_NAME(P)); - if (to < 0 || n == room) + if (to < 0 || *n == room) continue; /* The view after the page: /XYZ, /Fit and so on. */ pdf_obj *dest = pdf_dict_get(ctx, annot, PDF_NAME(Dest)); @@ -36,16 +36,17 @@ static int unhook(fz_context *ctx, pdf_document *src, inner_link *links, int roo dest = pdf_lookup_dest(ctx, src, dest); if (pdf_is_dict(ctx, dest)) dest = pdf_dict_get(ctx, dest, PDF_NAME(D)); - links[n].annot = pdf_keep_obj(ctx, annot); - links[n].rest = pdf_copy_array(ctx, dest); - pdf_array_delete(ctx, links[n].rest, 0); - links[n].page = to; - n++; + /* Counted as soon as kept: a throw still frees it. */ + links[*n].annot = pdf_keep_obj(ctx, annot); + links[*n].rest = NULL; + links[*n].page = to; + (*n)++; + links[*n - 1].rest = pdf_copy_array(ctx, dest); + pdf_array_delete(ctx, links[*n - 1].rest, 0); pdf_dict_del(ctx, annot, PDF_NAME(Dest)); pdf_dict_del(ctx, annot, PDF_NAME(A)); } } - return n; } /* The top of the field tree `widget` belongs to. */ @@ -338,7 +339,7 @@ int ely_insert_file(fz_context *ctx, fz_document *doc, int at, const char *path, for (i = 0; i < *count; i++) room += pdf_array_len(ctx, pdf_dict_get(ctx, pdf_lookup_page_obj(ctx, src, i), PDF_NAME(Annots))); links = fz_calloc(ctx, room + 1, sizeof *links); - n = unhook(ctx, src, links, room); + unhook(ctx, src, links, room, &n); map = pdf_new_graft_map(ctx, pdf); pdf_begin_operation(ctx, pdf, "Insert pages"); begun = 1; diff --git a/tasks/BUGS.md b/tasks/BUGS.md index 50d45e2..0c40805 100644 --- a/tasks/BUGS.md +++ b/tasks/BUGS.md @@ -44,7 +44,7 @@ - [x] P-09 识别文字的写入被拒后仍弹“成功” — on_same 回报是否执行;被拒时只有警告 - [x] P-10 预览回复被丢弃时“应用”静默无事 — 预览回复照常交回,版本已变即提示,不显示过期预览 - [x] P-11 撤销或重做在 MuPDF 侧失败后 worker 的步数不再同步 — 撤销失败后重读历史标记 -- [ ] P-12 `unhook` 中途抛出时泄漏保留的对象 +- [x] P-12 `unhook` 中途抛出时泄漏保留的对象 — 保留的链接随保留随计数 - [ ] P-13 优化导出的“之前”大小取磁盘文件而非当前文档 - [ ] P-14 文字块含控制字符时 JSON 回复不可解析 - [x] D-01 导出或打印对话框开着时关闭其标签即崩溃 — Docs 实现 tab_closed,关标签即撤下其导出对话框;R1 PASS