Repository: typst/typst
File: crates/typst-library/src/visualize/image/mod.rs (Rust)

Code before:
impl Packed<ImageElem> {
    /// Decodes the image.
    pub fn decode(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Image> {
        let span = self.span();
        let loaded = &self.source.derived;
        let format = self.determine_format(styles).at(span)?;

        // Warn the user if the image contains a foreign object. Not perfect
        // because the svg could also be encoded, but that's an edge case.
        if format == ImageFormat::Vector(VectorFormat::Svg) {
            let has_foreign_object =
                memchr::memmem::find(&loaded.data, b"<foreignObject").is_some();

            if has_foreign_object {
                engine.sink.warn(warning!(
                span,
                "image contains foreign object";
                hint: "SVG images with foreign objects might render incorrectly in typst";
                hint: "see https://github.com/typst/typst/issues/1421 for more information"
            ));
            }
        }

        // Construct the image itself.
        let kind = match format {
            ImageFormat::Raster(format) => ImageKind::Raster(
                RasterImage::new(
                    loaded.data.clone(),
                    format,
                    self.icc.get_ref(styles).as_ref().map(|icc| icc.derived.clone()),
                )
                .at(span)?,
            ),
            ImageFormat::Vector(VectorFormat::Svg) => {
                // Identify the SVG file in case contained hrefs need to be resolved.
                let svg_file = match self.source.source {
                    DataSource::Path(ref path) => span.resolve_path(path).ok(),
                    DataSource::Bytes(_) => span.id(),
                };
                ImageKind::Svg(
                    SvgImage::with_fonts_images(
                        loaded.data.clone(),
                        engine.world,
                        &families(styles).map(|f| f.as_str()).collect::<Vec<_>>(),
                        svg_file,
                    )
                    .within(loaded)?,
                )
            }
            ImageFormat::Vector(VectorFormat::Pdf) => {
                let document = match PdfDocument::new(loaded.data.clone()) {

Review comment (bug):
```suggestion
                        hint: "SVG images with foreign objects might render incorrectly in Typst";
```

As per https://github.com/typst/typst?tab=readme-ov-file#pronunciation-and-spelling

Code after:
impl Packed<ImageElem> {
    /// Decodes the image.
    pub fn decode(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Image> {
        let span = self.span();
        let loaded = &self.source.derived;
        let format = self.determine_format(styles).at(span)?;

        // Construct the image itself.
        let kind = match format {
            ImageFormat::Raster(format) => ImageKind::Raster(
                RasterImage::new(
                    loaded.data.clone(),
                    format,
                    self.icc.get_ref(styles).as_ref().map(|icc| icc.derived.clone()),
                )
                .at(span)?,
            ),
            ImageFormat::Vector(VectorFormat::Svg) => {
                // Warn the user if the image contains a foreign object. Not
                // perfect because the svg could also be encoded, but that's an
                // edge case.
                if memchr::memmem::find(&loaded.data, b"<foreignObject").is_some() {
                    engine.sink.warn(warning!(
                        span,
                        "image contains foreign object";
                        hint: "SVG images with foreign objects might render incorrectly in typst";
                        hint: "see https://github.com/typst/typst/issues/1421 for more information"
                    ));
                }

                // Identify the SVG file in case contained hrefs need to be resolved.
                let svg_file = match self.source.source {
                    DataSource::Path(ref path) => span.resolve_path(path).ok(),
                    DataSource::Bytes(_) => span.id(),
                };
                ImageKind::Svg(
                    SvgImage::with_fonts_images(
                        loaded.data.clone(),
                        engine.world,
                        &families(styles).map(|f| f.as_str()).collect::<Vec<_>>(),
                        svg_file,
                    )
                    .within(loaded)?,
                )
            }
            ImageFormat::Vector(VectorFormat::Pdf) => {
                let document = match PdfDocument::new(loaded.data.clone()) {
                    Ok(doc) => doc,
                    Err(e) => match e {
                        // TODO: the `DecyptionError` is currently not public
                        LoadPdfError::Decryption(_) => {