Ticket #24793: 24793.patch

File 24793.patch, 13.5 KB (added by stoecker, 4 days ago)

Switch to jsvg

  • build.xml

     
    11181118                <exclude name="com/drew/metadata/wav/**"/>
    11191119                <exclude name="com/drew/metadata/webp/**"/>
    11201120                <exclude name="com/drew/tools/**"/>
    1121                 <exclude name="com/kitfox/svg/app/ant/**"/>
    1122                 <exclude name="com/kitfox/svg/app/*Dialog*"/>
    1123                 <exclude name="com/kitfox/svg/app/*Frame*"/>
    1124                 <exclude name="com/kitfox/svg/app/*Player*"/>
    1125                 <exclude name="com/kitfox/svg/app/*Viewer*"/>
    11261121                <exclude name="org/apache/commons/compress/PasswordRequiredException*"/>
    11271122                <exclude name="org/apache/commons/compress/archivers/**"/>
    11281123                <exclude name="org/apache/commons/compress/changes/**"/>
  • ivy.xml

     
    3131        <dependency conf="api->default" org="org.tukaani" name="xz" rev="1.11"/>
    3232        <dependency conf="api->default" org="com.adobe.xmp" name="xmpcore" rev="6.1.11"/>
    3333        <dependency conf="api->default" org="com.drewnoakes" name="metadata-extractor" rev="2.19.0" transitive="false"/>
    34         <dependency conf="api->default" org="com.formdev" name="svgSalamander" rev="1.1.4"/>
     34        <dependency conf="api->default" org="com.github.weisj" name="jsvg" rev="1.7.0"/>
     35        <dependency conf="api->default" org="org.jetbrains" name="annotations" rev="24.1.0"/>
    3536        <dependency conf="api->default" org="ch.poole" name="OpeningHoursParser" rev="0.29.0"/>
    3637        <!-- Don't forget to update org.openstreetmap.josm.tools.Tag2Link#PREF_SOURCE -->
    3738        <dependency conf="api->default" org="org.webjars.npm" name="tag2link" rev="2026.6.26"/>
  • pom.xml

     
    123123      <scope>compile</scope>
    124124    </dependency>
    125125    <dependency>
    126       <groupId>com.formdev</groupId>
    127       <artifactId>svgSalamander</artifactId>
     126      <groupId>com.github.weisj</groupId>
     127      <artifactId>jsvg</artifactId>
    128128      <scope>compile</scope>
    129129    </dependency>
    130130    <dependency>
     131      <groupId>org.jetbrains</groupId>
     132      <artifactId>annotations</artifactId>
     133      <version>24.1.0</version>
     134      <scope>provided</scope>
     135    </dependency>
     136    <dependency>
    131137      <groupId>ch.poole</groupId>
    132138      <artifactId>OpeningHoursParser</artifactId>
    133139      <scope>compile</scope>
     
    661667                  </excludes>
    662668                </filter>
    663669                <filter>
    664                   <artifact>com.formdev:svgSalamander</artifact>
    665                   <excludes>
    666                     <exclude>com/kitfox/svg/app/ant/**</exclude>
    667                     <exclude>com/kitfox/svg/app/*Dialog*</exclude>
    668                     <exclude>com/kitfox/svg/app/*Frame*</exclude>
    669                     <exclude>com/kitfox/svg/app/*Player*</exclude>
    670                     <exclude>com/kitfox/svg/app/*Viewer*</exclude>
    671                   </excludes>
    672                 </filter>
    673                 <filter>
    674670                  <artifact>org.apache.commons:commons-compress</artifact>
    675671                  <excludes>
    676672                    <exclude>org/apache/commons/compress/PasswordRequiredException*</exclude>
  • src/org/openstreetmap/josm/tools/ImageProvider.java

     
    7979import org.xml.sax.XMLReader;
    8080import org.xml.sax.helpers.DefaultHandler;
    8181
    82 import com.kitfox.svg.SVGDiagram;
    83 import com.kitfox.svg.SVGException;
    84 import com.kitfox.svg.SVGUniverse;
     82import com.github.weisj.jsvg.SVGDocument;
     83import com.github.weisj.jsvg.geometry.size.FloatSize;
     84import com.github.weisj.jsvg.parser.DocumentLimits;
     85import com.github.weisj.jsvg.parser.LoaderContext;
     86import com.github.weisj.jsvg.parser.SVGLoader;
    8587
    8688/**
    8789 * Helper class to support the application with images.
     
    252254        ARCHIVE
    253255    }
    254256
     257    private static final SVGLoader svgloader = new SVGLoader();
     258
    255259    /**
    256260     * Property set on {@code BufferedImage} returned by {@link #makeImageTransparent}.
    257261     * @since 7132
     
    295299    /** <code>true</code> if multi-resolution image is requested */
    296300    protected boolean multiResolution = true;
    297301
    298     private static SVGUniverse svgUniverse;
    299 
    300302    /**
    301303     * The icon cache
    302304     */
     
    967969     */
    968970    private static ImageResource getIfAvailableHttp(String url, ImageType type) {
    969971        try (CachedFile cf = new CachedFile(url).setDestDir(
    970                 new File(Config.getDirs().getCacheDirectory(true), "images").getPath());
    971              InputStream is = cf.getInputStream()) {
     972                new File(Config.getDirs().getCacheDirectory(true), "images").getPath())) {
     973            URL localurl = Utils.fileToURL(cf.getFile());
    972974            switch (type) {
    973975            case SVG:
    974                 SVGDiagram svg;
    975                 synchronized (getSvgUniverse()) {
    976                     URI uri = getSvgUniverse().loadSVG(is, Utils.fileToURL(cf.getFile()).toString());
    977                     svg = getSvgUniverse().getDiagram(uri);
    978                 }
     976                Logging.debug("Load SVG "+url);
     977                SVGDocument svg = svgloader.load(localurl, getSVGContext());
    979978                return svg == null ? null : new ImageResource(svg);
    980979            case OTHER:
    981980                BufferedImage img = null;
    982981                try {
    983                     img = read(Utils.fileToURL(cf.getFile()), false, false);
     982                    img = read(localurl, false, false);
    984983                } catch (IOException | UnsatisfiedLinkError e) {
    985984                    Logging.log(Logging.LEVEL_WARN, "Exception while reading HTTP image:", e);
    986985                }
     
    10171016            }
    10181017            String mediatype = m.group(1);
    10191018            if ("image/svg+xml".equals(mediatype)) {
    1020                 String s = new String(bytes, StandardCharsets.UTF_8);
    10211019                // see #19097: check if s starts with PNG magic
    1022                 if (s.length() > 4 && "PNG".equals(s.substring(1, 4))) {
     1020                if (bytes.length > 4 && bytes[1] == 'P' && bytes[2] == 'N' && bytes[3] == 'G') {
    10231021                    Logging.warn("url contains PNG file " + url);
    10241022                    return null;
    10251023                }
    1026                 SVGDiagram svg;
    1027                 synchronized (getSvgUniverse()) {
    1028                     URI uri = getSvgUniverse().loadSVG(new StringReader(s), Utils.encodeUrl(s));
    1029                     svg = getSvgUniverse().getDiagram(uri);
    1030                 }
     1024                InputStream is = new ByteArrayInputStream(bytes);
     1025                Logging.debug("Load SVG "+url);
     1026                SVGDocument svg = svgloader.load(is, (URI) null, getSVGContext());
    10311027                if (svg == null) {
    1032                     Logging.warn("Unable to process svg: "+s);
     1028                    Logging.warn("Unable to process svg: "+bytes);
    10331029                    return null;
    10341030                }
    10351031                return new ImageResource(svg);
     
    11121108                try (InputStream is = zipFile.getInputStream(entry)) {
    11131109                    switch (type) {
    11141110                    case SVG:
    1115                         SVGDiagram svg;
    1116                         synchronized (getSvgUniverse()) {
    1117                             URI uri = getSvgUniverse().loadSVG(is, entryName, true);
    1118                             svg = getSvgUniverse().getDiagram(uri);
    1119                         }
     1111                        Logging.debug("Load SVG "+archive+" "+entryName);
     1112                        SVGDocument svg = svgloader.load(is, (URI) null, getSVGContext());
    11201113                        return svg == null ? null : new ImageResource(svg);
    11211114                    case OTHER:
    11221115                        while (size > 0) {
     
    11511144        Objects.requireNonNull(type, "ImageType must not be null");
    11521145        switch (type) {
    11531146        case SVG:
    1154             SVGDiagram svg = null;
    1155             synchronized (getSvgUniverse()) {
     1147            SVGDocument svg = null;
     1148            try {
     1149                Logging.debug("Load SVG "+path);
     1150                svg = svgloader.load(path, getSVGContext());
     1151            } catch (Exception e) {
     1152                Logging.error("Cannot open {0}: {1}", path, e.getMessage());
     1153                Logging.trace(e);
     1154            }
     1155
     1156            if (svg == null && "jar".equals(path.getProtocol())) {
    11561157                try {
    1157                     URI uri = null;
    1158                     try {
    1159                         uri = getSvgUniverse().loadSVG(path);
    1160                     } catch (InvalidPathException e) {
    1161                         Logging.error("Cannot open {0}: {1}", path, e.getMessage());
    1162                         Logging.trace(e);
    1163                     }
    1164                     if (uri == null && "jar".equals(path.getProtocol())) {
    1165                         URL betterPath = Utils.betterJarUrl(path);
    1166                         if (betterPath != null) {
    1167                             uri = getSvgUniverse().loadSVG(betterPath);
     1158                    URL betterPath = Utils.betterJarUrl(path);
     1159                    if (betterPath != null) {
     1160                        try {
     1161                            Logging.debug("Load SVG "+betterPath);
     1162                            svg = svgloader.load(betterPath, getSVGContext());
     1163                        } catch (Exception e) {
     1164                            Logging.log(Logging.LEVEL_WARN, "Unable to read SVG from fallback jar URL", e);
    11681165                        }
    11691166                    }
    1170                     svg = getSvgUniverse().getDiagram(uri);
    1171                 } catch (SecurityException | IOException e) {
     1167                } catch (IOException e) {
    11721168                    Logging.log(Logging.LEVEL_WARN, "Unable to read SVG", e);
    11731169                }
    11741170            }
     
    14711467     * @param resizeMode how to size/resize the image
    14721468     * @return an image from the given SVG data at the desired dimension.
    14731469     */
    1474     static BufferedImage createImageFromSvg(SVGDiagram svg, Dimension dim, ImageResizeMode resizeMode) {
     1470    static BufferedImage createImageFromSvg(SVGDocument svg, Dimension dim, ImageResizeMode resizeMode) {
    14751471        if (Logging.isTraceEnabled()) {
    1476             Logging.trace("createImageFromSvg: {0} {1}", svg.getXMLBase(), dim);
     1472            Logging.trace("createImageFromSvg: {0}", dim);
    14771473        }
    1478         final float sourceWidth = svg.getWidth();
    1479         final float sourceHeight = svg.getHeight();
     1474        FloatSize size = svg.size();
     1475        final float sourceWidth = size.width;
     1476        final float sourceHeight = size.height;
    14801477        if (sourceWidth <= 0 || sourceHeight <= 0) {
    1481             Logging.error("createImageFromSvg: {0} {1} sourceWidth={2} sourceHeight={3}", svg.getXMLBase(), dim, sourceWidth, sourceHeight);
     1478            Logging.error("createImageFromSvg: {0} sourceWidth={1} sourceHeight={2}", dim, sourceWidth, sourceHeight);
    14821479            return null;
    14831480        }
    14841481        return resizeMode.createBufferedImage(dim, new Dimension((int) sourceWidth, (int) sourceHeight), g -> {
    1485             try {
    1486                 synchronized (getSvgUniverse()) {
    1487                     svg.render(g);
    1488                 }
    1489             } catch (SVGException ex) {
    1490                 Logging.log(Logging.LEVEL_ERROR, "Unable to load svg:", ex);
    1491             }
     1482            svg.render(null, g);
    14921483        }, null);
    14931484    }
    14941485
    1495     private static synchronized SVGUniverse getSvgUniverse() {
    1496         if (svgUniverse == null) {
    1497             svgUniverse = new SVGUniverse();
    1498             // CVE-2017-5617: Allow only data scheme (see #14319)
    1499             svgUniverse.setImageDataInlineOnly(true);
    1500         }
    1501         return svgUniverse;
    1502     }
    1503 
    15041486    /**
    15051487     * Returns a <code>BufferedImage</code> as the result of decoding
    15061488     * a supplied <code>File</code> with an <code>ImageReader</code>
     
    19541936        return new ImageIcon(new BufferedImage(size.getAdjustedWidth(), size.getAdjustedHeight(), BufferedImage.TYPE_INT_ARGB));
    19551937    }
    19561938
     1939    private static LoaderContext getSVGContext() {
     1940        return LoaderContext.builder().documentLimits(new DocumentLimits(DocumentLimits.DEFAULT_MAX_NESTING_DEPTH,
     1941            DocumentLimits.DEFAULT_MAX_USE_NESTING_DEPTH, DocumentLimits.DEFAULT_MAX_PATH_COUNT+3000)).build();
     1942    }
     1943
    19571944    @Override
    19581945    public String toString() {
    19591946        return ("ImageProvider ["
  • src/org/openstreetmap/josm/tools/ImageResource.java

     
    1717
    1818import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
    1919
    20 import com.kitfox.svg.SVGDiagram;
     20import com.github.weisj.jsvg.SVGDocument;
    2121
    2222/**
    2323 * Holds data for one particular image.
     
    3636    /**
    3737     * SVG diagram information in case of SVG vector image.
    3838     */
    39     private SVGDiagram svg;
     39    private SVGDocument svg;
    4040    /**
    4141     * Use this dimension to request original file dimension.
    4242     */
     
    6767     * Constructs a new {@code ImageResource} from SVG data.
    6868     * @param svg SVG data
    6969     */
    70     public ImageResource(SVGDiagram svg) {
     70    public ImageResource(SVGDocument svg) {
    7171        CheckParameterUtil.ensureParameterNotNull(svg);
    7272        this.svg = svg;
    7373    }