`PdfSmartCopy` can take effectively unbounded time on nested shared Form XObjects
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- java
- Lĩnh vực
- backend, performance
Hướng nghiên cứu
Start in PdfSmartCopy.ByteStore, which the issue identifies as recursively traversing shared indirect objects during deduplication. Use the provided createPdfWithNestedFormXObjects example to reproduce the slowdown, then compare processing with PdfCopy. Done when PdfSmartCopy handles the shared nested Form XObjects without the reported excessive time and memory use.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Describe the bug
Using PdfSmartCopy to process a valid PDF with Form XObjects that reference nested resource dictionaries that repeatedly contain many Form XObjects from the next level can take a long time and use a lot of memory even for relatively small files. The problem seems to be that, in order to perform deduplication, PdfSmartCopy.ByteStore recursively traverses shared indirect objects once for every path through the resource graph, without keeping track of already-serialized indirect objects.
Important to note that using PdfCopy to process the same kind of file works fine, without taking too long or using too much memory.
To Reproduce
The document that triggered the issue cannot be shared because it contains private information. It is a 11 page document of roughly 300 KB, generated by the library TCPDF 6.7.5. The following code generates a 1 page pdf document that demonstrates the issue:
private void test() {
var pdfBytes = createPdfWithNestedFormXObjects(8, 8);
try (var doc = new Document(); var out = new ByteArrayOutputStream(); var copy = new PdfSmartCopy(doc, out)) {
doc.open();
copy(pdfBytes, copy);
}
}
void copy(byte[] bytes, PdfCopy copy) throws Exception {
try (var reader = new PdfReader(bytes)) {
for (var page = 1; page <= reader.getNumberOfPages(); page++) {
copy.addPage(copy.getImportedPage(reader, page));
}
}
}
private byte[] createPdfWithNestedFormXObjects(int nestedLeves, int fanout) throws Exception {
var output = new ByteArrayOutputStream();
var document = new Document(PageSize.A4);
var writer = PdfWriter.getInstance(document, output);
document.open();
document.add(new Paragraph("Test PDF, nested Form XObjects"));
List<PdfTemplate> layer = new ArrayList<>();
for (var index = 0; index < fanout; index++) {
var leaf = PdfTemplate.createTemplate(writer, 20, 20);
leaf.rectangle(0, 0, 10, 10);
leaf.stroke();
layer.add(leaf);
}
for (var level = 1; level < nestedLeves; level++) {
var parents = new ArrayList<PdfTemplate>();
for (var index = 0; index < fanout; index++) {
var parent = PdfTemplate.createTemplate(writer, 20, 20);
for (var nested : layer) {
parent.addTemplate(nested, 0, 0);
}
parents.add(parent);
}
layer = parents;
}
for (var form : layer) {
writer.getDirectContent().addTemplate(form, 0, 0);
}
document.close();
return output.toByteArray();
}
Varying the parameters of createPdfWithNestedFormXObjects allows to see the cases that trigger the problem.
Expected behavior
Using PdfSmartCopy should take more or less the same amount of time and use more or less the same amount of memory of using PdfCopy to process a document with multple levels of Form XObjects that reference shared Form XObjects.
System
- OpenPDF version: 3.0.3, 3.0.4, 3.0.5
- Ngôn ngữ chính
- Java
- Star
- 4.4k
- Fork
- 714
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của LibrePDF/OpenPDF
-
bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
-
IndexOutOfBoundsException in PdfReaderCó thể đã có người làm @andreasrosdalw đã nhận 95 ngày trước. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
-
enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 38/100
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 45/100
Tất cả issue của LibrePDF/OpenPDF
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
bug/错误
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
FCL-Team/FoldCraftLauncher#1982 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG] micronaut-serde-oracle-jdbc-json brings a second OJDBC driver onto the runtime classpathCó thể đã có người làm @ZARAYACH đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
micronaut-projects/micronaut-serialization#1494 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 75/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 2 ngày