From d71252990a4fd68c3f4324506ed9c3788906f028 Mon Sep 17 00:00:00 2001 From: Vladimir Babin Date: Wed, 2 Sep 2026 13:36:28 +0300 Subject: [PATCH] fix: avoid panic in layout when a section has no page definition LayoutEngine::calculate_layout panicked via expect("Section must have page definition") for any parsed document whose section lacks a PageDef record. PageDef is optional in the body-text stream and Section::page_def defaults to None, so a valid HWP file without that record (e.g. the repo's own styled_document.hwp) crashed callers of the public layout API. Skip sections without a page definition instead of unwrapping. --- src/render/layout.rs | 8 ++++---- tests/layout_missing_page_def_test.rs | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 tests/layout_missing_page_def_test.rs diff --git a/src/render/layout.rs b/src/render/layout.rs index 873bc91..56ef7f4 100644 --- a/src/render/layout.rs +++ b/src/render/layout.rs @@ -80,10 +80,10 @@ impl<'a> LayoutEngine<'a> { let mut pages = Vec::new(); // Get page definition - let page_def = section - .page_def - .as_ref() - .expect("Section must have page definition"); + let page_def = match section.page_def.as_ref() { + Some(page_def) => page_def, + None => return pages, + }; let mut current_page = RenderedPage { width: page_def.width, diff --git a/tests/layout_missing_page_def_test.rs b/tests/layout_missing_page_def_test.rs new file mode 100644 index 0000000..0b6e260 --- /dev/null +++ b/tests/layout_missing_page_def_test.rs @@ -0,0 +1,22 @@ +use hwpers::render::layout::LayoutEngine; +use hwpers::HwpReader; +use std::path::PathBuf; + +/// A section without a PageDef record must not panic during layout. +/// `styled_document.hwp` (shipped in the repo) parses into a section whose +/// `page_def` is `None`, which previously triggered a panic in `layout_section`. +#[test] +fn test_layout_section_without_page_def_does_not_panic() { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("styled_document.hwp"); + let bytes = std::fs::read(&path).expect("failed to read styled_document.hwp"); + let doc = HwpReader::from_bytes(&bytes).expect("failed to parse styled_document.hwp"); + + assert!( + doc.sections().any(|s| s.page_def.is_none()), + "expected at least one section without a page definition" + ); + + let engine = LayoutEngine::new(&doc); + let result = engine.calculate_layout(); + assert!(result.pages.is_empty()); +}