Skip to content

Commit

Permalink
20.2.8 release
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgraph committed Sep 1, 2022
1 parent 0e6f27f commit 59887e4
Show file tree
Hide file tree
Showing 40 changed files with 5,680 additions and 5,638 deletions.
18 changes: 18 additions & 0 deletions ChangeLog
@@ -1,3 +1,21 @@
01-SEP-2022: 20.2.8

- Fixes importing plain SVG images by drag and drop [DS-902]
- Adds createToolbarButton helper function [3007]
- Sets current stroke color and width independently [DS-903]
- Fixes layout for CSV import in lightbox mode [DS-904]
- Fixes repeated set default style not working [DS-905]
- [conf cloud] Catches errors in diagram text extraction to not break re-indexing process [DS-908]
- Applies fillColor=strokeColor for shapes where appropriate [DS-903]
- Makes format window closable in min ui [DS-906]
- Fixes file pattern for workbox [2977]
- Smaller stencils.min, uses built-in base64 encoder [DS-907]
- Allows for close icon in minimized format window [DS-906]
- Adds support for stroke and fill color in stencils [DS-903]
- Restricts proxy servlet, java disabled by default, all errors are 500 (not distinguishable), allow ports only by config [CSP-633]
- Conf Cloud: Fixed error of renaming/changing view settings not published if no modification done to the diagram [DID-6141]
- Adds custom starting unit number to Rack Cabinet shape [2967]

22-AUG-2022: 20.2.7

- Reduces cursor update frequency to reduce DO request count [DS-899]
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
20.2.7
20.2.8
Binary file modified etc/build/Xml2Js.class
Binary file not shown.
93 changes: 5 additions & 88 deletions etc/build/Xml2Js.java
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import java.util.Set;
import java.util.zip.Deflater;
import java.util.Base64;

public class Xml2Js
{
Expand Down Expand Up @@ -73,12 +74,8 @@ else if (f.getCanonicalPath().toLowerCase().endsWith(".xml"))
*/
public static String processFile(File file) throws IOException
{
System.out.println("Processing " + file.getCanonicalPath() + "...");

Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
byte[] inBytes = encodeURIComponent(
readInputStream(new FileInputStream(file)),
CHARSET_FOR_URL_ENCODING).getBytes("UTF-8");
Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true);
byte[] inBytes = readInputStream(new FileInputStream(file)).getBytes("UTF-8");
deflater.setInput(inBytes);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(
Expand All @@ -94,7 +91,7 @@ public static String processFile(File file) throws IOException

outputStream.close();

return encodeToString(outputStream.toByteArray(), false);
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
}

/**
Expand Down Expand Up @@ -160,85 +157,6 @@ public static String encodeURIComponent(String s, String charset)
IA['='] = 0;
}

// ****************************************************************************************
// * char[] version
// ****************************************************************************************

/** Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045.
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
* little faster.
* @return A BASE64 encoded array. Never <code>null</code>.
*/
public final static char[] encodeToChar(byte[] sArr, boolean lineSep)
{
// Check special case
int sLen = sArr != null ? sArr.length : 0;
if (sLen == 0)
return new char[0];

int eLen = (sLen / 3) * 3; // Length of even 24-bits.
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
char[] dArr = new char[dLen];

// Encode even 24-bits
for (int s = 0, d = 0, cc = 0; s < eLen;)
{
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8
| (sArr[s++] & 0xff);

// Encode the int into four chars
dArr[d++] = CA[(i >>> 18) & 0x3f];
dArr[d++] = CA[(i >>> 12) & 0x3f];
dArr[d++] = CA[(i >>> 6) & 0x3f];
dArr[d++] = CA[i & 0x3f];

// Add optional line separator
if (lineSep && ++cc == 19 && d < dLen - 2)
{
dArr[d++] = '\r';
dArr[d++] = '\n';
cc = 0;
}
}

// Pad and encode last bits if source isn't even 24 bits.
int left = sLen - eLen; // 0 - 2.
if (left > 0)
{
// Prepare the int
int i = ((sArr[eLen] & 0xff) << 10)
| (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);

// Set last four chars
dArr[dLen - 4] = CA[i >> 12];
dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
dArr[dLen - 1] = '=';
}
return dArr;
}

// ****************************************************************************************
// * String version
// ****************************************************************************************

/** Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
* little faster.
* @return A BASE64 encoded array. Never <code>null</code>.
*/
public final static String encodeToString(byte[] sArr, boolean lineSep)
{
// Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
return new String(encodeToChar(sArr, lineSep));
}

/**
* Main
*/
Expand Down Expand Up @@ -275,10 +193,9 @@ public static void main(String[] args)
result.append(" var t = f[filename.substring(STENCIL_PATH.length + 1)];\n");
result.append(" var s = null;\n");
result.append(" if (t != null) {\n");
result.append(" t = pako.inflateRaw(Uint8Array.from(atob(t), function (c) {\n");
result.append(" s = pako.inflateRaw(Uint8Array.from(atob(t), function (c) {\n");
result.append(" return c.charCodeAt(0);\n");
result.append(" }), {to: 'string'});\n");
result.append(" s = decodeURIComponent(t);\n");
result.append(" }\n");
result.append(" if (fn != null && s != null) {\n");
result.append(
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/com/mxgraph/online/ProxyServlet.java
Expand Up @@ -64,7 +64,11 @@ protected void doGet(HttpServletRequest request,
{
String urlParam = request.getParameter("url");

if (Utils.sanitizeUrl(urlParam))
if (!"1".equals(System.getenv("ENABLE_DRAWIO_PROXY")))
{
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
else if (Utils.sanitizeUrl(urlParam))
{
// build the UML source from the compressed request parameter
String ref = request.getHeader("referer");
Expand Down Expand Up @@ -152,12 +156,12 @@ protected void doGet(HttpServletRequest request,
}
else
{
response.setStatus(HttpURLConnection.HTTP_PRECON_FAILED);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
else
{
response.setStatus(HttpURLConnection.HTTP_UNSUPPORTED_TYPE);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}

out.flush();
Expand All @@ -169,24 +173,24 @@ protected void doGet(HttpServletRequest request,
}
catch (DeadlineExceededException e)
{
response.setStatus(HttpServletResponse.SC_REQUEST_TIMEOUT);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
catch (UnknownHostException | FileNotFoundException e)
{
// do not log 404 and DNS errors
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
catch (UnsupportedContentException e)
{
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
log.log(Level.SEVERE, "proxy request with invalid content: url="
+ ((urlParam != null) ? urlParam : "[null]")
+ ", referer=" + ((ref != null) ? ref : "[null]")
+ ", user agent=" + ((ua != null) ? ua : "[null]"));
}
catch (SizeLimitExceededException e)
{
response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

throw e;
}
Expand All @@ -205,7 +209,7 @@ protected void doGet(HttpServletRequest request,
}
else
{
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
log.log(Level.SEVERE,
"proxy request with invalid URL parameter: url="
+ ((urlParam != null) ? urlParam : "[null]"));
Expand Down
35 changes: 30 additions & 5 deletions src/main/java/com/mxgraph/online/Utils.java
Expand Up @@ -18,13 +18,11 @@
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.net.InetAddress;

/**
*
Expand Down Expand Up @@ -56,6 +54,32 @@ public class Utils
*/
public static final String TOKEN_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

private static Set<Integer> allowedPorts = new HashSet<>();

static {
// -1 is for no port urls (ports 80, 443)
allowedPorts.add(-1);

String allowedPortsStr = System.getenv("DRAWIO_PROXY_ALLOWED_PORTS");

if (allowedPortsStr != null)
{
String[] ports = allowedPortsStr.split(",");

for (String port : ports)
{
try
{
allowedPorts.add(Integer.parseInt(port));
}
catch (NumberFormatException e)
{
System.out.println("Invalid DRAWIO_PROXY_ALLOWED_PORTS port: " + port);
}
}
}
}

/**
* Returns a random string of the given length.
*/
Expand Down Expand Up @@ -553,11 +577,12 @@ public static boolean sanitizeUrl(String url)
InetAddress address = InetAddress.getByName(host);
String hostAddress = address.getHostAddress();
host = host.toLowerCase();

return (protocol.equals("http") || protocol.equals("https"))
&& !address.isAnyLocalAddress()
&& !address.isLoopbackAddress()
&& !address.isLinkLocalAddress()
&& allowedPorts.contains(parsedUrl.getPort())
&& !host.endsWith(".internal") // Redundant
&& !host.endsWith(".local") // Redundant
&& !host.contains("localhost") // Redundant
Expand Down

0 comments on commit 59887e4

Please sign in to comment.