Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unreachable! called when .build() is called on a document. #750

Open
JamieMair opened this issue Aug 7, 2024 · 1 comment
Open

unreachable! called when .build() is called on a document. #750

JamieMair opened this issue Aug 7, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@JamieMair
Copy link

JamieMair commented Aug 7, 2024

Describe the bug

The code hits an unreachable! block in the source code when running .build(), here is the stack trace:

internal error: entered unreachable code
stack backtrace:
   0: rust_begin_unwind
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/panicking.rs:72:14
   2: core::panicking::panic
             at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/core/src/panicking.rs:146:5
   3: <docx_rs::documents::elements::run::Run as docx_rs::documents::build_xml::BuildXML>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/run.rs:339:49
   4: <docx_rs::documents::elements::paragraph::ParagraphChild as docx_rs::documents::build_xml::BuildXML>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/paragraph.rs:47:39
   5: docx_rs::xml_builder::XMLBuilder::add_child
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/xml_builder/mod.rs:84:19
   6: docx_rs::xml_builder::XMLBuilder::add_children
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/xml_builder/mod.rs:111:20
   7: <docx_rs::documents::elements::paragraph::Paragraph as docx_rs::documents::build_xml::BuildXML>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/paragraph.rs:492:9
   8: docx_rs::documents::elements::paragraph::<impl docx_rs::documents::build_xml::BuildXML for alloc::boxed::Box<docx_rs::documents::elements::paragraph::Paragraph>>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/paragraph.rs:503:9
   9: <docx_rs::documents::elements::structured_data_tag::StructuredDataTagChild as docx_rs::documents::build_xml::BuildXML>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/structured_data_tag.rs:43:53
  10: docx_rs::xml_builder::XMLBuilder::add_child
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/xml_builder/mod.rs:84:19
  11: docx_rs::xml_builder::XMLBuilder::add_children
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/xml_builder/mod.rs:111:20
  12: docx_rs::documents::elements::structured_data_tag::StructuredDataTag::inner_build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/structured_data_tag.rs:152:9
  13: docx_rs::documents::elements::structured_data_tag::<impl docx_rs::documents::build_xml::BuildXML for alloc::boxed::Box<docx_rs::documents::elements::structured_data_tag::StructuredDataTag>>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/elements/structured_data_tag.rs:171:9
  14: docx_rs::xml_builder::XMLBuilder::add_child
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/xml_builder/mod.rs:84:19
  15: <docx_rs::documents::footer::Footer as docx_rs::documents::build_xml::BuildXML>::build
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/footer.rs:91:58
  16: docx_rs::documents::Docx::build::{{closure}}
             at /home/jamie/.cargo/git/checkouts/docx-rs-cc108461f2f164ad/93eb2e1/docx-core/src/documents/mod.rs:598:22

Reproduced step

Example doc (blank): example_doc.docx

  1. Create a new project and download the example_doc.docx file and place it next to main.rs
  2. Add docx-rs to Cargo.toml of a new binary project (I have tried latest and current git branch with docx-rs = { git = "https://github.com/bokuweb/docx-rs.git" } in Cargo.toml).
  3. Write the following code in main.rs
use std::io::Cursor;
static DOC_BYTES: &[u8] = include_bytes!("example_doc.docx");

fn main() {
    let document = docx_rs::read_docx(DOC_BYTES).unwrap();
    // Compile the docx into a zip file in the memory buffer
    let mut output_buffer = Cursor::new(Vec::new());
    // Compile the docx into a zip file in the memory buffer
    document.build().pack(&mut output_buffer).unwrap();

    let bytes: Vec<u8> = output_buffer.into_inner();
    format!("Output bytes: {} bytes", bytes.len());
}
  1. Build and run, which errors.

Expected behavior

The program to run correctly, with the produced document being identical (or almost) to the input document. This document should be stored in bytes within the bytes variable.

Actual behavior

A panic happens when running .build().

Screenshots

N/A

Desktop (please complete the following information)

  • OS: Fedora 40
  • Browser N/A
  • Version Latest (or 4.1.17)
@JamieMair JamieMair added the bug Something isn't working label Aug 7, 2024
@drewmiller
Copy link

drewmiller commented Sep 19, 2024

This is because the XML reader doesn't parse the instruction text in the page numbering. I've added the below to reader/run.rs and it seems to work.

fn read_instr_text(instr_text: String) -> Result<RunChild, ReaderError> {
    let instructions = instr_text.trim().split(" ").collect::<Vec<&str>>();
    let Some(instruction) = instructions.first() else {
        return Err(ReaderError::XMLReadError);
    };
    match *instruction {
        "TOC" => {
            if let Ok(toc) = crate::InstrToC::from_str(&instr_text) {
                return Ok(RunChild::InstrText(Box::new(crate::InstrText::TOC(toc))));
            }
        }
        "TC" => {
            if let Ok(tc) = crate::InstrTC::from_str(&instr_text) {
                return Ok(RunChild::InstrText(Box::new(crate::InstrText::TC(tc))));
            }
        }
        "PAGEREF" => {
            if let Ok(pageref) = crate::InstrPAGEREF::from_str(&instr_text) {
                return Ok(RunChild::InstrText(Box::new(crate::InstrText::PAGEREF(pageref))));
            }
        }
        "PAGE" => {
            return Ok(RunChild::InstrText(Box::new(crate::InstrText::PAGE(crate::InstrPAGE {}))));
        }
        "NUMPAGES" => {
            return Ok(RunChild::InstrText(Box::new(crate::InstrText::NUMPAGES(crate::InstrNUMPAGES {}))));
        }
        "HYPERLINK" => {
            if let Ok(link) = crate::InstrHyperlink::from_str(&instr_text) {
                return Ok(RunChild::InstrText(Box::new(crate::InstrText::HYPERLINK(link))));
            }
        }
        _ => {
            return Ok(RunChild::InstrText(Box::new(crate::InstrText::Unsupported(instr_text))));
        }
    };
    Err(ReaderError::XMLReadError)
}

Followed by:

...
XMLElement::InstrText => loop {
  let e = r.next();
  match e {
      Ok(XmlEvent::Characters(c)) => {
          run.children.push(read_instr_text(c)?);
          break;
      }
  ...

In the parsing loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants