Skip to content

SVG images embedded but no <Default Extension="svg"> written to [Content_Types].xml (panics in debug since 0.2.19) #10

Description

@squinky86

Version: 0.2.19 (regression introduced somewhere in 0.2.13–0.2.19; 0.2.12 works)

Summary

When a presentation embeds SVG images, the generated [Content_Types].xml does not declare a content type for the svg extension. The resulting package is invalid per OPC rules (every part needs an Override or a matching Default). In release builds this silently produces a broken .pptx; in debug builds the new package validation added in 0.2.19 turns it into a panic.

Panic message (debug builds)

thread '...' panicked at ppt-rs-0.2.19/src/generator/builder.rs:112:5:
generated PPTX failed package validation: [
  "Part ppt/media/image1.svg has no Override or Default in [Content_Types].xml",
  "Part ppt/media/image2.svg has no Override or Default in [Content_Types].xml",
  ...
]

Root cause

create_pptx_with_contentwrite_content_types collects the media extensions actually used (the registry does track svg), then builds the XML via content_types_openingappend_image_content_type_defaults in src/generator/package_xml.rs.

That function only emits Defaults for jpg/jpeg/png/gif:

fn append_image_content_type_defaults(xml: &mut String, media_exts: &[String]) {
    let mut has_jpg = false;
    let mut has_png = false;
    let mut has_gif = false;
    for ext in media_exts {
        match ext.as_str() {
            "jpg" | "jpeg" => has_jpg = true,
            "png" => has_png = true,
            "gif" => has_gif = true,
            _ => {}   // <-- svg / bmp / tiff / mp4 / mp3 / wav silently dropped
        }
    }
    // ...only writes jpg/png/gif defaults
}

So svg (and bmp, tiff, mp4, mp3, wav) are accepted as embeddable media but never get a <Default> entry. Note ContentTypesPart::new() does list all of these defaults (including svg), but the builder path doesn't go through ContentTypesPart — it uses this hand-rolled function instead, so the two have drifted out of sync.

Expected

Any media extension that can be embedded should get a corresponding <Default Extension="…" ContentType="…"/>, e.g. <Default Extension="svg" ContentType="image/svg+xml"/>.

Suggested fix

Have append_image_content_type_defaults cover every supported media extension (ideally derive it from the same source as ContentTypesPart::new() so they can't diverge again), rather than hardcoding only jpg/png/gif.

Reproduction

  1. Build a presentation with create_pptx_with_content, adding a slide with an SVG image (ImageBuilder::from_bytes(svg_bytes, w, h, "svg")).
  2. Debug build: panics at builder.rs:112.
  3. Release build: produces a .pptx whose [Content_Types].xml has no svg Default, which PowerPoint/validators reject.

Workaround

Pin to ppt-rs = "=0.2.12", or post-process the generated zip to inject <Default Extension="svg" ContentType="image/svg+xml"/> into [Content_Types].xml.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions