mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 06:59:44 +07:00
WEB-52274 Support non-base64 encoded image URLs
(cherry picked from commit 3d5276cb62a60589895686370a2da160343912cb) IJ-CR-148627 GitOrigin-RevId: 91318d4c76703ca673b364b77c181a706441e6b6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
eae71268ca
commit
6a7ed7a79a
@@ -8,7 +8,7 @@ import org.intellij.markdown.html.LinkGeneratingProvider
|
||||
private val UNSAFE_LINK_REGEX = Regex("^(vbscript|javascript|file|data):", RegexOption.IGNORE_CASE)
|
||||
private val UNSAFE_LINK_REGEX_IMAGE = Regex("^(vbscript|javascript|data):", RegexOption.IGNORE_CASE)
|
||||
/* We need to support svg for documentation rendering */
|
||||
private val ALLOWED_DATA_LINK_REGEX = Regex("^data:image/(gif|png|jpeg|webp|svg)(\\+[a-z0-9A-Z]*)?;", RegexOption.IGNORE_CASE)
|
||||
private val ALLOWED_DATA_LINK_REGEX = Regex("^data:image/(gif|png|jpeg|webp|svg)[+;=a-z0-9A-Z]*,", RegexOption.IGNORE_CASE)
|
||||
|
||||
fun makeXssSafeDestination(s: CharSequence, isImage: Boolean): CharSequence = s.takeIf {
|
||||
!(if (isImage) UNSAFE_LINK_REGEX_IMAGE else UNSAFE_LINK_REGEX).containsMatchIn(s.trim()) || ALLOWED_DATA_LINK_REGEX.containsMatchIn(s.trim())
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.svg.SvgImageDecoder;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -19,6 +20,7 @@ import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -66,8 +68,8 @@ public final class JBImageToolkit {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static URL tryBuildBase64Url(@NotNull String url) throws MalformedURLException {
|
||||
if (url.startsWith("data:image") && url.contains("base64")) {
|
||||
public static URL tryBuildDataImageUrl(@NotNull String url) throws MalformedURLException {
|
||||
if (url.startsWith("data:image/") && url.contains(",")) {
|
||||
return new URL(null, url, JBImageToolkit.dataImageStreamUrlHandler);
|
||||
}
|
||||
return null;
|
||||
@@ -87,8 +89,10 @@ public final class JBImageToolkit {
|
||||
return SvgImageDecoder.Companion.detect(source, bufferedStream, -1, -1);
|
||||
}
|
||||
|
||||
private JBImageToolkit() {}
|
||||
private JBImageToolkit() { }
|
||||
|
||||
private static final URLStreamHandler dataImageStreamUrlHandler = new DataImageURLStreamHandler();
|
||||
|
||||
private static class DataImageURLStreamHandler extends URLStreamHandler {
|
||||
|
||||
@Override
|
||||
@@ -105,9 +109,12 @@ public final class JBImageToolkit {
|
||||
connect(); // Mimics the semantics of an actual URL connection.
|
||||
var parts = StringUtil.split(u.toString(), ",");
|
||||
if (parts.size() == 2) {
|
||||
var isBase64 = parts.get(0).endsWith(";base64");
|
||||
var encodedImage = parts.get(1);
|
||||
return new ByteArrayInputStream(Base64.getDecoder().decode(encodedImage));
|
||||
} else {
|
||||
return new ByteArrayInputStream(isBase64 ? Base64.getDecoder().decode(encodedImage)
|
||||
: URLUtil.decode(encodedImage).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
else {
|
||||
throw new IOException("Malformed data url: " + u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ import javax.swing.text.Element
|
||||
import javax.swing.text.html.HTML
|
||||
import javax.swing.text.html.ImageView
|
||||
|
||||
internal open class Base64ImageView(elem: Element?) : ImageView(elem) {
|
||||
internal open class DataUrlImageView(elem: Element?) : ImageView(elem) {
|
||||
|
||||
override fun getImageURL(): URL? =
|
||||
element.attributes.getAttribute(HTML.Attribute.SRC).asSafely<String>()?.let {
|
||||
JBImageToolkit.tryBuildBase64Url(it)
|
||||
JBImageToolkit.tryBuildDataImageUrl(it)
|
||||
} ?: super.getImageURL()
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import javax.swing.text.FlowView
|
||||
import javax.swing.text.View
|
||||
import kotlin.math.max
|
||||
|
||||
internal class FitToWidthImageView(element: Element) : Base64ImageView(element) {
|
||||
internal class FitToWidthImageView(element: Element) : DataUrlImageView(element) {
|
||||
private var myAvailableWidth = 0
|
||||
|
||||
override fun getLoadingImageIcon(): Icon =
|
||||
|
||||
@@ -13,9 +13,8 @@ import java.awt.Shape
|
||||
import java.awt.image.BufferedImage
|
||||
import javax.swing.Icon
|
||||
import javax.swing.text.Element
|
||||
import javax.swing.text.html.ImageView
|
||||
|
||||
internal class HiDpiScalingImageView(elem: Element) : Base64ImageView(elem) {
|
||||
internal class HiDpiScalingImageView(elem: Element) : DataUrlImageView(elem) {
|
||||
private val scaleContext: ScaleContext?
|
||||
get() = container?.takeIf(StartupUiUtil::isJreHiDPI)?.let(ScaleContext::create)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user